通过Nginx Ingress Controller让K8s Pod获取真实客户端IP的问题
解决Nginx Ingress Controller下Pod直接获取真实客户端IP的问题
核心原因
你的Ingress Controller对应的Service未设置externalTrafficPolicy: Local,导致Kubernetes对进入的流量执行了SNAT(源地址转换),将客户端真实IP替换为集群节点的内部IP,最终后端Pod拿到的是Ingress Controller的IP而非客户端真实IP。
解决步骤
1. 修改Nginx Ingress Controller的Service配置
将Ingress Controller的Service的externalTrafficPolicy设为Local,禁止K8s对流量进行跨节点转发和SNAT,确保流量直接到达运行Ingress Controller Pod的节点,保留客户端真实IP:
apiVersion: v1 kind: Service metadata: name: nginx-ingress-controller namespace: ingress-nginx # 根据你的实际命名空间调整 spec: type: NodePort # 或LoadBalancer,匹配你的暴露方式 externalTrafficPolicy: Local selector: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/instance: ingress-nginx # 其他端口配置...
2. 配置Nginx Ingress Controller的ConfigMap
确保Ingress Controller不会通过请求头传递IP,而是直接将真实客户端IP透传给后端Pod:
apiVersion: v1 kind: ConfigMap metadata: name: nginx-ingress-controller namespace: ingress-nginx # 对应Ingress Controller的命名空间 data: # 禁用转发头,避免通过X-Forwarded-*传递IP use-forwarded-headers: "false" # 信任HAproxy所在网段(若HAproxy地址固定,建议替换为具体CIDR,提升安全性) proxy-real-ip-cidr: "0.0.0.0/0" # 启用真实IP获取,直接使用请求的源IP enable-real-ip: "true"
3. 验证配置
- 重启Nginx Ingress Controller Pod,让配置生效:
kubectl rollout restart deployment nginx-ingress-controller -n ingress-nginx - 访问后端服务,检查Pod内的
client_address是否已显示客户端真实IP。
额外注意事项
- 确认外部HAproxy的透明模式配置正确,未修改请求的源IP。
- 若Ingress Controller采用DaemonSet模式,
externalTrafficPolicy: Local的效果会更稳定,因为每个节点都有Ingress Controller Pod,流量不会被转发到其他节点。
内容的提问来源于stack exchange,提问作者Wolfdale
相关产品推荐
相关产品推荐

