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節點都配置上,讓它進行分發請求。  

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM