配置 k8s nginx ingress 以路由 React SPA 和后端 api

Configuring k8s nginx ingress to route React SPA and backend apis

我的后端服务与 ingress nginx 配合得很好。 我正在尝试将前端 SPA 反应应用程序添加到我的入口,但没有成功。

我确实设法让它工作,但我无法让我的后端和前端都工作。

我的入口 yml 是

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/use-regex: 'true'
    nginx.ingress.kubernetes.io/rewrite-target: /
    #nginx.ingress.kubernetes.io/add-base-url: "true"
    
spec:
  rules:
    - host: accounting.easydeal.dev
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend-srv
                port:
                  number: 3000
    - host: api.easydeal.dev
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: docker-hello-world-svc
                port:
                  number: 8088
          - path: /accounting(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: accounting-srv
                port:
                  number: 80
          - path: /company(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: dealers-srv
                port:
                    number: 80
                  

有了上面的这个 yml,我可以像这样戳我的后端 -> api.easydeal.dev/helloword 或 api.easydeal.dev/company/* 它起作用了!.

但是我的 React 应用程序 (accounting.easydeal.dev) 以白页结束,控制台日志显示此错误 ->

Uncaught SyntaxError: Unexpected token '<'

我能够让我的 React 应用工作的唯一方法是将 rewrite-target: /$2 更改为 / 。但是这样做会阻止正确路由我的其他 api。

我确实将 React 应用程序的主页设置为“.”但仍然有错误,我也尝试为我的前端设置 /?(*) 的路径

这是我的 dockerfile

# pull the base image
FROM node:alpine

# set the working direction
WORKDIR /app

# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH

# install app dependencies
COPY package.json ./
COPY package-lock.json ./
RUN npm install
COPY . ./

EXPOSE 3000
CMD ["npm", "start"]

正如发帖人在评论中指出的那样:

Doing 2 ingress services sold this issue.

此问题的解决方案是创建 2 个单独的 Ingress 资源。

根本问题是工作负载需要 2 个不同的 nginx.ingress.kubernetes.io/rewrite-target: 参数。

以上注释可以按 Ingress 资源设置,而不是按路径设置。

您可以创建 2 个 Ingress 资源,它们将是独立的实体(将具有不同的注释)并且它们将“一起”工作。

更多参考可以在下面的链接中找到:


特定于nginx-ingress

默认情况下 当你 provision/deploy NGINX Ingress controller 你告诉你的 Kubernetes 集群创建 Service 类型 LoadBalancer。此 Service 将从云提供商(GKEEKSAKS)请求 IP 地址,并将流量从该 IP 路由到您的 Ingress 控制器将根据您的 Ingress 资源定义评估并进一步发送请求。

A side note!

By default was not used without a reason as there are other methods to expose your Ingress controller to the external traffic. You can read more about it by following below link:

您的 Ingress 控制器将有 单个 IP 地址来公开您的工作负载:

  • $ kubectl get service -n ingress-nginx ingress-nginx-controller
NAME                                 TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
ingress-nginx-controller             LoadBalancer   10.32.6.63     AA.BB.CC.DD   80:30828/TCP,443:30664/TCP   19m

Ingress 正在使用 kubernetes.io/ingress.class: "nginx" 的资源将使用该地址。

Ingress 以这种方式创建的资源在发布时将如下所示:

  • $ kubectl get ingress
NAME              HOSTS                 ADDRESS        PORTS   AGE
goodbye-ingress   goodbye.domain.name   AA.BB.CC.DD    80      19m
hello-ingress     hello.domain.name     AA.BB.CC.DD    80      19m

A second side note!

If you are using a managed Kubernetes cluster, please refer to it's documentation for more reference on using Ingress resources as there could be major differences.