K8s Pod中应用如何获取客户端 IP

status
Published
type
Post
slug
get-ip-info-in-k8s-pod
date
Sep 4, 2021
tags
Java
K8s
Nginx
summary
在 Kubernetes (K8s) 的 Pod 中运行的应用,想要获取客户端的真实 IP 地址信息,可以通过检查 "X-Original-Forwarded-For" 请求头来获取。在 K8s 集群中,请求经过 Ingress Controller 处理后,会将真实的客户端 IP 地址添加到该请求头中。因此,应用需要通过提取该请求头来获取客户端 IP 信息。需要注意的是,在 Ingress 资源中配置 "nginx.ingress.kubernetes.io/proxy-real-ip-cidr" 注解来启用对该请求头的支持。通过这种方式,应用可以准确获取到客户端的 IP 地址信息。
近期项目中需要记录下用户操作时IP信息的功能,在现有的项目架构中,客户端的IP信息会携带在HTTP请求头中。因该服务是Java实现的,即我们需要在 HttpServletRequest 中去提取 IP 信息。
IP工具类代码如下:
以上代码中有多个请求头名称,下面依次介绍:
  • X-Forwarded-For:是一个扩展头,用于识别通过HTTP代理或负载均衡器传输的客户端IP地址。当请求经过多个代理时,每个代理服务器都会将自己的IP地址添加到该头部的末尾。
  • Proxy-Client-IP:是一种特定于代理服务器的请求头,它用于指示连接到代理的客户端的IP地址。
  • WL-Proxy-Client-IP:是WebLogic服务器特定的请求头,用于获取连接到WebLogic服务器的客户端的IP地址。
  • HTTP_CLIENT_IP:是一种特定于代理服务器的请求头,用于指示连接到代理的客户端的IP地址。
  • HTTP_X_FORWARDED_FOR:是一种常见的请求头,用于指示连接到代理服务器的客户端的IP地址。
这些请求头中的信息多依赖于各类负载均衡器,代理服务器等的配置,因此想要获取到还需对访问链路中涉及到的相关服务进行配置。
 
此工具类在应用直接部署在Linux服务器上时,可以正常获取到,但应用生产环境是部署在K8s集群中的,此时的获取到IP为链路中Nginx服务所在主机的IP,并非是客户端IP,也就是代表上面几个HTTP请求头中未包含客户端IP信息。
查看应用在Pod中获取到的请求头信息,可通过代码日志打印实现,此处我借助如下开源项目来快速查看。
K8s 部署配置如下:
测试发现客户端 IP 信息只存在于 X-Original-Forwarded-For 中。故调整上面代码中增加一行对此请求头信息的提取即可。
 
需求是解决了,那么为什么在 K8s 中时,客户端 IP 的信息就只在 X-Original-Forwarded-For 请求头中了呢?
下面是访问链路的简化示意图
K8s 部署下与直接部署的区别就是流量需要经过 K8s Ingress 的转发。Ingress Controller 是Kubernetes集群中用于管理入站网络流量的组件,它充当着入口点和流量路由器的角色。当请求到达Ingress控制器时,它会检查原始的请求头信息,并根据配置进行适当的处理和转发。通常情况下,X-Original-Forwarded-For 请求头是在 Ingress Controller 读取原有的请求头信息来设置的,因此请求最终到达应用时我们需要通过 X-Original-Forwarded-For 请求头来提取IP信息。
 

参考

更多相关信息
当使用Kubernetes集群和NGINX Ingress Controller 时,x-original-forwarded-for是一个HTTP请求标头,用于传递原始客户端IP地址。它被添加到传入请求的标头中,以便应用程序可以获取到真实的客户端IP地址,尤其在经过代理或负载均衡器之后。
使用NGINX Ingress控制器时,你可以通过在Ingress资源中配置nginx.ingress.kubernetes.io/proxy-real-ip-cidr注解来启用x-original-forwarded-for标头的支持。例如:
在上述示例中,nginx.ingress.kubernetes.io/proxy-real-ip-cidr设置为0.0.0.0/0,这将允许任何IP地址发送x-original-forwarded-for标头。可以根据需要设置特定的CIDR。
 
 

2020 - 2024 © HK