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

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

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

  1. 对服务请求的来源有做审计的需求,如异地登陆告警。
  2. 针对安全攻击或安全事件溯源需求,如 APT 攻击、DDoS 攻击等。
  3. 业务场景数据分析需求,如业务请求区域统计。
  4. 其他需要获取客户端地址的需求。

在 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, LoadBalancerNodePort 类型服务流量可能会被转发到其他节点的 Pods; Local 表示保留客户端源 IP 并避免 LoadBalancerNodePort 类型的服务流量转发到其他节点的 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-ForX-Real-IP 字段的值来获取客户端真实源 IP, TKE 中有两种场景使用方式,原理介绍如下:

在场景一中,腾讯云负载均衡器(CLB 七层) 默认会将客户端真实源IP放到 HTTP Header 的 X-Forwarded-ForX-Real-IP 字段,当服务流量在经过 Service 四层转发后会保留上述字段,后端通过WEB服务器代理配置或应用代码方式获取到客户端真实源IP,详情参考请文档 负载均衡如何获取客户端真实 IP - 最佳实践 - 文档中心 - 腾讯云

在场景二中, Nginx Ingress 服务部署需要 Nginx Ingress 能直接感知客户端真实源 IP,可以采用保留客户端源IP的配置方式(详情参考 kubernets设置外部负载均衡器说明 ),或通过 CLB 直通 Pod 的方式(详情参考 TKE场景下腾讯云CLB直通Pod使用场景介绍),当 Nginx Ingress 在转发请求时会通过 X-Forwarded-ForX-Real-IP 字段来记录客户端源 IP,后端可以通过此字段获得客户端真实源 IP。

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

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

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

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

待配置生效后,在后端通过获取 HTTP Header 中的 X-Forwarded-ForX-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-ForX-Real-IP 字段值得到客户端真实源 IP,后端抓包测试结果示例如下:

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

优点:在七层(HTTP/HTTPS)流量转发场景下比较推荐,可通过WEB服务代理的配置或后端应用代码直接获取 Http Header 中的字段即可拿到客户端真实IP,非常简单高效。

缺点:仅适用于七层(HTTP/HTTPS)流量转发场景,不适用于四层转发场景,如果是四层转发场景,请使用后面介绍的其他方式。

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

TOA 内核模块原理和加载方式参考 全球应用加速 获取访问用户真实 IP - 操作指南 - 文档中心 - 腾讯云 文档。

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

缺点

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

总结

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

参考资料

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!

在容器服务中获取客户端真实源 IP的更多相关文章

  1. C# 服务端获取客户端 系统/浏览器/IP

    /// <summary> /// 获取客户端操作系统版本 /// </summary> /// <returns></returns> public ...

  2. 通过HttpservletRequest对象获取客户端的真实IP地址

    这篇文章主要介绍了Java中使用HttpRequest获取用户真实IP地址,使用本文方法可以避免Apache.Squid.nginx等反向代理软件导致的非真实IP地址,需要的朋友可以参考下 在JSP里 ...

  3. IE8下服务端获取客户端文件的路径为C:/fakePath问题的解决方案

    上一篇文章上提到,IE8下服务端获取客户端文件的路径时,会变成C:/fakePath问题,于是乎通过文件路径去获得文件大小就失败了. 上网搜了一下,主要原因是IE8因为安全考虑,在上传文件时屏蔽了真实 ...

  4. nodejs之获取客户端真实的ip地址+动态页面中引用静态路径下的文件及图片等内容

    1.nodejs获取客户端真实的IP地址: 在一般的管理网站中,尝尝会需要将用户的一些操作记录下来,并记住是哪个用户进行操作的,这时需要用户的ip地址,但是往往当这些应用部署在服务器上后,都使用了ng ...

  5. F5中源地址转换(AutoMap)模式下后端服务器获取客户端真正的IP地址

    F5中开启AutoMap,并传递X-Forwarded-For值 开启F5源地址转换"Auto Map" 方式一: 在http profile中开启X-Forwarded-For ...

  6. 负载均衡获得真实源IP的6种方法 【转】

    除了X-FORWARD-FOR,负载均衡中获得真实源IP的方法还有很多种, 本文抛砖引玉,主要介绍获得真实源IP的多种方法,而不是具体配置, 负载均衡获得真实IP的方法有很多种,将形成专题文章, 本文 ...

  7. 负载均衡获得真实源IP的6种方法

    除了X-FORWARD-FOR,负载均衡中获得真实源IP的方法还有很多种. 本文抛砖引玉,主要介绍获得真实源IP的多种方法,而不是具体配置. 负载均衡获得真实IP的方法有很多种,将形成专题文章. 本文 ...

  8. 通过Request获取客户端的真实IP

    我们在做项目的时候经常需要获取客户端的真实ip去进行判断,为此搜索了相关文章,以下这个讲解的比较明白,直接拿来 https://blog.csdn.net/yin_jw/article/details ...

  9. 获取客户端用户真实ip方法整理(jekyll迁移)

    layout: post title: 获取客户端用户真实ip方法整理 date: 2019-08-22 author: xiepl1997 tags: springboot 由请求获取客户端ip地址 ...

随机推荐

  1. Ubuntu 16.04 安装Python 3.6

    1.配置软件仓库,因为python 3.6 新版没有发布到ubuntu的正式仓库中,咱们通过第3方仓库来做.在命令行中输入: sudo add-apt-repository ppa:jonathonf ...

  2. CSS 简介,学习 CSS 必看

    CSS 表示的是层叠样式表,学习 CSS 之前我们必须要掌握 HTML 和 XHTML 概述 CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 ...

  3. ASP.NET Core 配置与获取

    目录 1,来自字典 2,来自配置文件 3,层次结构 4,映射 ASP.NET Core 中,可以使用 ConfigurationBuilder 对象来构建. 主要分为三部:配置数据源 -> Co ...

  4. 在windows下使用pip安装python包遇到缺失stdint.h文件的错误

    今天在windows上使用pip安装一个python包python-lzf时遇到如下的错误: fatal error C1083: Cannot open include file: 'stdint. ...

  5. python中库引用与import

    在蟒蛇绘制函数中,多有turtle.   ,称它为<a>.<b>的编码风格 库引用 扩充python程序功能的方式 使用import保留字完成,采用<a>.< ...

  6. P4742 【[Wind Festival]Running In The Sky】

    相信来做这道题的人肯定都学过\(Tarjan\)缩点吧,如果没有建议先去做P3387 [模板]缩点,如果你忘了,建议也去看看 满足上面要求后,你会惊奇发现,这两道题基本一样,唯一的差别就是这道题需要记 ...

  7. hystrix文档翻译之开始使用

    获取包 使用maven获取包. <dependency> <groupId>com.netflix.hystrix</groupId> <artifactId ...

  8. 永远不要在代码中使用“User”这个单词

    ​ 当你意识到你在项目开始时做的轻量.简单的设想竟然完全错了时,你已经用了六个月的时间投入到这个项目上.现在你需要解决这些问题,才能让这个系统继续运行下去,你发现你用在这个项目上的精力远远超出了你的预 ...

  9. 趣图:大佬如何解决bug的

    Bug 变 Feature, 这招简直太帅了!   扩展阅读 趣图:我说自己菜 vs 大佬说自己菜 趣图:公司实习生找 Bug 趣图:国内一些大平台的推荐算法 趣图:开发和测试是如何对待代码的 趣图: ...

  10. Java多线程--创建和使用线程池

    使用线程池的目的 线程是稀缺资源,不能频繁的创建 解耦作用:线程的创建与执行完全分开,方便维护 将其放入一个池子中,可以给其他任务进行复用 优点 降低资源消耗,通过重复利用已创建的线程来降低线程创建和 ...