什么是 LB 直通 Pod ?
Kubernetes 官方提供了 NodePort 型別的 Service,即給所有節點開一個相同埠用于暴露這個 Service,大多云上 LoadBalancer 型別 Service 的傳統實作也都基于 NodePort,即 LB 后端綁各節點的 NodePort,LB 接收外界流量,轉發到其中一個節點的 NodePort 上,再通過 Kubernetes 內部的負載均衡,使用 iptables 或 ipvs 轉發到 Pod:

TKE 默認的 LoadBalancer 型別 Service 與默認的 Ingress 也都是這樣實作的,但目前也支持了 LB 直通 Pod 的方式,即 LB 后端直接綁 Pod IP+Port,不綁節點的 NodePort:

為什么需要 LB 直通 Pod ?
LB 直接綁 NodePort 來實作云上的 Ingress 或 LoadBalancer 型別 Service 是最簡單通用的方法,那為什么有了這種實作還不夠,還要搞個 LB 直通 Pod 的模式?
首先,我們分析下傳統 NodePort 實作方式存在的一些問題:
- 流量從 LB 轉發到 NodePort 之后還需要進行 SNAT,再轉發到 Pod,會帶來一些額外的性能損耗,
- 如果流量過于集中到某幾個 NodePort 時(比如使用 nodeSelector 部署網關到固定幾臺節點上),可能導致源埠耗盡,或者 conntrack 插入沖突,
- NodePort 本身也充當負載均衡器,LB 系結過多節點 NodePort 可能導致負載均衡狀態過于分散,導致全域負載不均,
如果使用 LB 直通 Pod 的方式,以上問題都將消失,并且還有一些其它好處:
- 由于沒有 SNAT,獲取源 IP 不再需要
externalTrafficPolicy: Local, - 實作會話保持更簡單,只需要讓 CLB 開啟會話保持即可,不需要設定 Service 的
sessionAffinity,
所以使用 LB 直通 Pod 的場景通常有:
- 在四層獲取客戶端真實源 IP,但又不希望通過使用
externalTrafficPolicy: Local的方式, - 希望進一步提升網路性能,
- 讓會話保持更容易,
- 解決全域連接調度的負載不均,
需要什么前提條件 ?
使用 LB 直通 Pod,需要滿足以下前提條件:
Kubernetes集群版本需要高于 1.12,因為 LB 直綁 Pod,檢查 Pod 是否 Ready,除了看 Pod 是否 Running、是否通過 readinessProbe 外, 還需要看 LB 對 Pod 的健康探測是否通過,這依賴于ReadinessGate特性,該特性在 Kubernetes 1.12 才開始支持,- 集群網路模式必須開啟
VPC-CNI彈性網卡模式,因為目前 LB 直通 Pod 的實作是基于彈性網卡的,普通的網路模式暫時不支持,這個在未來將會支持,
怎么用 ?
由于目前 LB 直通 Pod 依賴 VPC-CNI,需要保證 Pod 使用了彈性網卡:
-
如果集群創建時選擇的是 VPC-CNI 網路插件,那么創建的 Pod 默認就使用了彈性網卡,
-
如果集群創建時選擇的是 Global Router 網路插件,后來開啟了 VPC-CNI 支持,即兩種模式混用,創建的 Pod 默認不使用彈性網卡,需要使用 yaml 創建作業負載,為 Pod 指定
tke.cloud.tencent.com/networks: tke-route-eni這個 annotation 來宣告使用彈性網卡,并且為其中一個容器加上tke.cloud.tencent.com/eni-ip: "1"這樣的 requests 與 limits,示例:
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
name: nginx
resources:
requests:
tke.cloud.tencent.com/eni-ip: "1"
limits:
tke.cloud.tencent.com/eni-ip: "1"
當你用 LoadBalancer 的 Service 暴露服務時,需要宣告使用直連模式:
- 如果通過控制臺創建 Service,可以勾選
采用負載均衡直連Pod模式:

- 如果通過 yaml 創建 Service,需要為 Service 加上
service.cloud.tencent.com/direct-access: "true"的 annotation:
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
當使用 Ingress 暴露服務時,同樣也需要宣告使用直連模式:
- 如果通過控制臺創建 Ingress,可以勾選
采用負載均衡直連Pod模式:

- 如果通過 yaml 創建 Ingress,需要為 Ingress 加上
ingress.cloud.tencent.com/direct-access: "true"的 annotation:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
ingress.cloud.tencent.com/direct-access: "true"
kubernetes.io/ingress.class: qcloud
name: test-ingress
namespace: default
spec:
rules:
- http:
paths:
- backend:
serviceName: nginx
servicePort: 80
path: /
參考資料
- TKE 基于彈性網卡直連 Pod 的網路負載均衡: https://mp.weixin.qq.com/s/fJtlm5Qjm2BfzekC4RegCQ
- 集群開啟 VPC-CNI 模式網路: https://cloud.tencent.com/document/product/457/34993
- VPC-CNI 網路模式使用指引: https://cloud.tencent.com/document/product/457/48040
【騰訊云原生】云說新品、云研新術、云游新活、云賞資訊,掃碼關注同名公眾號,及時獲取更多干貨!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/121940.html
標籤:其他

