1. 项目概述
在私有云Kubernetes环境中,当使用HAProxy作为四层负载均衡器配合Ingress-NGINX作为七层入口时,业务Pod(如Nginx)的访问日志中往往无法记录真实的客户端IP地址,而是显示K8s内部地址或HAProxy的地址。这个问题源于多层代理架构对源IP的层层改写,本文将详细解析如何通过完整的链路配置实现真实客户端IP的透传。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心原理解析
2.1 多层代理架构下的IP传递问题
在典型的"客户端 → HAProxy → Ingress-NGINX → 业务Pod"架构中,每一层代理都会修改请求的源IP信息:
- HAProxy层:作为四层负载均衡器,默认使用TCP模式转发流量,原始客户端IP信息会丢失
- Ingress-NGINX层:作为七层入口控制器,默认会使用自己的IP作为请求源
- 业务Pod层:最终接收到的请求源IP是上一跳的Ingress-NGINX Pod IP
2.2 解决方案设计思路
要实现真实IP透传,需要在三个关键位置进行配置:
- HAProxy配置:启用PROXY协议v2,在四层转发时携带原始连接信息
- Ingress-NGINX配置:
- Service设置externalTrafficPolicy=Local保留源IP
- ConfigMap启用PROXY协议和X-Forwarded-For处理
- 业务Nginx配置:使用realip模块从HTTP头中提取真实IP
3. 详细配置步骤
3.1 Ingress-NGINX Service配置
3.1.1 externalTrafficPolicy参数详解
Kubernetes Service的externalTrafficPolicy参数有两种模式:
yaml复制apiVersion: v1
kind: Service
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
externalTrafficPolicy: Local # 关键配置
type: NodePort
ports:
- name: http
port: 80
targetPort: http
nodePort: 32280
selector:
app.kubernetes.io/component: controller
-
Cluster模式(默认):
- 流量会负载均衡到所有节点的后端Pod,可以跨节点转发
- 源IP会经过SNAT转换,通常变为节点IP
- 优点:高可用性好,任何节点都可以接收流量
- 缺点:无法保留真实客户端IP
-
Local模式:
- 流量只会转发到接收请求的节点上的本地Pod
- 如果当前节点没有对应Pod,连接会失败
- 优点:保留真实客户端IP
- 缺点:需要确保每个入口节点都有Ingress Pod
生产建议:使用DaemonSet方式部署Ingress-NGINX,确保每个Worker节点都有实例
