我需要在 Kubernetes 中获取客户端 IP,但我只能获取 Flannel 内部 IP10.244.X.1
(在 nginx 中通过$remote_addr
,$http_x_forwarded_for
总是-
(。
网络拓扑是:
客户端浏览器 -> k8s 集群节点 ip -> k8s 服务 (A( -> Pod (需要客户端 ip( ->其他服务
我已经尝试过externalTrafficPolicy
A
,不起作用。它仅适用于云提供商,还是在 LB 后面?[1]
我也尝试了 ingress-nginx [2],得到了相同的结果。
我的环境:
Kernel Version: 3.10.0-1062.4.1.el7.x86_64
OS Image: CentOS Linux 7 (Core)
Operating System: linux
Architecture: amd64
Container Runtime Version: docker://18.6.2
Kubelet Version: v1.16.2
Kube-Proxy Version: v1.16.2
Network Add-on: Flannel
我读过一些类似的问题[3] [4] [5],看起来答案暗示了云提供商或LB。
Kubernetes 服务以三种代理模式之一工作:Userspace、iptables 和 IPVS。我不熟悉 IPVS,但在用户空间和 iptables 模式下,NodePort 和负载均衡器服务的客户端 IP 都会被更改 [docs]。
由于这种代理行为,客户端 IP 必然会发生变化,并且只有当客户端和服务器使用"更高层"协议并且存在"更高层"代理可以捕获原始客户端 IP 并将其注入请求中时,才能保留数据。如果客户端和服务器正在使用HTTP,那么IaaS L7/HTTP(S(负载均衡器或nginx可以为您注入标准标头,但是如果您使用的是nginx-ingress,那么问题在于它位于NodePort或LoadBalancer服务后面,因此当它到达实际的nginx进程时,客户端IP已被更改。您需要在集群外部运行nginx才能完成这项工作。
如果您在公共云上运行它,我认为大多数云的 L7 LB 解决方案都会为您注入这些开箱即用的X-Forwarded-For
或Forwarded
标头。或者,考虑将服务器设计为不需要客户端 IP - 如果使用客户端 IP 对客户端进行身份验证或授权请求,则还有其他更多的云原生模式可以代替。