You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kubernetes+Metallb+Traefik环境下如何获取真实客户端IP?

问题分析与解决方案

我来帮你理清楚为啥X-Real-IP显示的是10.5.64.0,以及怎么拿到真实的客户端IP 192.168.0.100。

为啥X-Real-IP不对?

咱们先搞清楚根源:这是Kubernetes LoadBalancer Service的默认SNAT行为导致的。

  • 你用LoadBalancer类型的Service暴露Traefik时,Kubernetes会自动对进入的请求做「源地址转换(SNAT)」——简单说就是把客户端的真实IP替换成集群内部的Node或者Service IP(也就是你看到的10.5.64.0这个段的IP)。
  • 虽然你在Traefik的traefik.toml里设置了trustedIPs = ["0.0.0.0/0"],但请求到达Traefik之前,源IP已经被SNAT修改了,Traefik根本拿不到真实的客户端IP,只能拿到被替换后的集群内部IP。

怎么拿到真实客户端IP?

要解决这个问题,核心是让Kubernetes别乱改源IP,同时确保Traefik能正确识别转发头。具体操作如下:

1. 修改Traefik Service,关闭SNAT

更新你的Traefik Service配置,添加externalTrafficPolicy: Local——这个配置会告诉Kubernetes保留客户端的真实IP,不再做SNAT:

kind: Service
apiVersion: v1
metadata:
  name: traefik-ingress-service
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
    - protocol: TCP
      port: 80
      name: http
    - protocol: TCP
      port: 443
      name: https
  type: LoadBalancer
  externalTrafficPolicy: Local  # 关键:添加这一行

执行命令应用修改:

kubectl apply -f traefik-service.yaml -n kube-system

2. 确认Traefik的转发头配置没问题

你当前的traefik.toml里已经正确配置了forwardedHeaders的trustedIPs,在本地测试环境这个配置完全够用。如果是生产环境,建议把信任IP限制为你的负载均衡器或代理的IP段,防止恶意伪造转发头,但你的场景下不用调整。

3. 验证结果

从192.168.0.100的主机再跑一遍测试命令:

wget -qO - clusterip.staging

这次你应该能在返回结果里看到X-Real-IP是192.168.0.100了。

额外说明

  • externalTrafficPolicy: Local的作用是让Service只把流量转发到运行Traefik Pod的Node上,同时保留客户端源IP。如果你的Traefik Pod只在部分Node上运行,要确保LoadBalancer的流量能到达这些Node哦。
  • 要是你用的是云厂商的Kubernetes集群,有些服务商可能需要额外配置才能支持保留源IP,但本地环境(比如minikube、k3s)这个配置直接就能生效。

内容的提问来源于stack exchange,提问作者Andrey Perminov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:59:01