前言
在 EKS 上要建立 ELB 會採用 service type 指定 LoadBalancer。此時 AWS 的 In-Tree LoadBalacner Controller 或是 AWS Load Balancer Controller 其中之一會協助我們建立對應的 ELB 出來。本文紀錄這兩種 LB Controller 的差異以及不同類型 ELB 使用時機(以獲取 Client IP 為例)。
In-Tree LoadBalacner Controller - CLB
將 server type 指定成 LoadBalancer
此時 In-Tree LoadBalacner Controller 會 privosion 一個 CLB 出來
流量從外部要進入叢集的路徑為
CLB -> Node:NodePort -> Pod maybe in different node
因為透過節點上的 NodePort 進行跳轉,所以 Pod 如果要獲得 Clinet IP 會拿到 Node 中的 IP。而獲取不到真正的 Client IP
接著可以根據官方建議設定 .spec.externalTrafficPolicy
為 Local
(預設為 Cluster
)
這樣的設定可以避免流量進入到沒有含 Destination Pod 的 Node 上,多做一個 hop 的跳轉,也避免 IP 被洗成該 Node 的 IP
結果發現 Client IP 還是獲取不到,因為 CLB 在與後方的 instance 溝通時,是用該 subnet 介面的 IP 溝通,所以 Client IP 變成是 ELB 的 private IP(該 IP 可以從 ec2 的 network interfacae 找出來)
現在的路徑變成
CLB -> Node:NodePort (Pod also in the node)
開啟了 externalTrafficPolicy
需不需要擔心如果該節點上沒有 Pod,進而請求沒有辦法路由到正確的位置上
答案是不需要,因為 CLB 會對後方的 instance 做健康檢查,若後方 instance 沒有 Pod,那某該 instance 不健康,流量自然不會導入過去
1 | 優點:完全不需修改參數、不需安裝其他 controller |
In-Tree LoadBalacner Controller - NLB
需要在 annotations 加上
1 | annotations: |
並且我們將 externalTrafficPolicy
同樣設定成 Local
發現就可以正常獲取 Client IP 了,代表 NLB 在轉發時,不會將 Source IP 介面切換成內網介面,同時後端也不是 instance 是另外一層抽象(target group)
但試想一個一個情況,若我有 3 個 Pod (x, y, z),2 個 (x, y) 落在節點 A,1 個 (z) 落在節點 B
那麼流量進入 NLB 時會先進行 1/2 的機率選擇節點 (A, B),假設進入節點 A 又會有 1/2 的機率選擇 x, y 這兩個 Pod
那麼 Pod 被選中的機率變成
x: 1/2 * 1/2 = 1/4
y: 1/2 * 1/2 = 1/4
z: 1/2
可以發現流量並沒有真的平均轉發都後端的 Pod 上
但 In-Tree Controller 只能建立出這兩種 ELB(並且能修改的參數有限),剩下一種 ALB 必須安裝 AWS Load Balancer Controller
1 | 優點:不需安裝其他 controller、可以保留 Client IP |
AWS Load Balancer Controller - NLB
安裝 AWS Load Balancer Controller 後,在使用上必須指定 loadBalancerClass: service.k8s.aws/nlb
並且 AWS Load Balancer Controller 有提供 ip
與 instance
mode(使用 in-tree controller 建立出來的 mode 就是 instance mode)
該功能需要配合 AWS VPC CNI 使用
1 | annotations: |
此時會發現 NLB 後方的 target group 直接對應到 Pod IP,可以省去多一次跳轉,並且解決流量不平均的問題
但 Client IP 還是沒有保留,我們可以調整 NLB 參數
1 | annotations: |
將 NLB 提供的功能 preserve_client_ip 打開,即可完成配置,也不需要透過設定 externalTrafficPolicy
參數即可獲取 Client IP
1 | 優點:保留 Client IP、流量不會多一跳、流量平均 |
AWS Load Balancer Controller - ALB
使用 Ingress 資源建立出 ALB,但是無法設定 preserve_client_ip
如果去 management console 檢查對應 target group,會發現找不到 Preserve client IP addresses 但是多了 Load balancing algorithm 可以選擇
因為是 L7 支援,所以將 Client IP 放入 HTTP header 的 XFF 欄位即可
一樣有 instance
與 ip
mode 可以選擇
1 | 優點:保留 Client IP(放在 L7 的 HTTP header 中)、流量不會多一跳、流量平均 |