【问题标题】:Problems with a react application deployed on k8s部署在 k8s 上的 react 应用程序的问题
【发布时间】:2020-02-15 11:16:29
【问题描述】:

我对使用 npx create-react-app react-app 创建的简单 React 应用程序有疑问。在 k8s 上部署后,我得到了这个:

Uncaught SyntaxError: Unexpected token '<'

但是,如果我想 kubectl port-forward 到 pod 并在 localhost:3000 处查看应用程序(容器的 pod 位于 3000,集群 ip 服务侦听 3000 并转发到 3000)完全没有问题。

入口路由看起来不错,因为我可以访问其他服务以在集群内工作,但不能访问应用程序。一些帮助将不胜感激。

部署yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: react-app-deployment
  # namespace: gitlab-managed-apps
spec:
  replicas: 1
  selector:
    matchLabels:
      component: react-app
  template:
    metadata:
      labels:
        component: react-app
    spec:
      imagePullSecrets:
      - name: simpleweb-token-namespace
      containers:
      - name: react-app
        image: registry.gitlab.com/mttlong/sample/react-app
        env:
        - name: "PORT"
          value: "3000"
        ports:
        - containerPort: 3000

集群ip服务:

apiVersion: v1
kind: Service
metadata:
  name: react-app-cluster-ip-service
spec:
  type: ClusterIP
  selector:
    component: react-app
  ports:
  - port: 3000
    targetPort: 3000

Dockerfile:

FROM node:10.15.3-alpine as builder
WORKDIR '/app'
COPY ./package.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx
EXPOSE 3000
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /app/build /usr/share/nginx/html

入口服务:

apiVersion: extensions/v1beta1
kind: Ingress
metadata: 
  name: orion-ingress-service
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /$2

spec:
  rules:
    - host: horizon.zeezum.com
      http: 
        paths:
          - path: /
            backend:
              serviceName: react-app-cluster-ip-service
              servicePort: 3000
          - path: /api(/|$)(.*)
            backend:
              serviceName: simple-api-nodeport-service
              servicePort: 3050

【问题讨论】:

  • 能否提供部署yaml
  • 你能把整个文本放到错误中吗?
  • 资源解释为样式表,但使用 MIME 类型 text/html 传输:“horizon.zeezum.com/static/css/main.d1b05096.chunk.css”。 2.964cd682.chunk.js:1 Uncaught SyntaxError: Unexpected token '
  • 您好,我也遇到了同样的问题,请问您找到解决方案了吗?还是根本原因?
  • 不幸的是,没有。问题仍然存在。

标签: reactjs kubernetes


【解决方案1】:

我遇到了与您描述的相同的问题。我通过拆分前端和 API 的 Ingress 解决了这个问题。

在你的情况下,这看起来像这样:

前端入口服务(无重写目标):

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: orion-ingress-frontend-service
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: horizon.zeezum.com
      http:
        paths:
          - path: /
            backend:
              serviceName: react-app-cluster-ip-service
              servicePort: 3000

后端入口服务(使用 /$2 重写目标):

apiVersion: extensions/v1beta1
kind: Ingress
metadata: 
    name: orion-ingress-backend-service
    annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
    rules:
        - host: horizon.zeezum.com
            http: 
                paths:
                    - path: /api(/|$)(.*)
                        backend:
                            serviceName: simple-api-nodeport-service
                            servicePort: 3050

你们其余的配置应该没问题。

【讨论】:

    【解决方案2】:

    删除nginx.ingress.kubernetes.io/rewrite-target: /$2这一行,它应该可以工作

    【讨论】:

    • 我认为这意味着您将无法再访问 API,并且您将收到 405 错误。
    【解决方案3】:

    这很可能是 404 页面或重定向到提供常规 html 而不是预期的 JavaScript 文件的页面的结果。 (HTML 页面以 <html><!DOCTYPE...> 开头,因此 < 作为意外标记)

    确保您已正确构建映像并正确访问该页面。您可以通过使用浏览器手动访问 URL 或查看浏览器开发工具的网络选项卡来检查响应来进行验证。 (我假设您已经缓存了 index.html 并尝试访问旧资产,检查缓存标头,或者路径不匹配。在这种情况下,检查您的图像并手动访问 URL)

    【讨论】:

    • 我收到 200 个 GET 方法的响应。至于 HTML 页面,这是 React 应用程序的生产版本,即。代码已与资产一起编译到构建文件夹中。不知道该怎么做。
    • 您是否得到预期的 javascript 或索引页面 (html) 作为响应?
    • 我得到了 index.html 作为响应。
    • 所以这似乎与您的特定图像有关,而不是kubernetes或react。使用 docker 在本地尝试(确切!)图像或检查内容(例如使用潜水)以确保它包含您的应用程序。 (例如 .dockerignore 是一个常见的罪魁祸首)
    • 在部署到 k8s 之前,我曾尝试使用 'docker run' 在本地运行,没有任何问题。此外,在部署到 k8s 后,我没有问题将端口转发到 pod,react 应用程序也没有问题。只有当我尝试通过 URL 访问它时。
    【解决方案4】:

    我也有类似的情况。我完全摆脱了 Ingress,并在我的 Service yaml 文件中将我的 Service 更改为 type: Nodeport 并在每个端口下添加了 protocol: TCPnodePort: <insert nodeport> 字段。

    我通过运行kubectl expose deployment <insert deployment name> --type=NodePort --name=example-service 获得了节点端口的值。它创建一个服务并分配端口。然后您可以运行kubectl describe services example-service 以显示所有节点端口值。然后,您可以将这些值复制到您的服务 yaml 文件中。

    当它全部运行时,您将使用生成的节点端口从浏览器访问网站,例如localhost:31077,而不是实际端口3000

    然后我更改了我必须使用节点端口而不是实际端口和繁荣的任何 url 路由。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-30
      • 2016-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-02
      • 2018-11-19
      • 2021-09-23
      相关资源
      最近更新 更多