在 Kubernetes 集群上部署了 Nginx Ingress Controller ,最前端用的是阿里云七层负载均衡,部署后发现不能正确转发 X-Forwarded-Proto 请求头,造成 http 重定向到 https 无法正常工作,请问如何解决?
用下面的命令进入 nginx-ingress 容器
kubectl exec -it daemonset/nginx-ingress -n nginx-ingress cat /etc/nginx/conf.d/production-cnblogs-ingress.conf
发现问题是下面的配置引起的
proxy_set_header X-Forwarded-Proto $scheme;
终于在 Nginx Ingress Controller 的官方帮助文档 Advanced Configuration with Annotations 中找到一个注解(annotation)解决了这个问题,它就是 nginx.org/redirect-to-https: "true"
Annotation: nginx.org/redirect-to-https
ConfigMap Key redirect-to-https
Description Sets the 301 redirect rule based on the value of the http_x_forwarded_proto header on the server block to force incoming traffic to be over HTTPS. Useful when terminating SSL in a load balancer in front of the Ingress controller
操作步骤:
1)在 cnblogs-ingress.yaml 中 annotations 下面添加 nginx.org/redirect-to-https: "true"
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: cnblogs-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.org/redirect-to-https: "true"
spec:
rules:
- host: q.cnblogs.com
http:
paths:
- backend:
serviceName: q-web
servicePort: 80
2)更新 ingress 配置
kubectl apply -f cnblogs-ingress.yaml
3)更新 nginx-ingress
kubectl rollout restart daemonset/nginx-ingress -n nginx-ingress && \
kubectl rollout status daemonset/nginx-ingress -n nginx-ingress
4)查看 inginx 容器中的配置
kubectl exec -it daemonset/nginx-ingress -n nginx-ingress cat /etc/nginx/conf.d/production-cnblogs-ingress.conf
发现 proxy_set_header X-Forwarded-Proto $scheme;
变成了 proxy_set_header X-Forwarded-Proto https;
,并且增加了下面的 http 重定向 https 的配置。
if ($http_x_forwarded_proto = 'http') {
return 301 https://$host$request_uri;
}
nginx-ingress 自己完成了基于 X-Forwarded-Proto 的 http 重定向到 https 的操作,应用都不需要自己处理了。
这里用的是 nginxinc/kubernetes-ingress ,如果用的是 kubernetes/ingress-nginx (相关博文),不存在这个问题。
github 上的相关 issue :x-forwarded-proto unexpected behavior
– dudu 4年前