共計 5858 個字符,預計需要花費 15 分鐘才能閱讀完成。
今天就跟大家聊聊有關 TKE 基于彈性網卡直連 Pod 的網絡負載均衡是怎樣的,可能很多人都不太了解,為了讓大家更加了解,丸趣 TV 小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
前言
Kubernetes 在集群接入層設計并提供了兩種原生資源 Service 和 Ingress,分別負責四層和七層的網絡接入層配置。
傳統的做法是創建 Ingress 或 LoadBalancer 類型的 Service 來綁定騰訊云的負載均衡將服務對外暴露。這種做法將用戶流量負載到用戶節點的 NodePort 上,通過 KubeProxy 組件轉發到容器網絡中,但這種方案在業務的性能和能力支持會有所局限。
為了解決這個問題,TKE 容器團隊為在騰訊云上使用獨立或托管集群的用戶提供了一種新的網絡模式,利用彈性網卡直連 Pod 的方案很大的增強了性能和業務能力的支持。
本文將會從傳統的模式的問題入手,比較新舊模式的區別,并在最后提供新直連模式的使用指引。
傳統模式面臨的問題與挑戰性能與特性
KubeProxy 在集群中會將用戶 NodePort 的流量通過 NAT 的方式轉發到集群網絡中。這個 NAT 轉發帶來了以下一些問題。
NAT 轉發導致請求在性能上有一定的損失。
進行 NAT 操作本身會帶來性能上的損失。
NAT 轉發的目的地址可能會使得流量在容器網絡內跨節點轉發。
NAT 轉發導致請求的來源 IP 被修改了,客戶端無法獲取來源 IP。
當負載均衡的流量集中到幾個 NodePort 時。過于集中的流量會導致 NodePort 的 SNAT 轉發過多,使得源端口耗盡流量異常。還可能導致 conntrack 插入沖突導致丟包,影響性能。
KubeProxy 的轉發具有隨機性,無法支持會話保持。
KubeProxy 的每個 NodePort 其實也起到獨立的負載均衡作用,由于負載均衡無法收斂到一個地方,所以難以達到全局的負載均衡。
為了解決以上問題,我們以前給用戶提供的技術建議主要是通過 Local 轉發的方式,避免 KubeProxyNAT 轉發帶來的問題。但是因為轉發的隨機性,一個節點上部署多個副本時會話保持依舊無法支持。而且 Local 轉發在滾動更新時,容易出現服務的閃斷,對業務的滾動更新策略以及優雅停機提出了更高的要求。我們有理由去尋找更好的方案解決這個問題。
業務可用性
通過 NodePort 接入服務時,NodePort 的設計存在極大的容錯性。負載均衡會綁定集群所有節點的 NodePort 作為后端。集群任意一個節點的訪問服務時,流量將隨機分配到集群的工作負載中。這就意味著部分 NodePort 的不可用,或者是 Pod 的不可用都不會影響服務的流量接入。
和 Local 訪問一樣,直接將負載均衡后端連接到用戶 Pod 的情況下,當業務在滾動更新時,如果負載均衡不能夠及時綁定上新的 Pod,業務的快速滾動可能導致業務入口的負載均衡后端數量嚴重不足甚至被清空。因此,業務滾動更新的時候,接入層的負載均衡的狀態良好,方能保證滾動更新的安全平穩。
負載均衡的控制面性能
負載均衡的控制面接口。包括創建刪除修改四層、七層監聽器,創建刪除七層規則,綁定各個監聽器或者規則的后端。這些接口大部分是異步接口,需要輪詢請求結果,接口的調用時間相對較長。當用戶集群規模較大時,大量的接入層資源同步會導致組件存在很大的時延上的壓力。
新舊模式對比性能對比
Pod 直連模式已經在騰訊 TKE 上線,是對負載均衡的控制面優化。針對整個同步流程,重點優化了批量調用和后端實例查詢兩個遠程調用比較頻繁的地方。** 優化完成后,Ingress 典型場景下的控制面性能較優化前版本有了 95%-97% 左右的性能提升。** 目前同步的耗時主要集中在異步接口的等待上。
后端節點突增 (應對集群擴容的場景)
七層規則突增(應對業務第一次上線部署到集群的場景)
除去控制面性能優化這樣的硬核優化,負載均衡能夠直接訪問容器網絡的 Pod 就是組件業務能力最重要的組成部分了,其不僅避免了 NAT 轉發性能上的損失,同時避免了 NAT 轉發帶來的各種對集群內業務功能影響。但是在啟動該項目時這一塊還沒有特別好的訪問容器網絡的支持。所以一期考慮集群 CNI 網絡模式下 Pod 有彈性網卡入口,這個入口可以直接接入到負載均衡以達到直接訪問的目的。負載均衡直接后端訪問到容器網絡,目前已經有通過云聯網解決的方案,后續也會繼續跟進這種更貼近集群網絡的直連方案。
接下來能夠直接訪問了,如何保證滾動更新時的可用性保證呢?我們找到了官方提供的一個特性 ReadinessGate。這個特性在 1.12 正式提供出來,主要是用來控制 Pod 的狀態。默認情況下,Pod 有以下 Condition:PodScheduled、Initialized、ContainersReady,當這幾個狀態都 Ready 的時候,Pod Ready 的 Condition 就通過了。但是在云原生的場景下面,Pod 的狀態是非常有可能需要參考其他狀態的。ReadinessGate 提供了這樣一個機制,允許為 Pod 的狀態判斷添加一個柵欄,由第三方來進行判斷與控制。這樣 Pod 的狀態就和第三方關聯起來了。
負載均衡流量對比傳統 NodePort 模式
請求細節過程
請求流量進入負載均衡
請求被負載均衡轉發到某一個節點的 NodePort
KubeProxy 將來自 NodePort 的流量進行 NAT 轉發,目的地址是隨機的一個 Pod。
請求進入容器網絡,并根據 Pod 地址轉發到對應節點。
請求來到 Pod 所屬節點,轉發到 Pod。
新的 Pod 直連模式
請求細節過程
請求流量進入負載均衡
請求被負載均衡轉發到某一個 Pod 的 ENI 彈性網卡
直連與 Local 訪問的區別
看起來這兩種訪問方式的效果是一樣的,但是在細節上還是存在一些差別。
從性能上區別不大,開啟 Local 訪問時,流量不會進行 NAT 操作也不會進行跨節點轉發,所以僅僅多了一個到容器網絡的路由。
沒有進行 NAT 操作,來源 IP 就能夠正確獲取了。會話保持功能可能會有以下問題,當一個節點上存在多個 Pod 時,流量到哪一個 Pod 是隨機的,這個機制可能會使話保持出現問題。
ReadinessGate 的引入
前面有兩個細節,可以在這里得到解答。
為什么要求集群版本高于 1.12
為什么 kubectl get pod -o wide 的結果中 READINESS GATES 列有內容。
這里涉及到一個滾動更新相關的問題 當用戶開始為應用做滾動更新的時候,Kubernetes 會根據更新策略進行滾動更新。但是其判斷一批 Pod 啟動的標識僅包括 Pod 自身的狀態,并不會考慮這個 Pod 在負載均衡上是否已經進行配置健康檢查是否通過。有的時候當接入層組件高負載,不能及時對這些 Pod 進行及時調度的話,這些滾動更新成功的 Pod 可能并沒有正在對外提供服務,從而導致服務的中斷。為了將滾動更新和負載均衡的后端狀態關聯起來,TKE 接入層組件引入了 Kubernetes 1.12 中引入的新特性 ReadinessGate。TKE 接入層組件只有在確認后端綁定成功并且健康檢查通過時,通過配置 ReadinessGate 的狀態來使 Pod 達到 Ready 的狀態,從而推動整個工作負載的滾動更新。
在集群中使用 ReadinessGate 的細節 Kubernetes 集群提供的是一個服務注冊的機制,你只需要將你的服務以 MutatingWebhookConfigurations 資源的形式注冊到集群中就可以了。集群會在 Pod 創建的時候按照你的配置的回調路徑通知你,這個時候就可以對 Pod 做一些創建前的操作,在這個 Case 里面就是給 Pod 加上 ReadinessGate。唯一需要注意的就是這個回調過程必須是 Https 的,所以標配需要在 MutatingWebhookConfigurations 中配置簽發請求的 CA,并在服務端配置該 CA 簽發的證書。
ReadinessGate 機制的災難恢復 用戶集群中的服務注冊或是證書有可能被用戶刪除,雖然這些系統組件資源不應該被用戶修改或破壞。但在用戶對集群的探索或是誤操作下,這類問題會不可避免的出現。所以接入層組件在啟動時會檢查以上資源的完整性,在完整性受到破壞時會重建以上資源,加強系統的魯棒性。
QPS 和網絡時延對比
直連與 NodePort 是服務應用的接入層方案,其實最終參與工作的還是用戶部署的工作負載,用戶工作負載的能力直接決定了業務的 QPS 等指標。所以我們針對這兩種接入層方案,在工作負載壓力較低的情況下,重點針對網絡鏈路的時延進行了一些對比測試。直連在接入層的網絡鏈路上能夠優化 10% 左右的時間。同時測試中的監控也發現,直連模式減少了大量 VPC 網絡內的流量。測試場景,從 20 節點到 80 節點,逐步增大集群規模,通過 wrk 工具對集群進行網絡延時的測試。針對 QPS 和網絡時延,下圖給出了直連場景與 NodePort 的對比測試。
KubeProxy 的一些設計思考
KubeProxy 的缺點也在前文中提到的一樣明顯。但是基于云上負載均衡、VPC 網絡的各種特性,我們能給出各種其他更加本地化的接入層方案。但這并不意味著 KubeProxy 的設計不好或是作用不大。其對集群接入層的設計極具普適性、容錯性,基本適用于所有業務場景下的集群,作為一個官方提供的組件這個設計是非常合適的。
新模式使用指引前置要求
Kubernetes 集群版本需要高于 1.12。
集群網絡模式必須開啟 VPC-CNI 彈性網卡模式。
直連模式 Service 使用的工作負載需使用 VPC-CNI 彈性網卡模式。
控制臺操作指引
登錄 容器服務控制臺。
參考控制臺 創建 Service 步驟,進入“新建 Service”頁面,根據實際需求設置 Service 參數。
其中,部分關鍵參數信息需進行如下設置,如下圖所示:
服務訪問方式:選擇為【提供公網訪問】或【VPC 內網訪問】。
網絡模式:勾選【采用負載均衡直連 Pod 模式】。
Workload 綁定:選擇【引用 Worklocad】,并在彈出窗口中選擇 VPC-CNI 模式的后端工作負載。
單擊【創建服務】,完成創建。
Kubectl 操作指引
Workload 示例:nginx-deployment-eni.yaml
注意 spec.template.metadata.annotations 中聲明了 tke.cloud.tencent.com/networks: tke-route-eni,在工作負載使用 VPC-CNI 彈性網卡模式。
apiVersion: apps/v1 kind: Deployment metadata: labels: app: nginx name: nginx-deployment-eni spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: annotations: tke.cloud.tencent.com/networks: tke-route-eni labels: app: nginx spec: containers: – image: nginx:1.7.9 name: nginx ports: – containerPort: 80 protocol: TCP
- Service 示例:nginx-service-eni.yaml
注意:`metadata.annotations` 中聲明了 `service.cloud.tencent.com/direct-access: true `,Service 在同步負載均衡時將采用直連的方式配置訪問后端。 ```yaml
apiVersion: v1
kind: Service
metadata:
annotations:
service.cloud.tencent.com/direct-access: true
labels:
app: nginx
name: nginx-service-eni
spec:
externalTrafficPolicy: Cluster
ports:
- name: 80-80-no
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: None
type: LoadBalancer
```
- 部署以上內容到集群
注意:在你的環境你首先需要連接到集群(沒有集群的需要先創建集群),可以參考文章尾部的幫助文檔配置 kubectl 連接集群。 ```shell
? ~ kubectl apply -f nginx-deployment-eni.yaml
deployment.apps/nginx-deployment-eni created
? ~ kubectl apply -f nginx-service-eni.yaml
service/nginx-service-eni configured
? ~ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-eni-bb7544db8-6ljkm 1/1 Running 0 24s 172.17.160.191 172.17.0.3 none 1/1
nginx-deployment-eni-bb7544db8-xqqtv 1/1 Running 0 24s 172.17.160.190 172.17.0.46 none 1/1
nginx-deployment-eni-bb7544db8-zk2cx 1/1 Running 0 24s 172.17.160.189 172.17.0.9 none 1/1
? ~ kubectl get service -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.187.252.1 none 443/TCP 6d4h none
nginx-service-eni LoadBalancer 10.187.254.62 150.158.221.31 80:32693/TCP 6d1h app=nginx
```
看完上述內容,你們對 TKE 基于彈性網卡直連 Pod 的網絡負載均衡是怎樣的有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注丸趣 TV 行業資訊頻道,感謝大家的支持。