简体   繁体   English

Kubernetes 中的 React App 未正确连接

[英]React App in Kubernetes is not connecting properly

I'm new to Kubernetes and I'm trying to deploy a React app to my cluster.我是 Kubernetes 的新手,我正在尝试将 React 应用程序部署到我的集群。 Here's the basic info:以下是基本信息:

  • Docker Desktop, single-node Kubernetes cluster Docker 桌面,单节点 Kubernetes 集群
  • React development frontend, exposing port 3000 React 开发前端,暴露 3000 端口
  • Node.js/Express backend, exposing port 8080 Node.js/Express 后端,暴露 8080 端口
  • NGINX Ingress Controller, serving my React frontend on "localhost:3000" and routing my Fetch API requests (fetch("localhost:3000/api/...", OPTIONS)) to the backend (which works) NGINX 入口 Controller,在“localhost:3000”上为我的 React 前端提供服务,并将我的 Fetch API 请求(获取(“localhost:3000”)到后端(获取(“localhost:3000/”)

I am having an issue when opening the React app.打开 React 应用程序时遇到问题。 The Ingress Controller correctly routes to the app but the 3 bundles (bundle.js, main.chink.js, the third one which I don't remember) aren't loaded. Ingress Controller 正确路由到应用程序,但未加载 3 个包(bundle.js、main.chink.js,我不记得的第三个)。 I get the following error:我收到以下错误:

GET http://localhost/static/js/main.chunk.js net::ERR_ABORTED 404 (Not Found) ingress (one example)

I understand why this error happens.我明白为什么会发生这个错误。 The Ingress Controller correctly routes the traffic but only loads the index.html file. Ingress Controller 正确路由流量,但仅加载 index.html 文件。 In this file, there are calls to 3 scripts (referring to the bundles) which aren't loaded.在此文件中,调用了 3 个未加载的脚本(指捆绑包)。 I understand the error, the files don't get sent to the browser so the index.html file can't load them in, but do not know how to fix it.我理解错误,文件没有发送到浏览器,所以 index.html 文件无法加载它们,但不知道如何修复它。 Does anyone have any suggestions?有没有人有什么建议? de and then pulled from Docker Hub. de 然后从 Docker 集线器中拉出。 Does anybody know what a possible solution could be?有人知道可能的解决方案是什么吗? For example, does deploying the build/ folder (built React app using "npm run build") fix this?例如,部署 build/ 文件夹(使用“npm run build”构建 React 应用程序)是否解决了这个问题? Do I have to use nginx inside my Dockerfile to build the container?我是否必须在 Dockerfile 中使用 nginx 来构建容器?

Ingress.yaml入口.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: titanic-ingress
  #labels:
      #name: titanic-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: localhost
    http:
      paths:
      - path: /
        pathType: Exact
        backend:
          service:
            name: titanicfrontendservice
            port:
              number: 3000
      - path: /api
        pathType: Exact
        backend:
          service:
            name: titanicbackendservice
            port:
              number: 8080

Ingress controller deployment yaml入口 controller 部署 yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-ingress
  namespace: nginx-ingress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-ingress
  template:
    metadata:
      labels:
        app: nginx-ingress
     #annotations:
       #prometheus.io/scrape: "true"
       #prometheus.io/port: "9113"
    spec:
      serviceAccountName: nginx-ingress
      containers:
      - image: nginx/nginx-ingress:1.10.0
        imagePullPolicy: IfNotPresent
        name: nginx-ingress
        ports:
        - name: http
          containerPort: 80
        - name: https
          containerPort: 443
        - name: readiness-port
          containerPort: 8081
       #- name: prometheus
         #containerPort: 9113
        readinessProbe:
          httpGet:
            path: /nginx-ready
            port: readiness-port
          periodSeconds: 1
        securityContext:
          allowPrivilegeEscalation: true
          runAsUser: 101 #nginx
          capabilities:
            drop:
            - ALL
            add:
            - NET_BIND_SERVICE
        env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        args:
          - -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
          - -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret
          #- -v=3 # Enables extensive logging. Useful for troubleshooting.
          - -report-ingress-status
          - -external-service=nginx-ingress
         #- -enable-prometheus-metrics
         #- -global-configuration=$(POD_NAMESPACE)/nginx-configuration

Ingress controller service yaml入口 controller 服务 yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress
  namespace: nginx-ingress
spec:
  externalTrafficPolicy: Local
  type: LoadBalancer
  ports:
  - port: 3000
    targetPort: 80
    protocol: TCP
    name: http
  - port: 443
    targetPort: 443
    protocol: TCP
    name: https
  selector:
    app: nginx-ingress

The issue with your ingress.yaml is that the route for your ui should be /* and placed below the backend routing.您的 ingress.yaml 的问题是您的 ui 的路由应该是 /* 并放置在后端路由下方。 Also, check your routing for APIs此外,请检查您的 API 路由

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: titanic-ingress
  #labels:
      #name: titanic-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: localhost
    http:
      paths:
      - path: /api/*
        pathType: Exact
        backend:
          service:
            name: titanicbackendservice
            port:
              number: 8080
      - path: /*
        pathType: Exact
        backend:
          service:
            name: titanicfrontendservice
            port:
              number: 3000

TL;DR TL;博士

Switch your pathType in both /api and / path to Prefix ./api/ path 中的pathType切换为Prefix

I've included some explanation with fixed Ingress resource below.我在下面包含了一些带有固定Ingress资源的解释。


For the reproduction purposes I used the titanic manifests that you provided in the another question:出于复制目的,我使用了您在另一个问题中提供的titanic清单:

The issue with your configuration is with: pathType .您的配置问题在于: pathType

Using your Ingress resource with pathType: Exact showed me blank page.使用带有pathType: ExactIngress资源向我显示空白页。

Modifying your Ingress resource with pathType: Prefix solved the issue.使用pathType: Prefix修改Ingress资源解决了这个问题。

Side note!边注!

The message: "Would you have survived the sinking of the Titanic?"信息: “你能在泰坦尼克号沉没中幸存下来吗?” showed.显示。

The exact Ingress configuration should be following:确切的Ingress配置应如下所示:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: titanic-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: localhost
    http:
      paths:
      - path: /
        pathType: Prefix # <-- IMPORTANT
        backend:
          service:
            name: titanicfrontendservice
            port:
              number: 3000
      - path: /api
        pathType: Prefix # <-- IMPORTANT
        backend:
          service:
            name: titanicbackendservice
            port:
              number: 8080

Why I think it happened?为什么我认为它发生了?

Citing the official documentation:引用官方文档:

Path types路径类型

Each path in an Ingress is required to have a corresponding path type. Ingress 中的每条路径都需要具有相应的路径类型。 Paths that do not include an explicit pathType will fail validation.不包含显式 pathType 的路径将无法通过验证。 There are three supported path types:支持三种路径类型:

  • ImplementationSpecific : With this path type, matching is up to the IngressClass. ImplementationSpecific :使用此路径类型,匹配取决于 IngressClass。 Implementations can treat this as a separate pathType or treat it identically to Prefix or Exact path types.实现可以将其视为单独的 pathType 或将其视为 Prefix 或 Exact 路径类型。

  • Exact : Matches the URL path exactly and with case sensitivity. Exact :与 URL 路径完全匹配并且区分大小写。

  • Prefix : Matches based on a URL path prefix split by /. Prefix :基于由 / 分割的 URL 路径前缀匹配。 Matching is case sensitive and done on a path element by element basis.匹配区分大小写,并在逐个元素的路径元素基础上完成。 A path element refers to the list of labels in the path split by the / separator.路径元素是指由 / 分隔符分割的路径中的标签列表。 A request is a match for path p if every p is an element-wise prefix of p of the request path.如果每个 p 都是请求路径的 p 的元素前缀,则请求是路径 p 的匹配项。

-- Kubernetes.io: Docs: Concepts: Services networking: Ingress: Path types (there are some examples on how the path matching is handled) -- Kubernetes.io:文档:概念:服务网络:入口:路径类型(有一些关于如何处理路径匹配的示例)

Ingress controller is forced to match only the / path leaving rest of the dependencies (apart from the index.html ) on other paths like /super.jpg and /folder/awesome.jpg to error with 404 code. Ingress controller被迫匹配/路径离开 rest 的依赖项(除了index.html其他路径,例如/super.jpg和 jpg/ /folder/awesome.jpg 404

Side note!边注!

You can test yourself this behavior by spawning an nginx Pod and placing example files in it.您可以通过生成 nginx Pod并将示例文件放入其中来测试自己的这种行为。 After applying the Ingress resource with / and pathType: Exact you won't be able to request it through the Ingress controller but you could access them within the cluster.使用/pathType: Exact应用Ingress资源后,您将无法通过Ingress controller 请求它,但您可以在集群中访问它们。


I encourage you to check the additional resources:我鼓励您检查其他资源:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM