更新时间:2023-12-07 GMT+08:00
不同场景下容器内获取客户端源IP
背景
Kubernetes已经成为当今容器化的标准,人们在享受容器带来的高效与便利的同时,也遇到一些烦恼:客户端和容器服务器之间可能存在多种不同形式的代理服务器,那容器中如何获取到客户端真实的源IP呢?下面就几种场景类型进行讨论。
原理介绍
七层转发:
Ingress:应用在七层访问时,客户端源IP默认保存在HTTP头部的“X-Forwarded-For”字段,无需做其他操作。
- ELB型:自研ELB型Ingress基于弹性负载均衡服务ELB实现公网和内网(同一VPC内)的七层网络访问,当后端服务为NodePort类型时,需将“服务亲和”选项设置为“节点级别”。
- Nginx型:基于nginx-ingress插件实现七层网络访问,后端服务支持ClusterIP和NodePort类型。当后端服务为NodePort类型时,同样需将“服务亲和”选项设置为“节点级别”。
四层转发:
- 节点访问:Nodeport访问方式,是将容器端口映射到节点端口,如果“服务亲和”选择“集群级别”需要经过一次服务转发,无法实现获取客户端源IP,而“节点模式”不经过转发,可以获取客户端源ip。
七层转发(Ingress)
针对七层服务(HTTP/HTTPS协议),需要对应用服务器进行配置,然后使用X-Forwarded-For的方式获取来访者的真实IP地址。
真实的来访者IP会被负载均衡放在HTTP头部的X-Forwarded-For字段,格式如下:
X-Forwarded-For: 来访者真实IP, 代理服务器1-IP, 代理服务器2-IP, ...
当使用此方式获取来访者真实IP时,获取的第一个地址就是来访者真实IP。
- 添加Ingress时,若后端为NodePort类型的Service,需将服务亲和设置为“节点级别”,即spec.externalTrafficPolicy需设置为“Local”,参见节点访问 ( NodePort )。
- 以Nginx工作负载为例,未配置源IP访问前,使用以下命令查看访问日志,其中nginx-c99fd67bb-ghv4q为Pod名称:
kubectl logs nginx-c99fd67bb-ghv4q
回显如下:
... 10.0.0.7 - - [17/Aug/2023:01:30:11 +0000] "GET / HTTP/1.1" 200 19 "http://114.114.114.114:9421/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.203" "100.125.**.**"
其中100.125.**.**为负载均衡的地址段,说明流量经过负载均衡转发。
- 前往ELB控制台,开启ELB实例对应监听器的“获取客户端IP”功能。独享型ELB默认开启源地址透传功能,无需手动开启。
- 登录弹性负载均衡ELB的管理控制台。
- 在管理控制台左上角单击图标,选择区域和项目。
- 选择“服务列表 > 网络 > 弹性负载均衡”。
- 在“负载均衡器”界面,单击需要操作的负载均衡名称。
- 切换到“监听器”页签,单击需要修改的监听器名称右侧的“编辑”按钮。如果存在修改保护,请在监听器基本信息页面中关闭修改保护后重试。
- 开启“获取客户端IP”开关。
- (该步骤仅Nginx Ingress需执行)编辑nginx-ingress插件,在nginx配置参数处,需要添加的配置字段和信息(配置参数范围请参考社区文档)。配置完成后,更新插件。
{ "enable-real-ip": "true", "forwarded-for-header": "X-Forwarded-For", "proxy-real-ip-cidr": "100.125.0.0/16", "keep-alive-requests": "100" }
proxy-real-ip-cidr参数为代理服务器的网段。
- 共享型负载均衡的IP地址段 100.125.0.0/16(100.125.0.0/16是负载均衡服务保留地址,其他用户无法分配到该网段内,不会存在安全风险)和高防IP地址段。
- 独享型负载均衡需要添加ELB实例关联的VPC子网网段。
- 重新访问工作负载,并查看新增的访问日志如下:
... 10.0.0.7 - - [17/Aug/2023:02:43:11 +0000] "GET / HTTP/1.1" 304 0 "http://114.114.114.114:9421/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36 Edg/115.0.1901.203" "124.**.**.**"
显示成功获取到客户端源IP。
父主题: 网络