Docker环境下如何获取客户端真实IP?配置异常求助
解决Docker环境下Nginx+Kong网关无法获取客户端真实IP的问题
问题根源
- Docker网络配置冲突:
api-gateway和myservice同时配置了networks: mynet与network_mode: bridge,后者会覆盖前者,导致容器实际使用默认Docker bridge网络而非自定义mynet。同时Nginx采用host网络模式,通过宿主机IP访问Kong时,Kong接收到的请求来源是宿主机在mynet中的网关IP(172.18.0.1)。 - Kong可信代理IP未配置:虽已设置
KONG_REAL_IP_HEADER=X-Forwarded-For和KONG_REAL_IP_RECURSIVE=on,但未指定KONG_TRUSTED_IPS,Kong默认不信任172.18.0.0/16子网的请求,不会从X-Forwarded-For中提取真实客户端IP。 - 请求转发路径不合理:Nginx通过宿主机IP访问Kong,多了一层端口转发,掩盖了真实客户端IP。
修复步骤
1. 修正Docker Compose网络配置
移除api-gateway和myservice中的network_mode: bridge(该配置会覆盖自定义网络),确保容器加入mynet网络。同时为Kong添加可信IP范围,允许其从指定子网的代理请求中解析真实IP。
修正后的docker-compose.yml关键片段:
services: nginx: image: nginx:latest restart: always volumes: - F:\home\config\nginx\nginx.conf:/etc/nginx/nginx.conf ports: - 89:89 network_mode: host # 若保留host模式,需确保Nginx能访问mynet网络中的Kong api-gateway: image: kong:latest restart: always privileged: true volumes: - /home/log/proxy_gateways/:/home/log/ - F:\home\kong:/home/kong environment: - KONG_ADMIN_LISTEN=127.0.0.1:8001,127.0.0.1:8446, 127.0.0.1:8444 ssl - KONG_PROXY_LISTEN=0.0.0.0:5000 - KONG_LOG_LEVEL=info - KONG_DECLARATIVE_CONFIG=/home/kong/kong.yml - KONG_PLUGINS=cors,rate-limiting - KONG_REAL_IP_HEADER=X-Forwarded-For - KONG_REAL_IP_RECURSIVE=on - KONG_TRUSTED_IPS=172.18.0.0/16,192.168.139.0/24 # 添加mynet子网和宿主机所在子网为可信范围 networks: - mynet ports: - 5000:5000 myservice: image: myservice:3.2.1 restart: always networks: - mynet ports: - 88:88 networks: mynet: name: mynet
2. 调整Nginx转发配置
将proxy_pass改为Kong容器的服务名(api-gateway:5000),避免通过宿主机端口转发,确保真实IP能直接传递到Kong:
修正后的Nginx配置:
server { listen 89; server_name localhost; location / { proxy_pass http://api-gateway:5000; # 使用Docker服务名直接访问Kong proxy_http_version 1.1; proxy_cache_bypass $http_upgrade; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; # 移除real_ip_recursive,Nginx作为入口代理无需解析自身的代理IP } }
若Nginx必须使用
host模式且无法解析Docker服务名,可通过docker inspect api-gateway获取Kong容器在mynet中的IP,直接填写到proxy_pass中。
3. 业务服务读取正确IP字段
业务服务需从请求头的X-Forwarded-For或X-Real-IP中获取真实IP:
X-Forwarded-For格式为客户端IP, 代理1IP, 代理2IP...,取第一个值即为真实客户端IP;- 不要直接读取请求的源IP(该IP会是Kong或Nginx的IP)。
4. 验证配置
- 重启所有容器:
docker-compose down && docker-compose up -d - 发送测试请求,检查业务服务日志或接口返回,确认是否获取到真实客户端IP;
- 查看Kong日志:
docker logs api-gateway,验证日志中是否包含真实客户端IP。
内容的提问来源于stack exchange,提问作者Ali.goodarzi
相关产品推荐
相关产品推荐

