为什么 nginx return 404 在我的 Kubernetes Ingress 路由上?
Why does nginx return 404 on my Kubernetes Ingress route?
我设置了两个 nginx 网络服务器。一个是在 AWS Elastic Beanstalk 上设置的,另一个是使用 stable/nginx-ingress helm chart 在 Kubernetes 上设置的。
Elastic Beanstalk 网络服务器将流量从我域的所有子路由转发到 Kubernetes nginx 网络服务器。我可以通过检查来自 Kubernetes nginx 的日志来验证这些是否被正确转发。我使用 Ingress 资源来确保将此流量转发到正确的 Kubernetes 服务。
问题是:
两条路线之一,主要 /
路线,转发到正确的服务和 returns 200。另一条路线,/eks-test
,应该路由到相同的服务,但是returns 一个 404。这怎么可能?
规格:
Kubernetes上的nginx是运行nginx0.25.1
。我是 运行 AWS EKS 版本 1.14 上的 Kubernetes。
Nginx 日志:
172.16.10.103 - [172.16.10.103] - - [12/Sep/2019:08:05:09 +0000] "GET / HTTP/1.0" 200 8 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36" 703 0.004 [default-eks-test-repo-80] [] 172.16.10.100:8080 8 0.004 200 90dfa37364a5c43e57f12c5fb1a2d86f
172.16.40.108 - [172.16.40.108] - - [12/Sep/2019:08:05:12 +0000] "GET /eks-test HTTP/1.0" 404 9 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36" 730 0.002 [default-eks-test-repo2-80] [] 172.16.43.125:8080 9 0.004 404 ef1c81bba75dff2bdd2376799aa93c56
第一个 nginx 配置(Elastic Beanstalk):
server {
listen 80;
server_name my.domain.com;
location / {
proxy_pass http://internal.my.domain.lan/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Kubernetes Ingress 资源:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: internal
name: eks-test
namespace: default
spec:
rules:
- host: my.domain.com
http:
paths:
- path: /
backend:
serviceName: eks-test-repo
servicePort: 80
- path: /eks-test
backend:
serviceName: eks-test-repo
servicePort: 80
Kubernetes 服务:
kind: Service
apiVersion: v1
metadata:
name: eks-test-repo
namespace: default
labels:
name: eks-test-repo
spec
ports:
- port: 80
targetPort: 80
selector:
app: eks-test-repo
type: ClusterIP
Nginx helm 图表值(非默认值):
controller.ingressClass: internal
请使用以下配置,它可能会解决您的问题。
annotations:
kubernetes.io/ingress.class: "nginx"
ingress.kubernetes.io/rewrite-target: "/"
ingress.kubernetes.io/configuration-snippet: |
sub_filter_once on;
sub_filter '<base href="/">' '<base href="/{{$definitionName}}/">';
spec:
rules:
- http:
paths:
- path: /{{$definitionName}}
backend:
serviceName: {{$definitionName}}
servicePort: 80
此致,
Vaibhav kharode
可以找到此问题的答案here。
基本上,路径没有被重写为 /
,但 pods 中的网络服务器仅在根路径上侦听。添加 nginx.ingress.kubernetes.io/rewrite-target: /
注释解决了问题。
您应该从 Nginx 配置中删除这一行:
proxy_set_header Host $host;
重写主机名,Kubernetes 找不到目标主机。
我设置了两个 nginx 网络服务器。一个是在 AWS Elastic Beanstalk 上设置的,另一个是使用 stable/nginx-ingress helm chart 在 Kubernetes 上设置的。
Elastic Beanstalk 网络服务器将流量从我域的所有子路由转发到 Kubernetes nginx 网络服务器。我可以通过检查来自 Kubernetes nginx 的日志来验证这些是否被正确转发。我使用 Ingress 资源来确保将此流量转发到正确的 Kubernetes 服务。
问题是:
两条路线之一,主要 /
路线,转发到正确的服务和 returns 200。另一条路线,/eks-test
,应该路由到相同的服务,但是returns 一个 404。这怎么可能?
规格:
Kubernetes上的nginx是运行nginx0.25.1
。我是 运行 AWS EKS 版本 1.14 上的 Kubernetes。
Nginx 日志:
172.16.10.103 - [172.16.10.103] - - [12/Sep/2019:08:05:09 +0000] "GET / HTTP/1.0" 200 8 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36" 703 0.004 [default-eks-test-repo-80] [] 172.16.10.100:8080 8 0.004 200 90dfa37364a5c43e57f12c5fb1a2d86f
172.16.40.108 - [172.16.40.108] - - [12/Sep/2019:08:05:12 +0000] "GET /eks-test HTTP/1.0" 404 9 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36" 730 0.002 [default-eks-test-repo2-80] [] 172.16.43.125:8080 9 0.004 404 ef1c81bba75dff2bdd2376799aa93c56
第一个 nginx 配置(Elastic Beanstalk):
server {
listen 80;
server_name my.domain.com;
location / {
proxy_pass http://internal.my.domain.lan/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Kubernetes Ingress 资源:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: internal
name: eks-test
namespace: default
spec:
rules:
- host: my.domain.com
http:
paths:
- path: /
backend:
serviceName: eks-test-repo
servicePort: 80
- path: /eks-test
backend:
serviceName: eks-test-repo
servicePort: 80
Kubernetes 服务:
kind: Service
apiVersion: v1
metadata:
name: eks-test-repo
namespace: default
labels:
name: eks-test-repo
spec
ports:
- port: 80
targetPort: 80
selector:
app: eks-test-repo
type: ClusterIP
Nginx helm 图表值(非默认值):
controller.ingressClass: internal
请使用以下配置,它可能会解决您的问题。
annotations:
kubernetes.io/ingress.class: "nginx"
ingress.kubernetes.io/rewrite-target: "/"
ingress.kubernetes.io/configuration-snippet: |
sub_filter_once on;
sub_filter '<base href="/">' '<base href="/{{$definitionName}}/">';
spec:
rules:
- http:
paths:
- path: /{{$definitionName}}
backend:
serviceName: {{$definitionName}}
servicePort: 80
此致,
Vaibhav kharode
可以找到此问题的答案here。
基本上,路径没有被重写为 /
,但 pods 中的网络服务器仅在根路径上侦听。添加 nginx.ingress.kubernetes.io/rewrite-target: /
注释解决了问题。
您应该从 Nginx 配置中删除这一行:
proxy_set_header Host $host;
重写主机名,Kubernetes 找不到目标主机。