部署多網路 LoadBalancer 服務

本文說明如何在 GKE 中建立 Google Cloud 外部直通式網路負載平衡器和內部直通式網路負載平衡器資源,將多網路 Pod 公開給內部或外部用戶端。說明多重網路LoadBalancer服務的必要設定、功能和限制。

如果將工作負載連線至多個 VPC 網路,請使用 LoadBalancer 類型的 Kubernetes 服務,將流量轉送至特定次要網路上的 Pod。建立 Service 時,GKE 會建立直通式網路負載平衡器來管理這類流量。

如要進一步瞭解 GKE 中的多重網路,請參閱「關於 Pod 的多重網路支援」。

多重網路 LoadBalancer 服務的運作方式

如要公開多網路工作負載,請建立 Servicetype: LoadBalancer。 Service 必須包含特殊選取器,根據次要介面的網路指定 Pod。新增註解,指定要建立內部或外部負載平衡器。

選取器中的 networking.gke.io/network 標籤會依網路篩選端點。這個標籤可確保負載平衡器只會將流量傳送到連線至指定網路的 Pod 介面。

限制

多重網路負載平衡器有下列限制:

  • 不支援使用 externalTrafficPolicy: Cluster 的服務。
  • 系統不支援以 hostNetwork Pod 為目標的服務。
  • 不支援 IPv6 和雙重堆疊網路。
  • 您無法變更現有服務的網路。
  • 僅支援第 3 層網路。
  • 系統不支援以目標集區或執行個體群組後端為基礎的負載平衡器。
  • 次要 (非預設) 網路不支援 ClusterIP 和 NodePort 服務。

事前準備

開始之前,請先完成下列工作:

  1. 按照「為 Pod 設定多網路支援功能」中的步驟,準備虛擬私有雲網路,並建立具有額外網路的 GKE 叢集。
  2. 確認叢集已啟用第 4 層內部負載平衡器的子設定。如要啟用這項功能,請在建立或更新叢集時使用 --enable-l4-ilb-subsetting 旗標。
  3. 確認叢集執行的是 GKE 1.37 以上版本。

部署多網路 Pod

如要將 Pod 附加至其他網路,請使用 networking.gke.io/interfaces 註解建立 Deployment。這項註解會指定 Pod 的網路和介面。

  1. 將下列資訊清單儲存為 web-app-deployment.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: web-app
      labels:
        app: web-app
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: web-app
      template:
        metadata:
          labels:
            app: web-app
          annotations:
            networking.gke.io/default-interface: 'eth1'
            networking.gke.io/interfaces: '[
              {"interfaceName":"eth0","network":"default"},
              {"interfaceName": "eth1","network": "dmz"}
            ]'
    spec:
      containers:
      - name: whereami
        image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
        ports:
        - containerPort: 8080
    

    這份資訊清單會建立名為 web-app 的 Deployment,當中包含三個 Pod。Pod 有兩個介面:eth0連線至 default 網路,以及eth1連線至 dmz 網路。networking.gke.io/default-interface註解會將 eth1 設為 Pod 的預設介面。

  2. 將資訊清單套用至叢集:

    kubectl apply -f web-app-deployment.yaml
    

如果服務使用非預設介面,您必須在 Pod 中設定路由。如要設定路由,請在 Pod 規格中新增 initContainer,該規格具備 NET_ADMIN 功能。

以下範例顯示 initContainer,可為 eth1 介面新增預設路徑:

initContainers:
      - name: init-routes-busybox
        image: busybox
        command: ['sh', '-c', 'ip route add default dev eth1 table 200 && ip rule add from 172.16.1.0/24 table 200']
        securityContext:
          capabilities:
            add: ["NET_ADMIN"]

initContainer 指令中,將 172.16.1.0/24 替換為 Pod 網路的次要 IP 位址範圍。

部署內部 LoadBalancer 服務

如要在 dmz 網路中公開 web-app Deployment,請建立內部 LoadBalancer 服務。

  1. 將下列資訊清單儲存為 internal-lb-service.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: web-app-internal-lb
      namespace: default
      annotations:
        networking.gke.io/load-balancer-type: "Internal"
    spec:
      externalTrafficPolicy: Local
      ports:
      -   port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        networking.gke.io/network: dmz
        app: web-app
      type: LoadBalancer
    

    這份資訊清單會建立具備下列屬性的 Service:

    • networking.gke.io/load-balancer-type: "Internal":指定內部直通式網路負載平衡器。
    • selector:選取具有 app: web-app 標籤且連線至 dmz 網路的 Pod。
  2. 將資訊清單套用至叢集:

    kubectl apply -f internal-lb-service.yaml
    

部署外部 LoadBalancer 服務

如要向外部用戶端公開 web-app Deployment,請建立外部 LoadBalancer Service。

  1. 將下列資訊清單儲存為 external-lb-service.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: web-app-external-lb
      namespace: default
      annotations:
        cloud.google.com/l4-rbs: "enabled"
    spec:
      externalTrafficPolicy: Local
      ports:
      -   port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        networking.gke.io/network: dmz
        app: web-app
      type: LoadBalancer
    

    這份資訊清單會建立具備下列屬性的 Service:

    • cloud.google.com/l4-rbs: "enabled":指定以後端服務為基礎的外部直通式網路負載平衡器。
    • selector:選取具有 app: web-app 標籤且連線至 dmz 網路的 Pod。
  2. 將資訊清單套用至叢集:

    kubectl apply -f external-lb-service.yaml
    

驗證服務

部署服務後,請確認負載平衡器已建立並正確設定。

  1. 檢查服務狀態:

    kubectl get services
    

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

    NAME                  TYPE           CLUSTER-IP    EXTERNAL-IP     PORT(S)        AGE
    web-app-external-lb   LoadBalancer   10.8.47.77    35.239.57.231   80:31550/TCP   5m
    web-app-internal-lb   LoadBalancer   10.8.43.251   172.16.0.43     80:32628/TCP   6m
    kubernetes            ClusterIP      10.8.32.1     <none>          443/TCP        43h
    

    內部負載平衡器的 EXTERNAL-IP 位址屬於 dmz 網路。

  2. 列出專案中的轉送規則:

    gcloud compute forwarding-rules list
    

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

    NAME                                                   REGION        IP_ADDRESS     IP_PROTOCOL  TARGET
    af901673cc0f24907a6aa8c3ce4afc21                       us-central1   35.239.57.231  TCP          us-central1/backendServices/k8s2-xhvzqabw-default-web-app-external-lb-u4xbs4ot
    k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a us-central1   172.16.0.43    TCP          us-central1/backendServices/k8s2-xhvzqabw-default-web-app-internal-lb-vp1x1d6a
    
  3. 說明內部負載平衡器的轉送規則,確認該規則已附加至正確的網路:

    gcloud compute forwarding-rules describe k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a --region=$REGION
    

    REGION 替換為叢集所在區域。

    輸出結果大致如下。確認 networksubnetwork 欄位與 dmz 網路的詳細資料相符。

    IPAddress: 172.16.0.43
    IPProtocol: TCP
    ...
    loadBalancingScheme: INTERNAL
    name: k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a
    network: https://www.googleapis.com/compute/v1/projects/projectId/global/networks/dmz-vpc
    ...
    subnetwork: https://www.googleapis.com/compute/v1/projects/projectId/regions/us-central1/subnetworks/dmz-subnet
    

測試負載平衡器

  1. 如要測試外部負載平衡器,請將要求傳送至其外部 IP 位址:

    curl EXTERNAL_LB_IP:80
    

    EXTERNAL_LB_IP 替換為 web-app-external-lb 服務的外部 IP 位址。

  2. 如要測試內部負載平衡器,請從與負載平衡器位於相同 VPC 的主機傳送要求:

    curl INTERNAL_LB_IP:80
    

    INTERNAL_LB_IP 替換為 web-app-internal-lb 服務的 IP 位址。

疑難排解

本節說明如何排解多重網路負載平衡器的問題。

無法建立負載平衡器

如果無法建立負載平衡器,請檢查服務事件中的錯誤訊息:

kubectl describe service SERVICE_NAME

SERVICE_NAME 改為您的服務名稱。

如果出現 network some-other-network does not exist 等錯誤訊息,表示叢集未定義服務選取器中指定的網路。確認網路是否存在:

kubectl get networks

如果網路存在,請確認 Network 物件是否正確參照有效的 GKENetworkParamSet 資源。如要檢查設定錯誤,請檢查 Network 資源狀態:

kubectl get networks NETWORK_NAME -o yaml

請將 NETWORK_NAME 替換成您網路的名稱。

在有效設定中,ParamsReadyReady 條件都是 True。如果 ParamsReady 不是 True,請確認 Network 規格中的 parametersRef 與現有 GKENetworkParamSet 資源的名稱、種類和群組正確相符。

如果 Network 資源正確,但仍未準備就緒,請檢查參照 GKENetworkParamSet 的狀態是否有錯誤,例如缺少子網路:

kubectl get gkenetworkparamsets GNP_NAME -o yaml

GNP_NAME 替換為 GKENetworkParamSet 的名稱。

負載平衡器沒有後端

如果負載平衡器已佈建,但沒有健康狀態良好的後端,請執行下列操作:

  1. 確認節點集區存在於服務使用的網路中,且具有網路介面。
  2. 確認服務選取的 Pod 正在執行。
  3. 檢查服務的端點:

    kubectl describe endpointslice -l kubernetes.io/service-name=SERVICE_NAME
    

    multinet-endpointslice-controller.gke.io 控制器會建立多重網路端點。EndpointSlice 中列出的 Pod IP 位址屬於 Service 使用的網路。如果 EndpointSlice 沒有端點,請確認服務選取器標籤與正在執行的 Pod 相符,且網路選取器與 Pod 的網路相符。

後續步驟