使用 HTTPS Web 服务在 Ingress 上获取 ERR_TOO_MANY_REDIRECTS
Getting ERR_TOO_MANY_REDIRECTS on Ingress with HTTPS web services
我在具有以下配置的自定义节点上有一个 Rancher 集群 (v2.4.5) 运行:
- 外机(example.com):
- 在端口 8443 上运行 Rancher 服务器;
- 使用以下基本配置(以及其他不相关的配置)运行 NGINX:
user nginx;
worker_processes 4;
worker_rlimit_nofile 40000;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 8192;
}
http {
upstream rancher_servers {
least_conn;
server <MY_NODE_IP>:443 max_fails=3 fail_timeout=5s;
}
server {
listen 443 ssl http2;
server_name example.com service1.example.com service2.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://rancher_servers;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 900s;
}
}
}
- 内机(MY_NODE_IP):
- 运行 Rancher 代理(etcd/control plane/worker)
防火墙规则没问题,我可以仅在端口 80 上部署带有东西 运行 的小型 Web 应用程序并自动重定向到 HTTPS。下面是我用来部署内容的 YAML 示例:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: www-deployment
labels:
app: www
spec:
replicas: 1
selector:
matchLabels:
app: www
template:
metadata:
labels:
app: www
spec:
containers:
- name: www
image: my-www-image
---
kind: Service
apiVersion: v1
metadata:
name: www-service
spec:
selector:
app: www
ports:
- port: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: www-ingress
annotations:
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: service1.example.com
http:
paths:
- path: /
backend:
serviceName: www-service
servicePort: 80
问题是当我尝试部署在端口 80 和 443 上运行的服务时,当在端口 80 上请求时,会自动重定向到端口 443。在这种情况下,如果我像下面这样指定 Ingress (使用端口 443),我得到一个 Bad Gateway
响应 不是来自主机 NGINX。我可以这么说,因为我的主机运行 nginx/1.18.0
并且响应来自 nginx/1.17.10
.
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: www-ingress
annotations:
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: service1.example.com
http:
paths:
- path: /
backend:
serviceName: www-service
servicePort: 443
但是,如果我将上面的配置更改为 servicePort: 80
,我会一直收到 ERR_TOO_MANY_REDIRECTS,因为它进入了从任何内容重定向到 https://anything
.[=19= 的无限循环]
我是不是做错了什么?我怎样才能解决这些问题?
找到了。事实证明,我唯一需要做的就是告诉 nginx-ingress-controller 我期待 HTTPS 连接。公开服务的最终 YAML 如下:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: www-ingress
annotations:
ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
rules:
- host: service1.example.com
http:
paths:
- path: /
backend:
serviceName: www-service
servicePort: 443
我在具有以下配置的自定义节点上有一个 Rancher 集群 (v2.4.5) 运行:
- 外机(example.com):
- 在端口 8443 上运行 Rancher 服务器;
- 使用以下基本配置(以及其他不相关的配置)运行 NGINX:
user nginx;
worker_processes 4;
worker_rlimit_nofile 40000;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 8192;
}
http {
upstream rancher_servers {
least_conn;
server <MY_NODE_IP>:443 max_fails=3 fail_timeout=5s;
}
server {
listen 443 ssl http2;
server_name example.com service1.example.com service2.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://rancher_servers;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 900s;
}
}
}
- 内机(MY_NODE_IP):
- 运行 Rancher 代理(etcd/control plane/worker)
防火墙规则没问题,我可以仅在端口 80 上部署带有东西 运行 的小型 Web 应用程序并自动重定向到 HTTPS。下面是我用来部署内容的 YAML 示例:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: www-deployment
labels:
app: www
spec:
replicas: 1
selector:
matchLabels:
app: www
template:
metadata:
labels:
app: www
spec:
containers:
- name: www
image: my-www-image
---
kind: Service
apiVersion: v1
metadata:
name: www-service
spec:
selector:
app: www
ports:
- port: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: www-ingress
annotations:
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: service1.example.com
http:
paths:
- path: /
backend:
serviceName: www-service
servicePort: 80
问题是当我尝试部署在端口 80 和 443 上运行的服务时,当在端口 80 上请求时,会自动重定向到端口 443。在这种情况下,如果我像下面这样指定 Ingress (使用端口 443),我得到一个 Bad Gateway
响应 不是来自主机 NGINX。我可以这么说,因为我的主机运行 nginx/1.18.0
并且响应来自 nginx/1.17.10
.
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: www-ingress
annotations:
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: service1.example.com
http:
paths:
- path: /
backend:
serviceName: www-service
servicePort: 443
但是,如果我将上面的配置更改为 servicePort: 80
,我会一直收到 ERR_TOO_MANY_REDIRECTS,因为它进入了从任何内容重定向到 https://anything
.[=19= 的无限循环]
我是不是做错了什么?我怎样才能解决这些问题?
找到了。事实证明,我唯一需要做的就是告诉 nginx-ingress-controller 我期待 HTTPS 连接。公开服务的最终 YAML 如下:
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: www-ingress
annotations:
ingress.kubernetes.io/rewrite-target: /
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
rules:
- host: service1.example.com
http:
paths:
- path: /
backend:
serviceName: www-service
servicePort: 443