我在运行 NGINX 的自托管服务器上有一个带有外部负载平衡器的 Kubernetes 集群。我试图激活proxy_protocol以获取real_ip客户端,但 NGINX 日志是
2020/05/11 14:57:54 [error] 29614#29614: *1325 broken header: "?????????a"5?li<c?*? ???s? ?6?????X??o???E??i?{ ?/?0?+?,???? ??
??/5?" while reading PROXY protocol, client: 51.178.168.233, server: 0.0.0.0:443
Run Code Online (Sandbox Code Playgroud)
这是我的 NGINX 配置文件:
worker_processes 4;
worker_rlimit_nofile 40000;
events {
worker_connections 8192;
}
stream {
upstream rancher_servers_http {
least_conn;
server <IP_NODE_1>:80 max_fails=3 fail_timeout=5s;
server <IP_NODE_2>:80 max_fails=3 fail_timeout=5s;
server <IP_NODE_3>:80 max_fails=3 fail_timeout=5s;
}
server {
listen 80;
proxy_protocol on;
proxy_pass rancher_servers_http;
}
upstream rancher_servers_https {
least_conn;
server <IP_NODE_1>:443 max_fails=3 fail_timeout=5s;
server <IP_NODE_2>:443 max_fails=3 fail_timeout=5s;
server <IP_NODE_3>:443 max_fails=3 fail_timeout=5s;
}
server {
listen 443 ssl proxy_protocol;
ssl_certificate /certs/fullchain.pem;
ssl_certificate_key /certs/privkey.pem;
proxy_pass rancher_servers_https;
proxy_protocol on;
}
}
Run Code Online (Sandbox Code Playgroud)
这是我configmap的入口控制器:
apiVersion: v1
data:
compute-full-forwarded-for: "true"
proxy-body-size: 500M
proxy-protocol: "true"
use-forwarded-headers: "true"
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: '{"apiVersion":"v1","data":null,"kind":"ConfigMap","metadata":{"annotations":{},"labels":{"app":"ingress-nginx"},"name":"nginx-configuration","namespace":"ingress-nginx"}}'
creationTimestamp: "2019-12-09T13:26:59Z"
labels:
app: ingress-nginx
name: nginx-configuration
namespace: ingress-nginx
Run Code Online (Sandbox Code Playgroud)
在我添加proxy_protocol指令之前一切正常,但现在我遇到了所有这些broken headers错误,而且我无法在没有connection reset错误的情况下访问入口后面的任何服务。
我的配置可能有什么问题?
我应该使用 http 反向代理而不是 tcp 反向代理吗?
谢谢你。
编辑:
我还应该说,LoadBalancer我的集群中没有任何类型的服务。我应该有一个吗?我正在考虑 Metallb,但我不确定它将添加到我的配置中,因为我已经使用 nginx 对节点进行了负载平衡。
Nginx 允许您指定是否在传入或传出请求中使用 proxy_protocol,但您将两者混淆了。
要在传入连接中使用 proxy_protocol ,您必须像这样添加proxy_protocol到listen行中:
listen 443 ssl proxy_protocol;
Run Code Online (Sandbox Code Playgroud)
要在传出连接中使用 proxy_protocol ,您必须使用独立proxy_protocol指令,如下所示:
proxy_protocol on;
Run Code Online (Sandbox Code Playgroud)
它们不一样。在负载均衡器中,传入连接来自浏览器,它们不使用代理协议。你只需要在你的传出请求中使用代理协议,到你的 kubernetes 集群中的 nginx-ingress。
因此,proxy_protocol从listen指令中删除参数,它应该可以工作。
此外,您希望use-forwarded-headers: "false"在 nginx-ingress 配置中。那控制是否使用X-Forwarded-For& co。传入连接中的标头(从 nginx-ingress 的角度来看,即从您的负载均衡器传出),并且您在这些连接中使用代理协议而不是标头。启用它后,您的用户可能能够通过指定 X-Forwarded-For 来欺骗 IP,这可能是一个安全问题。(仅当 nginx-ingress 优先于代理协议的标头时,我不确定)
旁白:nginx-ingress 本身已经在所有 pod 之间负载平衡流量。对于您的架构,您正在运行两个“层”的负载均衡器,这可能是不必要的。如果您想简化,请强制 nginx-ingress 在单个节点上运行(nodeSelector例如)并将所有流量发送到该节点。如果您想将负载均衡器保留在专用机器上,您可以将第 4 台机器加入集群并确保它只运行 nginx-ingress(带有污点和容忍)。
另外,请确保您使用 hostNetwork: true 运行 nginx-ingress,否则您可能还有另一层平衡(kube-proxy,kubernetes 服务代理)
| 归档时间: |
|
| 查看次数: |
2171 次 |
| 最近记录: |