在容器服务中获取客户端真实源 IP
适用范围:腾讯云容器服务(Tencent Kubernetes Engine ,TKE), 以下简称 TKE。
为什么需要获取客户端真实源 IP?
当需要能感知到服务请求来源去满足一些业务需求时,就需要后端服务能准确获取到请求客户端的真实源 IP, 比如以下场景:
- 对服务请求的来源有做审计的需求,如异地登陆告警。
- 针对安全攻击或安全事件溯源需求,如 APT 攻击、DDoS 攻击等。
- 业务场景数据分析需求,如业务请求区域统计。
- 其他需要获取客户端地址的需求。
在 TKE 使用场景下如何获取客户端真实源 IP?
在TKE中默认的外部负载均衡器是 腾讯云负载均衡器,作为服务流量的访问首入口,腾讯云负载均衡器会将请求流量负载转发到 Kubernetes 工作节点的 Kubernets Service(默认),此负载均衡过程会保留客户端真实源 IP(透传转发),但在 Kubernetes Service 转发场景下,无论是使用 iptbales 还是 ipvs 的负载均衡转发模式,转发时都会对数据包做 SNAT,即不会保留客户端真实源 IP,为了能够准确的获取到客户端的真实源 IP,在 TKE 使用场景下,主要有四种方法获取客户端真实源 IP,下面将逐个展开介绍下。
一、通过 Service 资源的配置选项保留客户端源 IP
要启用保留客户端 IP 功能,可在 Service 资源中配置字段 Service.spec.externalTrafficPolicy
,此字段表示服务是否希望将外部流量路由到节点本地或集群范围的端点。有两个选项值:Cluster
(默认)和 Local
方式,如下图所示:
Cluster
表示隐藏了客户端源 IP, LoadBalancer
和 NodePort
类型服务流量可能会被转发到其他节点的 Pods; Local
表示保留客户端源 IP 并避免 LoadBalancer
和 NodePort
类型的服务流量转发到其他节点的 Pods,详情请参考 kubernets设置外部负载均衡器说明。相关 YAML 配置示例如下:
apiVersion: v1
kind: Service
metadata:
name: example-Service
spec:
selector:
app: 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,此方式无论是在四层还是七层服务的转发场景下都适用,转发原理如下图:
详细介绍和配置请参考文档 TKE场景下腾讯云CLB直通Pod使用场景介绍。
优点:TKE原生支持的功能特性,只需在控制台按照文档配置即可。
缺点:集群需要开启 VPC-CNI 模式网络,详情参考文档 VPC-CNI 模式说明
三、通过 HTTP Header 获取
在七层(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 - 最佳实践 - 文档中心 - 腾讯云;
在场景二中, Nginx Ingress 服务部署需要 Nginx Ingress 能直接感知客户端真实源 IP,可以采用保留客户端源IP的配置方式(详情参考 kubernets设置外部负载均衡器说明 ),或通过 CLB 直通 Pod 的方式(详情参考 TKE场景下腾讯云CLB直通Pod使用场景介绍),当 Nginx Ingress 在转发请求时会通过 X-Forwarded-For
和 X-Real-IP
字段来记录客户端源 IP,后端可以通过此字段获得客户端真实源 IP。
下面详细介绍在 TKE 中两种场景的配置使用方法:
场景一:使用 TKE Ingress 获取真实源 IP
在TKE控制台先为工作负载创建一个主机端口访问方式的 Service 资源,如下图:
然后在控制台为 Service 新建一个对应的 Ingress 访问入口,如下图:
待配置生效后,在后端通过获取 HTTP Header 中的 X-Forwarded-For
或 X-Real-IP
字段值得到客户端真实源 IP。后端抓包测试结果示例如下:
场景二: 使用 Nginx Ingress 获取真实源 IP
Nginx Ingress 可以通过 TKE 应用商店、自定义 YAML 配置或使用官方(helm 安装)方式安装,原理和部署方法可参考文档 在 TKE 上部署 Nginx Ingress 中的部署方案一或方案三,若选择方案一部署,则需要修改 Nginx Ingress Controller Service 的 externalTrafficPolicy
字段值为 Local
。安装完成后,会在TKE控制台自动为 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,后端抓包测试结果示例如下:
以上介绍的两种场景都可以满足获取客户端真实源 IP 的需求,且具有以下优点和缺点:
优点:在七层(HTTP/HTTPS)流量转发场景下比较推荐,可通过WEB服务代理的配置或后端应用代码直接获取 Http Header 中的字段即可拿到客户端真实IP,非常简单高效。
缺点:仅适用于七层(HTTP/HTTPS)流量转发场景,不适用于四层转发场景,如果是四层转发场景,请使用后面介绍的其他方式。
四、通过 TOA 内核模块加载获取真实源 IP
TOA 内核模块原理和加载方式参考 全球应用加速 获取访问用户真实 IP - 操作指南 - 文档中心 - 腾讯云 文档。
优点:对于 TCP 传输方式,在内核层面且仅对 TCP 连接的首包进行改造,几乎没有性能损耗。
缺点:
- 需要在集群工作节点上加载 TOA 内核模块,且需在服务端通过函数调用获取携带的源 IP、端口信息,配置使用比较麻烦。
- 对于 UDP 传输方式,会对每个数据包改造添加 option 数据(源 IP 和源端口),带来网络传输通道性能损耗。
总结
本文主要介绍了在TKE使用场景下服务端如何获取客户端真实源 IP,以满足用户相关使用场景的需求,用户可通过对比上述四几种方式的优点和缺点,选择适合实际需求场景的最佳方案。
参考资料
- 腾讯云负载均衡器获取客户端真实 IP 介绍:负载均衡 如何获取客户端真实 IP - 最佳实践 - 文档中心 - 腾讯云
- 腾讯云负载均衡器介绍:负载均衡CLB负载均衡器弹性流量分发 - 腾讯云
- 在 TKE 上部署 Nginx Ingress: 在 TKE 上部署 Nginx Ingress - 最佳实践
- TKE 容器服务网络模式介绍:容器服务 GlobalRouter 附加 VPC-CNI 模式说明 - 用户指南 - 文档中心 - 腾讯云
- TKE 场景下 CLB 直通 Pod 使用介绍:在 TKE 上使用负载均衡直通 Pod - 最佳实践
- TOA 模块使用介绍:全球应用加速 获取访问用户真实 IP - 操作指南 - 文档中心 - 腾讯云
- Kubernets 设置外部负载均衡器说明:创建外部负载均衡器 | Kubernetes
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!
在容器服务中获取客户端真实源 IP的更多相关文章
- C# 服务端获取客户端 系统/浏览器/IP
/// <summary> /// 获取客户端操作系统版本 /// </summary> /// <returns></returns> public ...
- 通过HttpservletRequest对象获取客户端的真实IP地址
这篇文章主要介绍了Java中使用HttpRequest获取用户真实IP地址,使用本文方法可以避免Apache.Squid.nginx等反向代理软件导致的非真实IP地址,需要的朋友可以参考下 在JSP里 ...
- IE8下服务端获取客户端文件的路径为C:/fakePath问题的解决方案
上一篇文章上提到,IE8下服务端获取客户端文件的路径时,会变成C:/fakePath问题,于是乎通过文件路径去获得文件大小就失败了. 上网搜了一下,主要原因是IE8因为安全考虑,在上传文件时屏蔽了真实 ...
- nodejs之获取客户端真实的ip地址+动态页面中引用静态路径下的文件及图片等内容
1.nodejs获取客户端真实的IP地址: 在一般的管理网站中,尝尝会需要将用户的一些操作记录下来,并记住是哪个用户进行操作的,这时需要用户的ip地址,但是往往当这些应用部署在服务器上后,都使用了ng ...
- F5中源地址转换(AutoMap)模式下后端服务器获取客户端真正的IP地址
F5中开启AutoMap,并传递X-Forwarded-For值 开启F5源地址转换"Auto Map" 方式一: 在http profile中开启X-Forwarded-For ...
- 负载均衡获得真实源IP的6种方法 【转】
除了X-FORWARD-FOR,负载均衡中获得真实源IP的方法还有很多种, 本文抛砖引玉,主要介绍获得真实源IP的多种方法,而不是具体配置, 负载均衡获得真实IP的方法有很多种,将形成专题文章, 本文 ...
- 负载均衡获得真实源IP的6种方法
除了X-FORWARD-FOR,负载均衡中获得真实源IP的方法还有很多种. 本文抛砖引玉,主要介绍获得真实源IP的多种方法,而不是具体配置. 负载均衡获得真实IP的方法有很多种,将形成专题文章. 本文 ...
- 通过Request获取客户端的真实IP
我们在做项目的时候经常需要获取客户端的真实ip去进行判断,为此搜索了相关文章,以下这个讲解的比较明白,直接拿来 https://blog.csdn.net/yin_jw/article/details ...
- 获取客户端用户真实ip方法整理(jekyll迁移)
layout: post title: 获取客户端用户真实ip方法整理 date: 2019-08-22 author: xiepl1997 tags: springboot 由请求获取客户端ip地址 ...
随机推荐
- TCP三次握手、四次挥手理解及可能问为什么?
三次握手: TCP3次握手连接:浏览器所在的客户机向服务器发出连接请求报文(SYN标志为1),此时,TCP客户端进程进入了 SYN-SENT(同步已发送状态)状态. 服务器接收报文后,同意建立连接, ...
- 实用js方法DataUrl转为File、url转base64
声明:仅为方便自己所需,也希望能方便他人,如有侵权,联系删除. 1,DataUrl转为File /** * DataUrl转为File * @param {String} dataUrl - data ...
- JVM垃圾回收行为的并行与并发
程序的并行和并发 程序的并发(Concurrent) 在操作系统中,是指一个时间段中有几个程序都处于己启动运行到运行完毕之间,且这几个程序都是在同一个处理器_上运行. 并发不是真正意义上的“同时进行” ...
- RXJAVA之异步操作
Observable提供了一些do方法来快速提供监听响应事件. doOnComplete 当complete时,执行action. doOnTerminate 当结束执行action,无论是正常还是异 ...
- Flutter学习五之网络请求和轮播图的实现
上期讲到了,怎样实现一个下拉刷新和加载更多的列表,数据更新,需要使用到网络请求,在flutter中,怎样实现一个网络请求呢?官方使用的是dart io中的HttpClient发起的请求,但HttpCl ...
- Windows10上安装MySQL(详细)
一.下载MySQL 1.在浏览器里打开mysql的官网http://www.mysql.com 2.进入页面顶部的"Downloads" 3.下滑页面,打开页面底部的"C ...
- 转载:pycharm IDE 导入自定义模块
http://www.mamicode.com/info-detail-2241193.html
- 解析Vue-router相关干货及工作原理
本文主要介绍了vue-router相关基础知识及单页面应用的工作原理,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. 单页面工作原理是通过浏览器U ...
- FastDFS 分布式文件系统详解
什么是文件系统 文件系统是操作系统用于在磁盘或分区上组织文件的方法和数据结构.磁盘空间是什么样的我们并不清楚,但文件系统可以给我们呈现一个非常清晰的表象,我们可以创建.删除.修改和复制这些文件,而实现 ...
- OpenMP变量作用域【private】【shared】
(1) privateprivate子句将一个或多个变量声明为线程的私有变量.每个线程都有它自己的变量私有副本,其他线程无法访问.即使在并行区域外有同名的共享变量,共享变量在并行区域内不起任何作用,并 ...