说明:本文适用于腾讯云容器服务(Tencent Kubernetes Engine ,TKE),以下简称 TKE。
当需明确服务请求来源以满足业务需求时,则需后端服务能够准确获取请求客户端的真实源 IP。例如以下场景:
在 TKE 中默认的外部负载均衡器为 腾讯云负载均衡 作为服务流量的访问首入口,腾讯云负载均衡器会将请求流量负载转发到 Kubernetes 工作节点的 Kubernetes Service(默认)。此负载均衡过程会保留客户端真实源 IP(透传转发),但在 Kubernetes Service 转发场景下,无论使用 iptbales 或 ipvs 的负载均衡转发模式,转发时都会对数据包做 SNAT,即不会保留客户端真实源 IP。在 TKE 使用场景下,本文提供以下4种方式获取客户端真实源 IP,请参考本文按需选择适用方式。
该方式优缺点分析如下:
如需启用保留客户端 IP 功能,可在 Service 资源中配置字段 Service.spec.externalTrafficPolicy
。该字段表示服务是否希望将外部流量路由到节点本地或集群范围的 Pods。有两个选项值:Cluster
(默认)和 Local
方式。如下图所示:
Cluster
:表示隐藏客户端源 IP,LoadBalancer
和 NodePort
类型服务流量可能会被转发到其他节点的 Pods。Local
:表示保留客户端源 IP 并避免 LoadBalancer
和 NodePort
类型的服务流量转发到其他节点的 Pods,详情请参考 Kubernetes 设置外部负载均衡器说明。相关 YAML 配置示例如下:apiVersion: v1
kind: Service
metadata:
name: example-Service
spec:
selector:
app: example-Service
ports:
- port: 8765
targetPort: 9376
externalTrafficPolicy: Local
type: LoadBalancer
该方式优缺点分析如下:
使用 TKE 原生支持的 CLB 直通 Pod 的转发功能(CLB 透传转发,并绕过 Kubernetes Service 流量转发),后端 Pods 收到的请求的源 IP 即为客户端真实源 IP,此方式适用于四层及七层服务的转发场景。转发原理如下图:
详细介绍和配置请参见 在 TKE 上使用负载均衡直通 Pod。
该方式优缺点分析如下:
在七层(HTTP/HTTPS)服务转发场景下,可以通过获取 HTTP Header 中 X-Forwarded-For
和 X-Real-IP
字段的值来获取客户端真实源 IP。TKE 中有两种场景使用方式,原理介绍图如下所示:
腾讯云负载均衡器(CLB 七层) 默认会将客户端真实源 IP 放至 HTTP Header 的 X-Forwarded-For
和 X-Real-IP
字段。当服务流量在经过 Service 四层转发后会保留上述字段,后端通过 Web 服务器代理配置或应用代码方式获取到客户端真实源 IP,详情请参见 负载均衡如何获取客户端真实 IP。通过容器服务控制台获取源 IP 步骤如下:
X-Forwarded-For
或 X-Real-IP
字段值得到客户端真实源 IP。后端抓包测试结果示例如下图所示:Nginx Ingress 服务部署需要 Nginx Ingress 能直接感知客户端真实源 IP,可以采用保留客户端源 IP 的配置方式,详情请参见 Kubernetes 设置外部负载均衡器说明。或通过 CLB 直通 Pod 的方式,详情请参见 在 TKE 上使用负载均衡直通 Pod。当 Nginx Ingress 在转发请求时会通过 X-Forwarded-For
和 X-Real-IP
字段来记录客户端源 IP,后端可以通过此字段获得客户端真实源 IP。配置步骤如下:
Nginx Ingress 可以通过 TKE 应用商店、自定义 YAML 配置或使用官方(helm 安装)方式安装,原理和部署方法请参见 在 TKE 上部署 Nginx Ingress 中的部署方案1或方案3。若选择方案1部署,则需要修改 Nginx Ingress Controller Service 的 externalTrafficPolicy
字段值为 Local
。
安装完成后,会在容器服务控制台自动为 Nginx Ingress Controller 服务创建一个 CLB(四层)访问入口,如下图所示:
为需转发的后端服务创建一个 Ingress 资源并配置转发规则。YAML 示例如下:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx # ingressClass类为"nginx"
name: example
namespace: default
spec:
rules: # 配置服务转发规则
- http:
paths:
- backend:
serviceName: nginx
servicePort: 80
path: /
待配置生效后,在后端获取 HTTP Header 中的 X-Forwarded-For
或 X-Real-IP
字段值得到客户端真实源 IP。后端抓包测试结果示例如下图所示:
该方式优缺点分析如下:
TOA 内核模块原理和加载方式请参见 获取访问用户真实 IP 文档。
本页内容是否解决了您的问题?