在Amazon EKS中获取客户端真实源IP的不同方式

b6bde140b202f9a9c1346117b636bbf0.gif

背景介绍

客户的一些业务场景需要明确服务的请求来源,需要准确获取和记录请求客户端的真实源IP。例如:安全团队需要对请求的来源进行审计及安全事件的处理,数据团队需要通过源IP做数据分析等。

结合客户在使用Amazon EKS过程中不同的工作场景,对各种获取源IP的实现方法进行总结,供大家参考。

具体场景

一、在“原生Kubernetes Service资源的配置选项”中保留客户端源IP。

Kubernetes依靠kube-proxy组件实现Service的通信与负载均衡。默认情况下Kube-proxy在做转发的时候会做一次SNAT(source network address translation),在这个过程中,由于使用了SNAT对源地址进行了转换,导致Pod中的服务拿不到真实的客户端IP地址信息。

如下图所示:

bf4fec71c0ad94725f901e627007851a.png

如果要启用保留客户IP功能,可以对Service对象中“externalTrafficPolicy”字段进行设置。

apiVersion: v1
kind: Service
metadata:
  name: Test-Service
spec:
  selector:
    app: Test-Service
  ports:
    - port: 80
      targetPort: 80
  externalTrafficPolicy: Local
  type: LoadBalancer #

ExternalTrafficPolic有两个选项值:Cluster(默认)和Local。Cluster模式下流量可以转发到其他节点上的Pod,Kube-proxy转发时会替换掉报文的源IP;Local模式下流量只发给本机的Pod,Kube-proxy转发时会保留源IP。

对比图如下:

ec48e69c5d3718a309dc4b1d2d7f37c6.png

虽然Local模式可以保留客户端源IP,但是在生产环境下,通常会有多个节点同时接收客户端的流量,如果使用Local模式,负载均衡可能就不是很好,因为一旦容器(pod)分布在多个节点上,它只转发给本机,不跨节点转发流量,这将会导致服务可访问性变低。

二、通过Amazon Application Load Balancer ingress->Service获取真实源IP。

Kubernetes Ingress是一种API对象,借助它可以管理对集群中运行的Kubernetes服务的外部(或)内部HTTP[s]访问,Amazon Elastic Load Balancing Application Load Balancer(Amazon ALB)是一个非常受欢迎的负载均衡服务,它可在应用程序层(第 7 层)跨一个区域的多个目标(例如Amazon EKS多个pod)调整传入流量的负载平衡。

192b437b6d360207ccb73abfb2485c8a.png

Amazon Application Load Balancer负载均衡器(七层)默认会将客户端真实源IP放至HTTP Header的X-Forwarded-For和X-Real-IP字段中。后端应用通过获取HTTP Header中的X-Forwarded-For或X-Real-IP字段值就可以得到客户端真实源IP。例如:只需要在配置/etc/nginx/nginx.conf配置文件LogFormat部分中,添加$http_x_forwarded_for,类似于以下内容:

http {
    ...
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    ...
}

左右滑动查看更多

三、通过Amazon NLB->Nginx Ingress-> Service访问获取真实IP。

Amazon ALB入口控制器非常优秀,但也有一些使用场景下更适合将Amazon NLB与Amazon NGINX入口控制器配合使用。Amazon NLB每秒能够处理数百万个请求,同时保持极低的延迟,因此非常适合TCP流量的负载均衡。Amazon NLB专为处理突增和波动流量模式而优化,同时每个可用区使用单个静态IP地址。Nginx Ingress可以自定义组件实现特定功能比如:限流,动静分离等。

具有TCP/SSL侦听器的四层负载均衡器Amazon Network Load Balancer,后端应用程序可以通过两种方式获取源IP。

4640a89b00bf7c7c8b3eba9930fe5831.png

(1) 通过启用Proxy Protocol v2来取得Client IP。

a6fececeb489343c3591b66f1e6d66c9.png

此方式需要在负载均衡器上启用代理协议版本2

  • https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#proxy-protocol

有关说明,请参阅启用代理协议

  • https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#enable-proxy-protocol

另外启用代理协议v2之前,请确保您的应用程序目标可以处理代理协议标头,否则您的应用程序可能会中断。

例如:Ningx需要更改server部分的listen行,以启用 proxy_protocol。确保更改http部分的log_format行,以设置proxy_protocol_addr:

http {
    ...
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$proxy_protocol_addr"';
    access_log  /var/log/nginx/access.log  main;
    ...
}
server {
        ...
        listen  80  default_server proxy_protocol;        
        ...
        }
...
}

左右滑动查看更多

(2)Amazon NLB现在已支持IP透传的模式,通过启用Client IP preservation,后端应用无需额外配置。也建议大家使用此种方式。

717e4c2b7fcb5a86f4e02fccc2f275e6.png

有关说明,请参阅客户端IP保留

  • https://docs.aws.amazon.com/zh_cn/elasticloadbalancing/latest/network/load-balancer-target-groups.html#target-group-attributes

注:在Amazon EKS环境下,Amazon NLB与Kubernetes Service和Ingress资源结合时,可以通过Amazon Load Balancer Controller自动创建Amazon NLB资源以及相应的Target Group。也可使用Amazon Load Balancer Controller中的新功能TargetGroupBinding,它允许客户在Amazon EKS集群之外自己创建和管理Amazon NLB和TargetGroup。通过TargetGroupBinding可以将Kubnernetes Service和指定的Target Group进行关联。

由于此内容不是本文的重点,本文不作过多介绍,详细内容请大家可以查看官方文档以及相关blog。

总结

Kubernetes原生的负载均衡机制以及相关集成的负载均衡组件Nginx、Amazon Network Load Balancer、Amazon Application Load Balancer等都使业务上获取客户源IP变的复杂,本文主要介绍了在Amazon EKS使用场景下服务端如何获取客户端真实源IP:

  • 通过Service资源的配置选项保留客户端源IP,只需修改Kubernetes Service资源配置即可,但可能会存在潜在的Pods(Endpoints)流量负载不均衡风险;

  • 在七层(HTTP/HTTPS)服务转发场景下,可以通过获取HTTP Header中X-Forwarded-For和X-Real-IP字段的值来获取客户端真实源IP;

  • 在四层(tcp/udp)服务转发场景下,除了可以通过启用Proxy Protocol v2来获取客户端真实源IP外,Amazon NLB现在也支持IP透传的模式,不需要后端应用做额外配置就可以获取客户端真实源IP。

参考材料:

  • https://kubernetes.io/docs/concepts/services-networking/ingress/

  • https://kubernetes.io/zh/docs/tasks/access-application-cluster/create-external-load-balancer/

  • https://docs.aws.amazon.com/zh_cn/elasticloadbalancing/latest/network/load-balancer-target-groups.html#client-ip-preservation

  • https://aws.amazon.com/cn/premiumsupport/knowledge-center/elb-capture-client-ip-addresses/

  • https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html

本篇作者

e04bd4981f34869843a69111c3c95459.png

梁战雷

亚马逊云科技解决方案架构师

具有超过13年的运维工作经验,在微服务,容器,Devops等云原生领域有丰富的项目落地实施经验,现在主要负责企业级客户的上云推广及支持工作。

12ea5819d86b3dea4d93c2ca58f1003b.png

崔志阳

首汽约车基础架构部运维工程师

主要负责ISSA层平台及云架构方面的设计与优化。在运维领域有多年的架构设计及运维经验,对Devops、服务网格、容器领域、云原生相关技术等有着深入的研究和热情。

1ee717dadf7b346729148e0b66c3ef6a.gif

46ba7ea30b24e52939fab0d56623f137.gif

听说,点完下面4个按钮

就不会碰到bug了!

b5cf158aebda5d75599f31c462c2cfce.gif

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值