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

Docker Desktop Kubernetes中Nginx-Ingress无法传递客户端真实IP至Keycloak

问题根源分析

你的问题核心在于Docker Desktop的网络转发机制:在M1 Mac上,Docker Desktop运行在一个Linux虚拟机(IP为192.168.65.3)中,所有外部流量到达Mac主机后,会被转发到这个VM,VM会对流量做SNAT(源地址转换),将客户端真实IP替换为VM自身的集群IP。这就导致nginx-ingress接收到的请求源IP都是192.168.65.3,而非真实客户端IP。

流量完整路径:
外部客户端 → 路由器 → Mac主机物理网卡 → Docker Desktop Linux VM(192.168.65.3)→ NodePort Service → nginx-ingress Pod → Keycloak Pod


1. 修改Nginx-Ingress Controller配置,启用真实IP解析

需要在Controller的启动参数中添加真实IP相关配置,告诉nginx信任Docker VM的子网,从请求头中提取真实IP。

修改你的Controller Deployment的args部分:

args: [
  "/nginx-ingress-controller",
  "--default-backend-service={{.Values.namespace}}/default-http-backend-2",
  "--enable-ssl-passthrough",
  "--enable-real-ip",  # 启用真实IP解析
  "--real-ip-header=X-Forwarded-For",  # 指定从哪个头获取真实IP
  "--set-real-ip-from=192.168.65.0/24",  # 信任Docker VM所在子网
  "--set-real-ip-from=你的Mac主机IP段",  # 比如你的Mac在192.168.1.0/24就填这个
  "--set-real-ip-from=你的路由器IP段",  # 比如路由器网关是192.168.1.1,填192.168.1.0/24
  "--log-format-upstream='{\"time\": \"$time_local\", \"remote_addr\": \"$remote_addr\", \"x-forwarded-for\": \"$http_x_forwarded_for\", \"x-real-ip\": \"$http_x_real_ip\"}'",  # 自定义日志格式,方便排查
]

2. 优化Ingress资源的Annotations

添加配置片段,强制nginx传递正确的转发头到Keycloak:

metadata:
  annotations:
    # 保留原有annotations,新增以下内容
    nginx.ingress.kubernetes.io/configuration-snippet: |
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"

3. 配置路由器传递真实IP

如果你的路由器支持,需要在端口转发规则中开启X-Forwarded-For头注入,将客户端的真实IP添加到请求头中。这一步很关键,因为如果路由器不传递这个头,nginx拿到的源IP还是Docker VM的IP,无法提取真实客户端IP。

4. 验证配置效果

  1. 重新部署nginx-ingress Controller和Ingress资源:
    kubectl apply -f your-ingress-controller-deployment.yaml
    kubectl apply -f your-ingress-resource.yaml
    
  2. 查看nginx-ingress Pod的日志,检查x-forwarded-for字段是否包含真实客户端IP:
    kubectl logs -n <你的命名空间> <nginx-ingress-pod-name>
    
  3. 登录Keycloak后台,查看用户登录记录的IP字段,确认是否已显示真实IP。

额外说明:docker-compose场景的问题

单独用docker-compose启动Keycloak时,同样因为Docker Desktop的网络转发,流量从Mac主机进入容器时源IP被替换为Docker网桥的IP。解决方法是:

  • 在docker-compose.yml中为Keycloak容器添加network_mode: host(不推荐,可能有端口冲突);
  • 或者使用nginx反向代理前置Keycloak,在nginx中配置real_ip_header X-Forwarded-For和set_real_ip_from信任Docker网桥的IP段,同时确保路由器传递X-Forwarded-For头。

内容的提问来源于stack exchange,提问作者Duane Allman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 16:33:15