k8s容器获取客户端真实ip配置

思路:先说如何操作——再说原理

1、server 配置中加入externalTrafficPolicy:配置

spec:
  type: NodePort
  externalTrafficPolicy: Local
只能在服务启动pod节点 访问才有反应,其他节点直接丢弃请求

2、对于问题那就直接将pod指定到某个节点

deploy中加入
spec:
   nodeName: node1    #指定pod节点配置 
   containers:
      - name: pod-name

3、访问的时候就直接 通过nodeip:serveri-port 进行访问即可获取真实ip

下面分析原因:

对于Service, 如果指定类型为 NodePort, 那么这个端口会在集群的所有 Node 上打开,即使这个Node 上面没有这个pod
(很好理解,和守护进程集不一样,对于Deployment 来说,很少会在每个节点上都启动pod,所以必定有一些节点上没有这个pod)
引出一个问题,当某个节点上没有pod的时候,又去访问ta的这个NodePort,能访问到吗?
流程1
答案是可以的,官方文档
流程大概是这样的
          client
              ^
               
               v 
   node 1 <--- node 2
    | ^   SNAT
    | |   --->
    v |
 endpoint


Client sends packet to node2:nodePort
客户端发送 tcp 包 到 node2:nodePort
node2 replaces the source IP address (SNAT) in the packet with its own IP address
node2 把客户端源ip地址替换为node2 的ip地址
node2 replaces the destination IP on the packet with the pod IP
node2 把请求的目的地ip替换为 pod ip
packet is routed to node 1, and then to the endpoint
tcp包被路由到 node1, 接着达到 endpoint(如service)
the pod’s reply is routed back to node2
pod的响应被路由到 node2
the pod’s reply is sent back to the client
node2把pod的响应发送给客户端
可以发现,在这个过程中,客户端的源IP地址丢失了(看第二步)
流程2

为了解决这个问题, k8s 提供了一个功能,通过设置 externalTrafficPolicy=Local 可以保留源IP地址
设置完这个参数之后,流程如下
        client
       ^ /   
      / /     
     / v       X
   node 1     node 2
    ^ |
    | |
    | v
 endpoint

client sends packet to node2:nodePort, which doesn’t have any endpoints
客户端发送tcp包到 node2:nodePort, 但是 node2 并没有 这个pod
packet is dropped
tcp包被丢弃
client sends packet to node1:nodePort, which does have endpoints
客户端发送数据包到 node1:nodePort, node1有pod
node1 routes packet to endpoint with the correct source IP
node1 把包路由到对应的pod,那么pod 就可以拿到正确的客户端源IP地址

4、如果有多个pod可以使用lb进行负载,lb有服务的活性检测,把所有node节点都配置上,让它进行分发请求。  

  

  

 

原文地址:https://www.cnblogs.com/wukc/p/14313444.html