使用容器原生負載平衡

本頁面說明如何在 Google Kubernetes Engine 中使用容器原生負載平衡。

總覽

「容器原生負載平衡」可讓 HTTP(S) 負載平衡器直接定位 Pod,並將其流量平均分配至 Pod。

容器原生負載平衡運用的資料模型稱為網路端點群組 (NEG),NEG 是網路端點的集合,由 IP 和通訊埠組合表示。

優勢

容器原生負載平衡具備下列優勢:

Pod 是負載平衡的一等公民
kube-proxy 會設定節點的 iptables 規則,將流量分配到多個 Pod。要是沒有容器原生負載平衡,負載平衡器流量會前往節點執行個體群組,並且透過 iptables 規則轉送到多個 Pod,而這些 Pod 不一定位於同一節點內。要是擁有容器原生負載平衡,負載平衡器流量會直接分配到多個 Pod,而這些 Pod 應接收流量,並且消除額外的網路躍點。此外,容器原生負載平衡直接以 Pod 為目標,因此健康狀態檢查可獲得改善。

此圖比較預設行為 (左) 和容器原生負載平衡器行為。
網路效能獲得改善
因為容器原生負載平衡器可直接與 Pod 交流,而且連線的網路躍點較少,所以延遲時間和總處理量都獲得改善。
瀏覽權限提升
使用容器原生負載平衡時,您有權限可瀏覽用戶端到 HTTP 負載平衡器的來回時間 (RTT),包括 Stackdriver UI 支援。如此一來,NEG 層級服務的疑難排解就會變得更加容易。
HTTP(S) 負載平衡器功能的支援
容器原生負載平衡提供 Google Kubernetes Engine 中原生的支援,其中包含數種 HTTP 負載平衡功能,例如與 GCP 服務 (Cloud ArmorCloud CDNCloud Identity-Aware Proxy) 整合的功能。此外,還具備負載平衡演算法,可精確分配流量。

需求

Google Kubernetes Engine 上的容器原生負載平衡器必須滿足下列需求:

Google Kubernetes Engine 1.10 版
執行 Google Kubernetes Engine 1.10 以上版本的 Google Kubernetes Engine 叢集中,提供容器原生負載平衡器。
虛擬私人雲端原生
如要使用容器原生負載平衡,叢集必須是虛擬私人雲端原生。詳情請參閱使用別名 IP 建立虛擬私人雲端原生叢集

限制

容器原生負載平衡器無法搭配舊版網路使用。

限制

容器原生負載平衡器不支援內部負載平衡器和網路負載平衡器。

定價

您在本指南中建立的 Ingress 所佈建的 HTTP(S) 負載平衡器,系統會向您收取費用。負載平衡器定價資訊,請參閱 Compute Engine 定價頁面的負載平衡和轉送規則

使用容器原生負載平衡

下列各節會逐步引導您在 Google Kubernetes Engine 上設定容器原生負載平衡。

建立虛擬私人雲端原生叢集

如要使用容器原生負載平衡,使用別名 IP 建立叢集就必須啟用。

例如,下列指令建立一個名為 neg-demo-cluster 的叢集,而 us-central1-a 區域含有一個自動佈建子網路:

gcloud container clusters create neg-demo-cluster \
    --enable-ip-alias \
    --create-subnetwork="" \
    --network=default \
    --zone=us-central1-a

建立部署

接著,將工作負載部署到叢集。

下列的部署範例 neg-demo-app 會執行容器化 HTTP 伺服器的單一執行個體:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: neg-demo-app # Label for the Deployment
  name: neg-demo-app # Name of Deployment
spec: # Deployment's specification
  minReadySeconds: 60 # Number of seconds to wait after a Pod is created and its status is Ready
  selector:
    matchLabels:
      run: neg-demo-app
  template: # Pod template
    metadata:
      labels:
        run: neg-demo-app # Labels Pods from this Deployment
    spec: # Pod specification; each Pod created by this Deployment has this specification
      containers:
      - image: k8s.gcr.io/serve_hostname:v1.4 # Application to run in Deployment's Pods
        name: hostname # Container name
      terminationGracePeriodSeconds: 60 # Number of seconds to wait for connections to terminate before shutting down Pods

在此部署中,各容器都會執行一個 HTTP 伺服器。HTTP 伺服器會傳回應用程式伺服器的主機名稱 (亦即伺服器執行所在的 Pod 名稱) 做為回應。

將此份資訊清單儲存為 neg-demo-app.yaml,然後執行下列指令來建立部署:

kubectl apply -f neg-demo-app.yaml

為容器原生負載平衡器建立 Service

建立部署後,必須將部署的多個 Pod 組成一個 Service

下列的 Service 範例 neg-demo-svc 會以前一節建立的部署範例為目標:

apiVersion: v1
kind: Service
metadata:
  name: neg-demo-svc # Name of Service
  annotations:
    cloud.google.com/neg: '{"ingress": true}' # Creates an NEG after an Ingress is created
spec: # Service's specification
  type: NodePort
  selector:
    run: neg-demo-app # Selects Pods labelled run: neg-demo-app
  ports:
  - port: 80 # Service's port
    protocol: TCP
    targetPort: 9376

Service 的註解 cloud.google.com/neg: '{"ingress": true}' 會啟用容器原生負載平衡。然而,要等到您為 Service 建立 Ingress 後,才會建立負載平衡器。

將此份資訊清單儲存為 neg-demo-svc.yaml,然後執行下列指令來建立 Service:

kubectl apply -f neg-demo-svc.yaml

為 Service 建立 Ingress

下列的 Ingress 範例 neg-demo-ing 會以您建立的 Service 為目標:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: neg-demo-ing
spec:
  backend:
    serviceName: neg-demo-svc # Name of the Service targeted by the Ingress
    servicePort: 80 # Should match the port used by the Service

將此份資訊清單儲存為 neg-demo-ing.yaml,然後執行下列指令來建立 Ingress:

kubectl apply -f neg-demo-ing.yaml

建立 Ingress 後,HTTP 負載平衡器隨即會在專案裡建立,NEG 會在叢集執行所在的每個區域裡建立。NEG 裡的端點和 Service 端點會保持同步。

驗證 Ingress

在部署工作負載、將工作負載的多個 Pod 組成一個 Service,並為 Service 建立 Ingress 之後,應該要確認 Ingress 已成功佈建容器原生負載平衡器。

如要擷取 Ingress 的狀態,請執行下列指令:

kubectl describe ingress neg-demo-ing

在指令輸出中,找出 ADDCREATE 事件:

Events:
Type     Reason   Age                From                     Message
----     ------   ----               ----                     -------
Normal   ADD      16m                loadbalancer-controller  default/neg-demo-ing
Normal   Service  4s                 loadbalancer-controller  default backend set to neg-demo-svc:32524
Normal   CREATE   2s                 loadbalancer-controller  ip: 192.0.2.0

測試負載平衡器功能

下列各節說明如何測試容器原生負載平衡器的功能。

造訪 Ingress IP 位址

請等候數分鐘,以等待 HTTP 負載平衡器完成設定。

您可以造訪 Ingress 的 IP 位址,確認容器原生負載平衡器功能運作正常。

如要取得 Ingress IP 位址,請執行下列指令:

kubectl get ingress neg-demo-ing

在指令列輸出中,Ingress 的 IP 位址會顯示於 ADDRESS 欄。使用網路瀏覽器造訪 IP 位址。

檢查後端服務健康狀態

您也可以取得負載平衡器「後端服務」的健康狀態。

首先,取得專案裡執行的後端服務清單:

gcloud beta compute backend-services list

複製含 Service 名稱的後端名稱,例如 neg-demo-svc。然後,取得後端服務的健康狀態:

gcloud compute backend-services get-health [BACKEND_SERVICE_NAME] --global

驗證 Ingress 功能

要如預期般測試負載平衡器功能,還有另外一種方法:調度部署範例的資源,將測試要求傳送到 Ingress,然後驗證回應的備用資源數量正確無誤。

下列指令會將一個執行個體的 neg-demo-app 部署資源擴充到兩個執行個體:

kubectl scale deployment neg-demo-app --replicas 2

請稍候幾分鐘,才會完成發佈。如要確認發佈已完成,請執行下列指令:

kubectl get deployment neg-demo-app

在指令輸出中,確認有兩個可用的備用資源:

NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
neg-demo-app   2         2         2            2           26m

然後,執行下列指令來計算負載平衡器傳出的不重複回應之數量:

for i in `seq 1 100`; do \
  curl --connect-timeout 1 -s [IP_ADDRESS] && echo; \
done  | sort | uniq -c

其中 [IP_ADDRESS] 是 Ingress 的 IP 位址。您可以從 kubectl describe ingress neg-demo-ing 取得 Ingress 的 IP 位址。

在指令輸出中,發現不重複回應的數量等於備用資源數量,這就表示所有後端 Pod 都在處理流量:

44 neg-demo-app-7f7dfd7bc6-dcn95
56 neg-demo-app-7f7dfd7bc6-jrmzf

清除

完成本頁面的工作之後,為避免您的帳戶中產生不必要的費用,請按照下列步驟移除資源:

刪除叢集

gcloud

gcloud container clusters delete neg-demo-cluster

主控台

  1. 造訪 GCP 主控台的 Google Kubernetes Engine 選單。

    造訪 Google Kubernetes Engine 選單

  2. 選取 [neg-demo-cluster]

  3. 按一下 [Delete] (刪除)

疑難排解

下列各節說明如何解決容器原生負載平衡相關的常見問題。

無法使用別名 IP 建立叢集

問題
嘗試使用別名 IP 建立叢集時,可能會碰到下列錯誤:
ResponseError: code=400, message=IP aliases cannot be used with a legacy network.
可能原因
嘗試透過使用舊版網路的別名 IP 來建立叢集時,可能會發生上列錯誤。
解決方法
請勿在啟用舊版網路的情況下使用別名 IP 建立叢集。別名 IP 使用詳情請參閱使用別名 IP 建立虛擬私人雲端原生叢集

流量未達端點

問題
502 錯誤或連線遭拒。
可能原因
新端點只要會回應健康狀態檢查,則在附加到負載平衡器後通常就可存取。如果流量達不到端點,就可能會發生 502 錯誤或連線遭拒。
解決方法

如要解決此問題,請確認防火牆規則允許連入 TCP 流量到 130.211.0.0/2235.191.0.0/16 範圍內的端點。詳情請參閱 Cloud Load Balancing 說明文件中的新增健康狀態檢查

查看專案裡的後端服務。相關後端服務有對應的 Google Kubernetes Engine Service 名稱:

gcloud beta compute backend-services list

向後端服務擷取後端健康狀態:

gcloud beta compute backend-services get-health [BACKEND_SERVICE_NAME]

如果所有後端健康狀態不良,就表示防火牆、Ingress 或 Service 可能設定有誤。

如果有些後端健康狀態短時間不良,就表示網路程式設計延遲時間可能是原因所在。

如果有些後端沒有出現在後端服務清單,就表示程式設計延遲時間可能是原因所在。要確認這點,請執行下列指令,當中的 [NEG] 是後端服務名稱。(NEG 和後端服務共用同一個名稱):

gcloud beta compute network-endpoint-groups list-network-endpoints [NEG]

確認所有預期的端點是否都已在 NEG 中。

已知問題

Google Kubernetes Engine 上的容器原生負載平衡在測試版具有下列已知問題:

工作負載的發佈以及端點的傳播應保持一致

將工作負載部署到叢集時,或更新現有工作負載時,容器原生負載平衡器傳播新端點的所需時間可能會超過工作負載發佈完成的所需時間。您在本指南中部署的部署範例為了讓發佈與端點的傳播保持一致,會使用下列兩個欄位:terminationGracePeriodSecondsminReadySeconds

terminationGracePeriodSeconds 允許 Pod 安全關閉,方法是等待連線在 Pod 預定刪除後終止。

minReadySeconds 會在 Pod 建立後新增延遲期間。您要指定下列狀態的最短秒數:在新 Pod 中沒有任何容器當機 (即系統認定 Pod 可用) 的情況下,新 Pod 處於 Ready 狀態的最短秒數。

您應將工作負載的 minReadySeconds 值和 terminationGracePeriodSeconds 值設成 60 秒以上,這樣就能確保服務不會因工作負載的發佈而中斷。

terminationGracePeriodSeconds 在所有 Pod 規格中都可用;minReadySeconds 適用於部署和 DaemonSet。

如要進一步瞭解如何微調發佈,請參閱 RollingUpdateStrategy

垃圾收集未完成

Google Kubernetes Engine 每十分鐘就會對容器原生負載平衡器進行垃圾收集。如果叢集在負載平衡器完全移除前就遭到刪除,就必須手動刪除負載平衡器的 NEG。

請執行下列指令來查看專案裡的 NEG:

gcloud beta compute network-endpoint-groups list

在指令輸出中,找出相關的 NEG。

如要刪除 NEG,請執行下列指令,其中的 [NEG] 是 NEG 的名稱:

gcloud beta compute network-endpoint-groups delete [NEG]

將工作負載的資源調度降到零卻發生中斷情況

如果 NEG 裡的端點數量從零轉換成非零,或從非零轉換成零,則將工作負載的資源調度降到零,有可能會發生暫時中斷的情況。在中斷期間,負載平衡器可能會傳回非 200 回應,而後端可能會健康狀態不良。

相關資源

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Kubernetes Engine 說明文件