Kubernetes 多个 nginx 入口重定向到错误的服务

Kubernetes multiple nginx ingress redirecting to wrong services

我想在同一个集群上部署我的应用程序的两个版本。为此,我使用名称空间将它们分开,并且每个应用程序都有自己的入口重定向到它自己的服务。我在入口处使用控制器。

总结架构如下:

我的问题是,当我使用 ingress2 的 nginx-controller 的外部 ip 时,它会访问我的 app1

我正在使用 helm 来部署我的应用程序

Ingress.yaml

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: "{{ .Release.Name }}-ingress"
  annotations:
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
    - hosts:
      - {{ .Values.host }}
      secretName: {{ .Release.Namespace }}-cert-secret
  rules:
  - http:
    - path: /api($|/)(.*)
      backend:
        serviceName: "{{ .Release.Name }}-api-service"
        servicePort: {{ .Values.api.service.port.api }}

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: "{{ .Release.Name }}-api-service"
spec:
  selector:
    app: "{{ .Release.Name }}-api-deployment"
  ports:
    - port: {{ .Values.api.service.port.api }}
      targetPort: {{ .Values.api.deployment.port.api }}
      name: 'api'

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: "{{ .Release.Name }}-api-deployment"
spec:
  replicas: 1
  selector:
    matchLabels:
      app: "{{ .Release.Name }}-api-deployment"
  template:
    metadata:
      labels:
        app: "{{ .Release.Name }}-api-deployment"
    spec:
      containers:
      - name: "{{ .Release.Name }}-api-deployment-container"
        imagePullPolicy: "{{ .Values.api.image.pullPolicy }}"
        image: "{{ .Values.api.image.repository }}:{{ .Values.api.image.tag }}"
        command: ["/bin/sh"]
        args:
        - "-c"
        - "node /app/server/app.js"
        env:
        - name: API_PORT
          value: {{ .Values.api.deployment.port.api | quote }}

values.yaml

api:
  image:
    repository: xxx
    tag: xxx
    pullPoliciy: Always
  deployment:
    port:
      api: 8080
    ressources:
      requests:
        memory: "1024Mi"
        cpu: "1000m"
  service:
    port:
      api: 80
    type: LoadBalancer

部署我的应用 运行:

kubectl -n namespace1 获取 svc

NAME                                       TYPE           CLUSTER-IP      EXTERNAL-IP                                                               PORT(S)                                       AGE
nginx-ingress-1581005515-controller        LoadBalancer   10.100.20.183   a661e982f48fb11ea9e440eacdf86-1089217384.eu-west-3.elb.amazonaws.com   80:32256/TCP,443:32480/TCP                    37m
nginx-ingress-1581005515-default-backend   ClusterIP      10.100.199.97   <none>                                                                    80/TCP                                        37m
release1-api-service                       LoadBalancer   10.100.87.210   af6944a7b48fb11eaa3100ae77b6d-585994672.eu-west-3.elb.amazonaws.com    80:31436/TCP,8545:32715/TCP,30300:30643/TCP   33m

kubectl -n namespace2 获取 svc

NAME                                       TYPE           CLUSTER-IP       EXTERNAL-IP                                                               PORT(S)                                       AGE
nginx-ingress-1580982483-controller        LoadBalancer   10.100.177.215   ac7d0091648c511ea9e440eacdf86-762232273.eu-west-3.elb.amazonaws.com    80:32617/TCP,443:30459/TCP                    7h6m
nginx-ingress-1580982483-default-backend   ClusterIP      10.100.53.245    <none>                                                                    80/TCP                                        7h6m
release2-api-service                       LoadBalancer   10.100.108.190   a4605dedc490111ea9e440eacdf86-2005327771.eu-west-3.elb.amazonaws.com   80:32680/TCP,8545:32126/TCP,30300:30135/TCP   36s

当我命中 namespace2 的 nginx-controller 时,它应该命中部署在 release2 中的 app2,但它命中的是 app1。 当我点击 namespace1 的 nginx-controller 时,正如预期的那样,它点击了 app1.

仅供参考,顺序很重要,总是第一个部署的应用程序总是被命中

为什么第二个负载均衡器没有重定向到我的第二个应用程序?

问题是我对两个入口使用了相同的 "nginx" class。两个 nginx 控制器都服务于相同的 class "nginx".

这里是关于如何使用 mutilple nginx ingress controller 的 wiki:https://kubernetes.github.io/ingress-nginx/user-guide/multiple-ingress/

我最终这样定义入口 class: kubernetes.io/ingress.class: nginx-{{ .Release.Namespace }}

并像这样部署我的 nginx 控制器:install -n $namespace nginx-$namespace stable/nginx-ingress --set "controller.ingressClass=nginx-${namespace}"

如果你没有使用 helm 来部署你的 nginx-controller,你需要修改的是 nginx ingress class