Kubernetes 多个 nginx 入口重定向到错误的服务
Kubernetes multiple nginx ingress redirecting to wrong services
我想在同一个集群上部署我的应用程序的两个版本。为此,我使用名称空间将它们分开,并且每个应用程序都有自己的入口重定向到它自己的服务。我在入口处使用控制器。
总结架构如下:
- 集群
- 命名空间1
- app1
- 服务 1
- 入口 1
- 命名空间
- app2
- 服务 2
- 入口2
我的问题是,当我使用 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
部署我的应用 运行:
helm install -n namespace1 release1 .
helm install -n namespace2 release2 .
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
我想在同一个集群上部署我的应用程序的两个版本。为此,我使用名称空间将它们分开,并且每个应用程序都有自己的入口重定向到它自己的服务。我在入口处使用控制器。
总结架构如下:
- 集群
- 命名空间1
- app1
- 服务 1
- 入口 1
- 命名空间
- app2
- 服务 2
- 入口2
- 命名空间1
我的问题是,当我使用 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
部署我的应用 运行:
helm install -n namespace1 release1 .
helm install -n namespace2 release2 .
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