You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Kubernetes中Nginx-ingress无法获取真实客户端IP(X-Real-Ip)求助

解决Nginx Ingress无法获取真实客户端IP(X-Real-Ip)的问题

我明白你已经尝试了externalTrafficPolicy: "Local"use-proxy-protocol: "true"但还是没解决问题,咱们一步步排查可能漏掉的配置点:

1. 确认Helm Values配置的正确性

首先要确保你的Helm values.yaml里的配置真的被正确应用了,这是最容易踩坑的地方:

  • 检查Service的externalTrafficPolicy是否生效:

    kubectl get svc <你的ingress-service名称> -n <命名空间> -o yaml | grep externalTrafficPolicy
    

    输出应该是externalTrafficPolicy: Local,如果不是,说明Helm配置没正确覆盖,可能是values里的层级不对(比如controller.service.externalTrafficPolicy: Local)。

  • 确认Proxy Protocol的配置同时在Service和ConfigMap中开启:
    在values.yaml里需要同时配置:

    controller:
      service:
        externalTrafficPolicy: Local
        # 如果是云服务商LB,可能需要加对应的注解开启Proxy Protocol,比如AWS:
        annotations:
          service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"
      config:
        use-proxy-protocol: "true"
        real_ip_header: "proxy_protocol"  # 关键!开启Proxy Protocol后要指定这个
    

    然后重新部署:helm upgrade <release名称> ingress-nginx/ingress-nginx -f values.yaml -n <命名空间>

2. 检查云服务商负载均衡的Proxy Protocol配置

如果你的集群运行在云服务商(AWS/GCP/Azure等)上,光配置Kubernetes还不够,必须让云LB也开启Proxy Protocol:

  • AWS NLB:需要在Service注解里添加上面提到的service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*",并且确保LB是Network Load Balancer(不是Classic)。
  • GCP GCLB:需要配置cloud.google.com/load-balancer-type: "External",并且在Backend Service里启用Proxy Protocol v2。
  • 阿里云SLB:需要在SLB控制台开启“透传客户端IP”或者“Proxy Protocol”选项。

3. 验证Nginx Ingress Pod的日志和请求头

直接在Nginx Ingress Pod里查看日志,确认真实IP是否被正确捕获:

  • 进入Pod:kubectl exec -it <ingress-pod名称> -n <命名空间> -- /bin/bash
  • 查看Nginx的access日志(通常在/var/log/nginx/access.log),日志格式里如果包含$remote_addr,开启Proxy Protocol后这个字段应该显示真实客户端IP;如果用$http_x_real_ip,需要确保Nginx正确设置了real_ip_header

也可以在Pod里curl后端服务,模拟请求看请求头:

curl -H "X-Real-Ip: 192.168.1.100" http://<后端服务地址>

然后看后端服务的日志是否能拿到这个IP,排除后端服务本身的问题。

4. 检查externalTrafficPolicy: Local的生效条件

这个配置要求流量直接发送到运行Ingress Pod的节点,所以:

  • 确保Ingress Pod分布在所有节点上(或者至少是客户端流量可能到达的节点),可以用kubectl get pods -o wide -n <命名空间>查看Pod所在节点。
  • 如果用了节点亲和性或污点容忍,确保没有限制Pod只能跑在特定节点,导致流量到达的节点没有Ingress Pod,从而被kube-proxy转发丢失IP。

5. 排除其他中间件干扰

如果集群里还有其他代理(比如Istio、Linkerd)或者防火墙,可能会修改或覆盖X-Real-Ip请求头。可以暂时禁用这些组件,或者检查它们的配置是否允许透传真实IP。

内容的提问来源于stack exchange,提问作者Or Nahum

火山引擎 最新活动