Kubernetes Nginx Ingress日志未显示用户外部IP,如何解决?
这个问题我之前在GCP环境里也碰到过,核心原因是GCP的HTTP(S)负载均衡器作为反向代理转发请求到Nginx Ingress Controller时,默认会把自己的内部IP(也就是你看到的10.28.0.1)作为请求源IP,而真实客户端IP会被放在X-Forwarded-For HTTP头中。要让日志显示真实外部IP,需要做两个关键配置:
解决方案步骤
1. 让Nginx Ingress信任GCP代理并启用转发头
我们需要配置Nginx Ingress Controller,让它识别并信任GCP负载均衡器的IP,同时启用对X-Forwarded-For头的解析,把真实客户端IP替换到日志的client字段中。
方式A:通过ConfigMap配置
如果你的Ingress Controller使用ConfigMap(通常名为nginx-ingress-controller),编辑该ConfigMap添加以下配置:
data: use-forwarded-headers: "true" proxy-real-ip-cidr: "10.28.0.0/16, 130.211.0.0/22, 35.191.0.0/16"
其中10.28.0.0/16是你环境中GCP内部LB的IP段,另外两个是GCP公共负载均衡器的标准CIDR范围,确保所有GCP代理IP都被信任。
应用配置并重启Ingress Controller Pod:
kubectl apply -f your-configmap-file.yaml kubectl rollout restart deployment nginx-ingress-controller
方式B:通过Deployment参数配置
如果是直接在Ingress Controller的Deployment中设置参数,在容器的args列表里添加以下内容:
args: - --use-forwarded-headers=true - --proxy-real-ip-cidr=10.28.0.0/16,130.211.0.0/22,35.191.0.0/16
同样应用配置并重启Pod:
kubectl apply -f your-ingress-deployment.yaml kubectl rollout restart deployment nginx-ingress-controller
2. 配置Service保留源IP
默认情况下,Kubernetes Service的externalTrafficPolicy是Cluster,这会导致节点对外部请求做SNAT(源地址转换),使得Ingress Controller看到的是节点IP而非真实客户端IP。需要将该字段改为Local:
编辑Ingress Controller的Service:
kubectl edit service nginx-ingress-controller
找到spec.externalTrafficPolicy字段,修改为:
spec: externalTrafficPolicy: Local
保存退出后,Service会自动更新配置。
验证效果
等待Pod重启和Service配置生效后,再发送测试请求并查看日志:
kubectl logs -f nginx-ingress-controller-xxxxxx-yyyyy
此时日志中的client字段应该会显示用户的真实外部IP了。
内容的提问来源于stack exchange,提问作者silgon

