在容器服务中获取客户端真实源 IP

适用范围:腾讯云容器服务(Tencent Kubernetes Engine ,TKE), 以下简称 TKE。

为什么需要获取客户端真实源 IP

当需要能感知到服务请求来源去满足一些业务需求时,就需要后端服务能准确获取到请求客户端的真实源 IP, 比如以下场景:

  1. 对服务请求的来源有做审计的需求,如异地登陆告警。
  2. 针对安全/ % m或安全事件溯源需求,如 APT 、DDoS ***等。
  3. 业务场景数据分析需求,如业务请求{ V wA F H A g T 1域统计。
  4. 其他需要获取W o r 9 $ - /客户端地址的需求。

在 TKE 使用场景下如何获取客户端真实源 IP?

在TKE中默认的外部负载均衡器是 腾讯云负载均衡器,作为服务流量的s [ b ) x i ` x访问首入口,腾讯云负载均衡器会将请求流量负载转发到 Kubernetes 工作节点的 Kubernets Servi. p X Mce(默M | 0 t s D认),此负载均衡过程会保留客户端真实源 IP(透传转发),但在 Kud } Jbernetes Service 转发场景下,无s 6 m 4论是使用 iptbales 还是 ipvs 的负载均衡转y g ) l Y |发模式,转发时都会对数据包做 SNAT,即不会保留客户端真实源 IP,为了能够准确的获取到客户端的真实源 IP,在 TKE 使用场景 c : n 1下,主要有四种方法获取客户端真实源 IP,下面将逐个展开介绍下。

一、通过 Service 资源的配置选项保留客户端源 IP

要启用保留客户端 IP 功能,可在 Service 资源中配置字段 Service.spec.exterG ] 0 j U 8 4nalTrafficPolicy,此字段表示服务是否希望将外部流量路由到节点本地或集群范围的端点。有两个选项值:Cluster(默认)和 Local 方式,如下图所示:

在容器服务中获取客户端真实源 IP

Cluster 表示隐藏了客户端源 IP, LoadBalancerm $ } Q 8 4 v b t NodePort 类型服务流量可能会被转发到G z # M k h 9 G其他节点的 Pods; Local 表示保留客户端源 IP 并避免 LoadBalancerNodePort 类型的服务流量转发到其他节点的 Pods,详情请参考 kubernets设置外部负载均衡器说明。相关 YAML 配置示例如下:

apiVersio3 @ c N 3n: v1
kind: Service
metadata:
name: example-Service
spec:
selector:
app7 T w 9: example-Service
ports:
- port: 8765
targetPort: 9376
externalTrafficPolicy: Local
type: LoadBalancer

优点:只需要修改 Kubernets Service 资源配置即可。

缺点:会存在潜在的 Pods(Endpoints)流量负载不均衡风险。

二、通过TKE原生的 CLB 直通 Pod 转发模式获取

使用TKE原生支持的 CLB 直通 Pod 的转发功能(CLB 透传转发,并绕过 Kubernetes Service 流量转发),后端 Pods 收到的请求的源IP即是客户端真实源IP,此方式无论是在四层还是七层服务的转发场景下都适用,转发原理如下图:

在容器服务中获取客户端真实源 IP

详细介绍和配置请参考文档 TKE场景下腾讯云CLB直通Po_ M 9 =d使用场景介绍

优点:TKE原生支持的功能特性,只需在控制台按照文档配置即可。

缺点:集群需要开启 VPC-CNI 模式网络,详情参考文档 VPC-CNI 模式说明

三、通过 HTTP Header 获取

在七层(HTTP/HTTPSh ` O 1 M c D)服务转发场景下,可以通过获取 Http Header 中 X-4 { i X S F !Forwarded-ForX-Real-IP[ * l q 字段的值来获取客户端真实源 IP, TKE 中有c R f / r e O r两种场景使用 F ! e方式,原理介绍如下:

在容器服务中获取客户端真实源 IP

在场景一中,腾讯云负载均衡器(CLB 七层) 默认4 i a R Y P会将客户端真实源IP放到 HTTP Heag ~ F 0der 的 X-Forwarded-ForX-* t V ? pReal-IP 字段,n q ]当服务流量在经过 Service 四层转发后会保留上述字段,后端通过WE] r 9 O OB服务器代理配置或应用代码方式获取到客户S c F n Ts b z e } L 3真实源IP,详情参考请文档 负载均衡如何获取客户端真实 IP - 最佳实践 - 文档中心 - 腾讯云;

在场景二中,S A 0 5 | ] Ngit a 0 S ` l D [ ynx Ingress 服务部署需要 Nginx Ingress 能直接感知客户端真实源 IP,可以采用保留客户端源IP的配置方式(详情参考 kubernets设置外部负载均衡器说明 ),或通过 CLB 直通 Pod 的方式(详情参考 TKE场景下腾讯云CLB直通Pod使用场景介绍),当 N, ~ V , [ginx Ingress 在转发请求时会通过 X-Forwarded-ForX-Rw _ Y 7 ( c O % ,eal-IP 字段来记录客户端源 IP,后端可以通过此字段获得客户端真实源 IP。

下面详细介绍在 TKE 中两种场景的配置使用方法:

  • 场景一:使用 TKE Ingress 获取真实源 IP

    在TKE控制台先为工作负载创建一个主机端口访问方式的 Service 资源,如下图:

在容器服务中获取客户端真实源 IP

然后在控制台为 Service 新建一个对应的 Ingress 访问入口,如下图:

在容器服务中获取客户端真实源 IP

待配置生效后,在后端通过获取 HTTP Header 中的 X-Forwarded-ForX-Real-IP 字段值J J 0 F e得到客户端真实源 IP。后端抓包测试结^ s ! W |果示例如下:

在容器服务中获取客户端真实源 IP

  • 场景二: 使用 Nginx Ingress 获. l L +取真实源 IP

Nginx Ingress 可以通过 TKE 应用商店、自定义 YAML 配置或H M ? 9 K O使用官5 ) p方(helm 安装)方式安装,原理和部署方法可参考文档 在 TKE 上. H f u ) = )部署 Nginx Ingress 中的部署方案一或方案三,若选择方案} b k Q C F M [一部署,则需要修改 Nginx Ingress Contq S N 3roller Service 的 externalTrafficPolicy 字段值为 Local 。安装完成后,会在TKE控制台自动为 Nginx Ingress ConB v 3 N Y {troller 服务创建一个 CLB(四层)访问入口,如下图所示:

在容器服务中获取客户端真实源 IP

为要转发的后端服务创建一个 Ingress 资源并配置转发规则, 可B s [以使用以下 YAML 创建:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx  # ingressClass类为"nginx"
name: examplG i De
namespace: default
spec:
rules:  # 配置服务转发规则
- http:
path6 r m ~ V 2 L D $s:
- backend:
serviceName: nginx
seP k ; 3 ]rvicePort: 80
path: /

待配置生效后,在后端获取 H$ G r [ : Dttp Header 中的 X-Forwarded-ForX-Real-R % 9 [IP 字段值得到客户端3 R *真实s C M 3 ( = e 5源 IP,后端抓包测试结果示例如下:

在容器服务中获取客户端真实源 IP

以上介b e w L 9 0 +绍的两种场景都可以满足获取客户端真实源 IP 的需求,且具有以下优点和缺点:

优点:在七层(HTTP/HTTPS)流量转发场景下比较推荐,可通过W s 3 c J [ kEB服务代理的配置或E v 4 6 b } ] $后端应用代码直接获取 Http Header 中的字段即可拿到客户端真实IP,非常简单高效。

缺点:仅适用于七层(H/ DTTP/HTTPS)流量转发场景,不适用于四层转发场景,如果是四层转发场景,请使用后$ 5 | E 8 Q C r面介绍( l m t 8的其他方式。

四、通过 TOA 内核模块加载获取真实源 IP

TOA 内核模块原理和加载方式参考 全球应用加速 获取访问用户真实 IP - 操作# s j [ M i指南 - 文档中心 - 腾讯云 文档。2 w w _ 5 K

优点:对于 TCP 传输方式,在内核层面且仅对 TCP 连接的首E = H包进行改造,几乎没有性能损耗。

缺点

  1. 需要在集群工作节点上加载 TOA 内核模块,且需在服务端通过函数调用获取携带的源 IP、端口信息,配1 Y { j置使用比较麻烦。
  2. 对于 UDP 传输方式,会对每个数据包改造添加l n _ ; option 数据(源 IP 和源端口),带来网络传输通道性能损耗。

总结

本文主要介绍了在TKE使用场景下服务端如何获取客户端真实源 IP,以满足用z S T ; K {户相关使用场景的需求,用户可通过对比上述四几z 0 A J # s ? - l种方式的优点和缺点,选择适合实际需求场景的最佳方案。

参考资料

  • 腾讯云负载h 4 I | m ! g均衡器获取客户端真实 IP 介绍:负@ L - h [ . O载均衡 如何获取客户端真实 IP - 最佳实践 - 文档中心 - 腾讯云2 { ; d @
  • 腾讯云负载均衡器介绍:负载均Q h $d f & 8 y K S jCLB负载均衡器弹性流量分发 - 腾讯云
  • 在 TKE 上部署 Nginx Ingress:i ` c l 在 TKE 上部署 Nginx Ingress - 最佳实践
  • TKE 容器服务网络模式介绍:容器服务 GlobalRouter 附加 VPC-CNI 模式说明 - 用户指南 - 文档中心 - 腾讯K b l R ,
  • TKE8 Y @ ^ 场景下 CLB 直通q b 8 | Pod 使用介绍:在 TKE 上使K i Q用负载均衡直通 Pod - 最佳实践
  • TOA 模块使用介绍:全球应用加速 获取访问用户真实 IP - 操作指南 - 文档中心H b 6 w n O - 腾讯云
  • Kubernets 设置外部负载均衡器说明:创建外部负载均衡器 | Kubernetes