我正在使用nginx-ingress在kubernetes中建立我的第一个入口。我设置了ingress-nginx
负载均衡器服务,如下所示:
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "ingress-nginx",
"namespace": "...",
"labels": {
"k8s-addon": "ingress-nginx.addons.k8s.io"
},
"annotations": {
"service.beta.kubernetes.io/aws-load-balancer-backend-protocol": "tcp",
"service.beta.kubernetes.io/aws-load-balancer-proxy-protocol": "*",
"service.beta.kubernetes.io/aws-load-balancer-ssl-cert": "arn....",
"service.beta.kubernetes.io/aws-load-balancer-ssl-ports": "443"
}
},
"spec": {
"ports": [
{
"name": "http",
"protocol": "TCP",
"port": 80,
"targetPort": "http",
"nodePort": 30591
},
{
"name": "https",
"protocol": "TCP",
"port": 443,
"targetPort": "http",
"nodePort": 32564
}
],
"selector": {
"app": "ingress-nginx"
},
"clusterIP": "...",
"type": "LoadBalancer",
"sessionAffinity": "None",
"externalTrafficPolicy": "Cluster"
},
"status": {
"loadBalancer": {
"ingress": [
{
"hostname": "blablala.elb.amazonaws.com"
}
]
}
}
}
注意https
端口如何将targetPort
属性指向端口80(http),以便在负载均衡器处终止ssl。
我的ingress看起来像这样:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: something
namespace: ...
annotations:
ingress.kubernetes.io/ingress.class: "nginx"
ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
rules:
- host: www.exapmle.com
http:
paths:
- path: /
backend:
serviceName: some-service
servicePort: 2100
现在,当我导航到网址时,我得到Too many redirects error
。令我困惑的是,当我添加以下标题" X-Forwarded-Proto:https"我收到了预期的回复(curl https://www.example.com -v -H "X-Forwarded-Proto: https"
)。
我有什么想法可以解决这个问题吗?
P.S。这与ingress.kubernetes.io/force-ssl-redirect: "false"
一样正常,并且看起来没有任何无关的重定向。
答案 0 :(得分:5)
这是一个已知问题,annotation
用于SSL重定向,结合代理协议和终止ELB上的SSL连接。
您应该为Nginx-Ingress创建自定义ConfigMap,而不是使用force-ssl-redirect
注释,如下所示:
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app: ingress-nginx
name: nginx-ingress-configuration
namespace: <ingress-namespace>
data:
ssl-redirect: "false"
hsts: "true"
server-tokens: "false"
http-snippet: |
server {
listen 8080 proxy_protocol;
server_tokens off;
return 301 https://$host$request_uri;
}
该配置将创建一个额外的侦听器,只需简单重定向到https。
NodePort
8080添加到其容器定义和服务中。使用这个额外的监听器,它将起作用。
答案 1 :(得分:1)
另一种适用于我的环境的方法(k8s v1.16.15,rancher / nginx-ingress-controller:nginx-0.32.0-rancher1):
apiVersion: v1
data:
compute-full-forwarded-for: "true"
use-forwarded-headers: "true"
kind: ConfigMap
metadata:
labels:
app: ingress-nginx
name: nginx-configuration
namespace: ingress-nginx
这与在应用程序入口处使用force-ssl-redirect一起使用。看来,入口控制器并没有使用现成的ELB中的X-Forwarded-Proto标头。
答案 2 :(得分:1)
我必须添加这些注释才能使其正常工作,而无需更改入口控制器:
annotations:
kubernetes.io/ingress.class: nginx-ingress-internal # <- AWS NLB
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($http_x_forwarded_proto = 'http') {
return 301 https://$host$request_uri;
}