建立後端服務型外部負載平衡器


本頁面說明如何部署外部 LoadBalancer 服務,以建構後端服務型外部直通式網路負載平衡器。閱讀本頁面之前,請先熟悉下列概念:

如要進一步瞭解外部直通式網路負載平衡器,請參閱「後端服務型外部直通式網路負載平衡器」。

事前準備

開始之前,請確認你已完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update,取得最新版本。

需求條件

  • 您必須在叢集中啟用 HttpLoadBalancing 外掛程式。這項外掛程式預設為啟用。叢集可藉此管理使用後端服務的負載平衡器。

  • 如要建立使用後端服務型外部直通式網路負載平衡器的外部 LoadBalancer 服務,GKE 叢集必須使用 1.25.5 以上版本。

  • 如要建立使用加權負載平衡的外部 LoadBalancer 服務,GKE 叢集必須使用 1.31.0-gke.1506000 以上版本。

  • 如要建立使用 GCE_VM_IP 網路端點群組 (NEG) 後端的外部 LoadBalancer 服務,GKE 叢集必須使用 1.32.2-gke.1652000 以上版本。

選擇叢集

您可以建立新叢集,或選擇符合條件的現有叢集。

建立新叢集

Autopilot

如要建立新的 Autopilot 叢集,請按照下列步驟操作:

gcloud container clusters create-auto CLUSTER_NAME \
    --release-channel=RELEASE_CHANNEL \
    --cluster-version=VERSION \
    --location=COMPUTE_LOCATION

更改下列內容:

  • CLUSTER_NAME:新叢集的名稱。
  • RELEASE_CHANNEL:叢集的 GKE 發布版本名稱。
  • VERSION:叢集的 GKE 版本。
  • COMPUTE_LOCATION:叢集的 Compute Engine 地區

如要停用 LoadBalancer Service 的虛擬私有雲防火牆規則自動建立功能,請加入 --disable-l4-lb-firewall-reconciliation 旗標。詳情請參閱「GKE LoadBalancer 服務的使用者管理防火牆規則」。

標準

如要建立新的標準叢集,請按照下列步驟操作:

gcloud container clusters create CLUSTER_NAME \
    --release-channel=RELEASE_CHANNEL \
    --cluster-version=VERSION \
    --location=COMPUTE_LOCATION

更改下列內容:

  • CLUSTER_NAME:新叢集的名稱。
  • RELEASE_CHANNEL:叢集的 GKE 發布版本名稱。
  • VERSION:叢集的 GKE 版本。
  • COMPUTE_LOCATION:叢集的 Compute Engine 地區

如要停用 LoadBalancer Service 的虛擬私有雲防火牆規則自動建立功能,請加入 --disable-l4-lb-firewall-reconciliation 旗標。詳情請參閱「GKE LoadBalancer 服務的使用者管理防火牆規則」。

升級現有叢集

使用 gcloud CLI 更新現有叢集:

gcloud container clusters upgrade CLUSTER_NAME \
    --cluster-version=VERSION \
    --master \
    --location=COMPUTE_LOCATION

更改下列內容:

如要停用 LoadBalancer Service 的虛擬私有雲防火牆規則自動建立功能,請加入 --disable-l4-lb-firewall-reconciliation 旗標。詳情請參閱「GKE LoadBalancer 服務的使用者管理防火牆規則」。

部署範例工作負載

部署下列範例工作負載,為外部 LoadBalancer 服務提供服務 Pod。

  1. 將下列範例 Deployment 儲存為 store-deployment.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: store
    spec:
      replicas: 20
      selector:
        matchLabels:
          app: store
      template:
        metadata:
          labels:
            app: store
        spec:
          containers:
          - image: gcr.io/google_containers/echoserver:1.10
            imagePullPolicy: Always
            name: echoserver
            ports:
              - name: http
                containerPort: 8080
            readinessProbe:
              httpGet:
                path: /healthz
                port: 8080
                scheme: HTTP
    
  2. 將資訊清單套用至叢集:

    kubectl apply -f store-deployment.yaml
    
  3. 確認部署作業有 20 個服務 Pod:

    kubectl get pods
    

    輸出結果會與下列內容相似:

    NAME                     READY   STATUS    RESTARTS   AGE
    store-cdb9bb4d6-s25vw      1/1     Running   0          10s
    store-cdb9bb4d6-vck6s      1/1     Running   0          10s
    ....
    

建立外部 LoadBalancer 服務

  1. 建立外部 LoadBalancer 服務,公開範例工作負載。

    1. 將下列 Service 資訊清單儲存為 store-v1-lb-svc.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: store-v1-lb-svc
        annotations:
          cloud.google.com/l4-rbs: "enabled"
      spec:
        type: LoadBalancer
        selector:
          app: store
        ports:
        - name: tcp-port
          protocol: TCP
          port: 8080
          targetPort: 8080
      
    2. 將資訊清單套用至叢集:

      kubectl apply -f store-v1-lb-svc.yaml
      

    請注意這個範例資訊清單的下列事項:

    • 首次將資訊清單套用至叢集時,Service 資訊清單必須包含 cloud.google.com/l4-rbs: "enabled" 註解。這會指示 GKE 建立以後端服務為基礎的外部直通式網路負載平衡器。如要支援 IPv6 和加權負載平衡等功能,必須使用後端服務型外部直通式網路負載平衡器。

    • 視叢集版本而定,GKE 會使用 GCE_VM_IP NEG 後端或非代管執行個體群組後端。在版本為 1.32.2-gke.1652000 的叢集中,以後端服務為基礎的外部直通式網路負載平衡器會使用 GCE_VM_IP NEG。在舊版中,以後端服務為基礎的外部直通式網路負載平衡器使用非代管執行個體群組。

    • 如果您將 cloud.google.com/l4-rbs: "enabled" 註解新增至現有外部 LoadBalancer 服務的資訊清單 (也就是在建立負載平衡器後),GKE 會忽略該註解。如果建立 External LoadBalancer 服務時沒有在資訊清單中加入這項註解,系統就會使用以目標集區為基礎的外部直通式網路負載平衡器。建議不要使用目標集區型外部直通式網路負載平衡器。

啟用加權負載平衡

如要根據每個節點上服務、就緒和非終止 Pod 的數量,將新連線按比例分配至節點,請在服務資訊清單中新增 networking.gke.io/weighted-load-balancing: "pods-per-node" 註解,啟用加權負載平衡。

  1. store-v1-lb-svc.yaml Service 資訊清單中新增 networking.gke.io/weighted-load-balancing: "pods-per-node" 註解,並確保您也設定了 externalTrafficPolicy: Local,如下所示:

    apiVersion: v1
    kind: Service
    metadata:
      name: store-v1-lb-svc
      annotations:
        cloud.google.com/l4-rbs: "enabled"
        networking.gke.io/weighted-load-balancing: "pods-per-node"
    spec:
      type: LoadBalancer
      externalTrafficPolicy: Local
      selector:
        app: store
      ports:
      - name: tcp-port
        protocol: TCP
        port: 8080
        targetPort: 8080
    
  2. 將資訊清單套用至叢集:

    kubectl apply -f store-v1-lb-svc.yaml
    

請注意下列加權負載平衡範例的相關事項:

  • Service 資訊清單使用 externalTrafficPolicy: Local。如果不需要啟用加權負載平衡,也可以使用 externalTrafficPolicy: Cluster。如要進一步瞭解 externalTrafficPolicy 如何定義節點分組、哪些節點通過負載平衡器健康狀態檢查,以及封包的處理方式,請參閱「LoadBalancer Service 概念」。

  • 如果您啟用加權負載平衡,GKE 不會禁止您使用 externalTrafficPolicy: Cluster,但 externalTrafficPolicy: Cluster 會有效停用加權負載平衡,因為封包可能會在負載平衡器之後,轉送至其他節點。

您也可以使用 kubectl edit svc service-name,在現有的外部 LoadBalancer 服務上啟用加權負載平衡。kubectl edit 指令會在您設定的文字編輯器中開啟現有負載平衡器的服務資訊清單,您可以在其中修改資訊清單並儲存變更。編輯現有的外部 LoadBalancer 服務時,請注意下列事項:

  • 現有的外部 LoadBalancer Service 必須已建立後端服務型外部直通式網路負載平衡器。也就是說,當資訊清單首次套用至叢集時,現有的外部 LoadBalancer 服務必須包含 cloud.google.com/l4-rbs: "enabled" 註解。

    如果現有的外部 LoadBalancer Service 使用以目標集區為基礎的外部直通式網路負載平衡器,則新增 networking.gke.io/weighted-load-balancing: "pods-per-node" 註解不會有任何影響。

  • 更新現有的外部 LoadBalancer 服務資訊清單時,請務必設定 externalTrafficPolicy: Local。使用 externalTrafficPolicy: Cluster 會有效停用加權負載平衡,因為封包可能會在負載平衡器之後,轉送至其他節點。

停用加權負載平衡

如要將新連線分配至節點,而不論每個節點上有多少服務 Pod,請從 Service 資訊清單中移除 networking.gke.io/weighted-load-balancing: "pods-per-node" 註解,停用加權負載平衡。

驗證外部 LoadBalancer 服務及其元件

  1. 確認服務正在執行:

    kubectl get svc store-v1-lb-svc
    

    輸出結果會與下列內容相似:

    NAME               TYPE           CLUSTER-IP        EXTERNAL-IP     PORT(S)          AGE
    store-v1-lb-svc   LoadBalancer   10.44.196.160     35.193.28.231   8080:32466/TCP   11m
    

    GKE 已為外部直通式網路負載平衡器指派 EXTERNAL_IP

  2. 測試能否連線至負載平衡器:

    curl EXTERNAL_IP:PORT
    

    更改下列內容:

    • EXTERNAL_IP:為外部直通式網路負載平衡器分配的 IP 位址。
    • PORT:外部直通式網路負載平衡器的已分配通訊埠號碼。

    輸出結果會與下列內容相似:

    Hostname: store-v1-lb-svc-cdb9bb4d6-hflxd
    
    Pod Information:
      -no pod information available-
    
    Server values:
      server_version=nginx: 1.13.3 - lua: 10008
    
    Request Information:
      client_address=10.128.0.50
      method=GET
      real path=/
      query=
      request_version=1.1
      request_scheme=http
      request_uri=EXTERNAL_IP
    
    Request Headers:
      accept=*/*
      host=EXTERNAL_IP
      user-agent=curl/7.81.0
    
    Request Body:
      -no body in request-
    
    
  3. 檢查 LoadBalancer 服務及其註解集,其中說明瞭Google Cloud 資源:

    kubectl describe svc store-v1-lb-svc
    

    輸出結果會與下列內容相似:

    Name:                     my-service-external
    Namespace:                default
    Labels:                   <none>
    Annotations:              cloud.google.com/l4-rbs: enabled
                              cloud.google.com/neg-status: {"network_endpoint_groups":{"0":"k8s2-qvveq1d8-default-my-service-ext-5s55db85"},"zones":["us-central1-c"]} #This annotation appears in the output only if the service uses NEG backends.
                              networking.gke.io/weighted-load-balancing: pods-per-node #This annotation appears in the output only if weighted load balancing is enabled.
                              service.kubernetes.io/backend-service: k8s2-qvveq1d8-default-my-service-ext-5s55db85
                              service.kubernetes.io/firewall-rule: k8s2-qvveq1d8-default-my-service-ext-5s55db85
                              service.kubernetes.io/firewall-rule-for-hc: k8s2-qvveq1d8-default-my-service-ext-5s55db85-fw
                              service.kubernetes.io/healthcheck: k8s2-qvveq1d8-default-my-service-ext-5s55db85
                              service.kubernetes.io/tcp-forwarding-rule: a808124abf8ce406ca51ab3d4e7d0b7d
    Selector:                 app=my-app
    Type:                     LoadBalancer
    IP Family Policy:         SingleStack
    IP Families:              IPv4
    IP:                       10.18.102.23
    IPs:                      10.18.102.23
    LoadBalancer Ingress:     35.184.160.229
    Port:                     tcp-port  8080/TCP
    TargetPort:               8080/TCP
    NodePort:                 tcp-port  31864/TCP
    Endpoints:                10.20.1.28:8080,10.20.1.29:8080
    Session Affinity:         None
    External Traffic Policy:  Local
    HealthCheck NodePort:     30394
    
    Events:
      Type    Reason                Age                    From                     Message
      ----    ------                ----                   ----                     -------
      Normal  ADD                   4m55s                  loadbalancer-controller  default/my-service-ext
    

    有幾個欄位會指出後端服務型外部直通式網路負載平衡器及其 Google Cloud 資源已成功建立:

    • Events 欄位。如果 LoadBalancer 服務及其資源已成功建立,這個欄位會顯示空白。如果發生錯誤,會列於此處。
    • 已啟用 Annotations:GKE 會將下列唯讀註解清單新增至服務資訊清單。名稱開頭為 service.kubernetes.io/ 的每個註解,都用於指出為負載平衡器建立或支援的Google Cloud 資源名稱。

      • networking.gke.io/weighted-load-balancing: pods-per-node 註解表示已套用加權負載平衡,且負載平衡器會根據每個節點上執行的 Pod 數量,將流量分配至後端 Pod。
      • service.kubernetes.io/backend-service 註解表示負載平衡器的後端服務名稱。
      • service.kubernetes.io/healthcheck 註解表示後端服務使用的負載平衡器健康狀態檢查名稱。
      • service.kubernetes.io/tcp-forwarding-ruleservice.kubernetes.io/udp-forwarding-rule 註解表示負載平衡器轉送規則的名稱。
      • service.kubernetes.io/firewall-rule 註解表示為允許流量傳輸至叢集節點而建立的防火牆規則名稱。您可以使用 spec.loadBalancerSourceRanges[] 自訂這項防火牆規則的來源範圍。如要進一步瞭解 LoadBalancer 服務的防火牆規則,請參閱防火牆規則和來源 IP 位址允許清單
      • service.kubernetes.io/firewall-rule-for-hc 註解表示負載平衡器健康狀態檢查所需的防火牆規則名稱。
      • cloud.google.com/neg-status 註解會指出負載平衡器使用的 NEG 及其區域。只有在符合下列所有條件時,才會顯示這項註解:

        • 將資訊清單套用至叢集時,叢集執行的是 GKE 1.32.2-gke.1652000 以上版本,且
        • 將 Service 資訊清單套用至叢集時,該資訊清單中含有 cloud.google.com/l4-rbs: "enabled" 註解。
  4. 確認已為外部 LoadBalancer 服務建立負載平衡器資源和防火牆規則:

    • 如要查看轉送規則,請執行下列指令:

        gcloud compute forwarding-rules describe FWD_RULE_NAME \
          --region=REGION_NAME
      

      更改下列內容:

      • FWD_RULE_NAME:由 service.kubernetes.io/tcp-forwarding-ruleservice.kubernetes.io/udp-forwarding-rule 唯讀註解提供的轉送規則名稱。如要檢查這些註解,請執行 kubectl describe svc SERVICE_NAME
      • REGION_NAME:包含叢集的 Google Cloud 區域 。如果是區域叢集,則區域包含叢集使用的可用區。
    • 如要查看後端服務,請執行下列指令:

      gcloud compute backend-services describe BACKEND_SERVICE_NAME \
        --region=REGION_NAME
      

      更改下列內容:

      • BACKEND_SERVICE_NAMEservice.kubernetes.io/backend-service 唯讀註解提供的後端服務名稱。如要檢查這項唯讀註解,請執行 kubectl describe svc SERVICE_NAME
      • REGION_NAME:包含叢集的 Google Cloud 區域 。如果是區域叢集,則區域會包含叢集使用的可用區。
    • 如要查看負載平衡器健康狀態檢查,請執行下列指令:

      gcloud compute health-checks describe HEALTH_CHECK_NAME \
        --region=REGION_NAME
      

      更改下列內容:

      • HEALTH_CHECK_NAME:負載平衡器的健康檢查名稱。健康狀態檢查的名稱是由 service.kubernetes.io/healthcheck 唯讀註解提供。如要檢查這個唯讀註解,請執行 kubectl describe svc SERVICE_NAME
      • REGION_NAME:包含叢集的 Google Cloud 區域。如果是區域叢集,則區域會包含叢集使用的可用區。
    • 如要查看防火牆規則,請執行下列指令:

      gcloud compute firewall-rules describe FIREWALL_RULE_NAME \
      gcloud compute firewall-rules describe HEALTH_CHECK_FIREWALL_RULE_NAME
      

      更改下列內容:

      • FIREWALL_RULE_NAME:允許流量流向負載平衡器的防火牆規則名稱。這個防火牆規則的名稱是由 service.kubernetes.io/firewall-rule 唯讀註解提供。如要檢查這項唯讀註解,請執行 kubectl describe svc SERVICE_NAME
      • HEALTH_CHECK_FIREWALL_RULE_NAME:允許負載平衡器後端 (叢集節點) 健康狀態檢查的防火牆規則名稱。這項防火牆規則的名稱是由service.kubernetes.io/firewall-rule-for-hc唯讀註解提供。如要檢查這項唯讀註解,請執行 kubectl describe svc SERVICE_NAME
    • 如要查看負載平衡器 NEG,請執行下列指令:

      gcloud compute network-endpoint-groups describe NEG_NAME \
        --zone=ZONE_NAME
      

      更改下列內容:

      • NEG_NAME:負載平衡器的 NEG 名稱。NEG 的名稱是由 cloud.google.com/neg-status 唯讀註解提供。如要檢查這個唯讀註解,請執行 kubectl describe svc SERVICE_NAME 指令。註解包含結構化資料,內含負載平衡器使用的 NEG 名稱和區域相關資訊。如果是可用區叢集,這個註解會包含一個 NEG 的相關資訊。如果是區域叢集,這個註解會包含叢集所在每個區域的 NEG 相關資訊。
      • ZONE_NAME:包含 NEG 的 Google Cloud 區域。

刪除外部 LoadBalancer 服務

如要刪除範例 store-v1-lb-svc 外部 LoadBalancer 服務,請使用下列指令:

kubectl delete service store-v1-lb-svc

GKE 會自動移除為外部 LoadBalancer Service 建立的所有負載平衡器資源。

遷移至 GCE_VM_IP NEG 後端

使用 cloud.google.com/l4-rbs: "enabled" 註解的外部 LoadBalancer 服務會建立以網路端點群組或執行個體群組後端為基礎的外部直通式網路負載平衡器,具體取決於叢集的 GKE 版本:GCE_VM_IP

  • 如果將 Service 資訊清單套用至執行 GKE 1.32.2-gke.1652000 以上版本的叢集,產生的外部直通式網路負載平衡器會使用GCE_VM_IP網路端點群組 (NEG) 後端。

  • 如果將 Service 資訊清單套用至執行舊版 GKE 的叢集,產生的外部直通式網路負載平衡器會使用非代管執行個體群組後端。

詳情請參閱「關於 LoadBalancer 服務」一文中的節點分組

如果現有 Service 使用下列任一負載平衡器,您可以建立新的外部 LoadBalancer Service,並以使用 GCE_VM_IP NEG 後端的後端服務為基礎,透過外部直通式網路負載平衡器提供服務:

  • 以執行個體群組後端為基礎的後端服務型外部直通式網路負載平衡器
  • 以目標集區為基礎的外部直通式網路負載平衡器

如要使用 GCE_VM_IP NEG 後端切換至後端服務型外部直通式網路負載平衡器,請按照下列步驟操作:

  1. 如果尚未升級叢集,請升級至 GKE 1.32.2-gke.1652000 以上版本。

  2. 找出要切換至以後端服務為基礎的外部直通式網路負載平衡器的外部 LoadBalancer 服務,並使用 GCE_VM_IP NEG 後端。使用下列指令說明服務:

    kubectl describe svc SERVICE_NAME -n SERVICE_NAMESPACE
    

    更改下列內容:

    • SERVICE_NAME:現有外部 LoadBalancer 服務的名稱。

    • SERVICE_NAMESPACE:現有外部 LoadBalancer 服務的命名空間。

    在指令輸出內容中,記下現有負載平衡器在 EXTERNAL-IP 欄中使用的外部 IPv4 位址。

  3. 擷取現有 LoadBalancer 服務的 Service 資訊清單:

    • 最好是使用您先前套用至叢集的原始 Service 資訊清單。舉例來說,您可能會在來源控制存放區中看到這個檔案。

    • 如果沒有原始的 Service 資訊清單:

      • 執行下列指令,取得代表負載平衡器目前實作項目的 Service 資訊清單 YAML 副本:

        kubectl get svc SERVICE_NAME -n SERVICE_NAMESPACE -o yaml
        
      • 將資訊清單 YAML 複製到文字編輯器。移除 status 屬性和下列 metadata 屬性:

        • 所有下列註解:
          • kubectl.kubernetes.io/last-applied-configuration 註解
          • 開頭為 service.kubernetes.io 的所有註解
        • creationTimestamp
        • finalizers
        • resourceVersion
        • uid
    • 確認資訊清單包含 cloud.google.com/l4-rbs: "enabled" 註解。如果您要從目標集區型外部直通式網路負載平衡器遷移,則需要新增註解。

    請記下包含服務資訊清單檔案的本機路徑。本程序其餘部分會將路徑稱為 MANIFEST_FILE_PATH

  4. 設定靜態外部 IPv4 位址資源,保留現有負載平衡器使用的外部 IPv4 位址:

    gcloud compute addresses create IP_ADDRESS_NAME --region=CLUSTER_REGION --addresses LB_EXTERNAL_IP
    

    更改下列內容:

    • IP_ADDRESS_NAME:靜態外部 IP 位址的名稱。名稱必須遵守 Compute Engine 資源的命名慣例

    • CLUSTER_REGION:叢集所在的區域。 如果是區域叢集,這是指包含叢集區域的地區。

    • LB_EXTERNAL_IP:目前負載平衡器使用的外部 IPv4 位址,此位址是在本程序的第二個步驟中決定。

  5. 確認已建立靜態外部 IPv4 位址資源:

    gcloud compute addresses describe IP_ADDRESS_NAME --region=CLUSTER_REGION
    

    替換上一步中列出的變數。

  6. 刪除現有服務:

    kubectl delete svc SERVICE_NAME -n SERVICE_NAMESPACE
    
  7. 將下列註解新增至 MANIFEST_FILE_PATH 服務資訊清單檔案:

    networking.gke.io/load-balancer-ip-addresses: IP_ADDRESS_NAME
    

    如要進一步瞭解這項註解,請參閱 LoadBalancer 服務參數中的「靜態 IP 位址」。

  8. 將更新後的 Service 資訊清單套用至叢集:

    kubectl apply -f MANIFEST_FILE_PATH
    
  9. (選用) 釋出靜態 IPv4 位址資源。

    gcloud compute addresses delete IP_ADDRESS_NAME --region=CLUSTER_REGION
    

疑難排解

本節說明設定加權負載平衡時可能遇到的問題。

加權負載平衡的外部流量政策有誤

啟用加權負載平衡時,如果未設定 externalTrafficPolicy: Local,使用下列指令說明服務時,可能會收到警告事件:

kubectl describe svc store-v1-lb-svc`
Events:
  Type     Reason                   Age      From                     Message
  ----     ------                   ----     ----                     -------
  Warning  UnsupportedConfiguration 4m55s    loadbalancer-controller  Weighted load balancing by pods-per-node has no effect with External Traffic Policy: Cluster.

如要有效啟用加權負載平衡,您必須設定 externalTrafficPolicy: Local

後續步驟