建立混合通訊協定負載平衡器

本文說明如何使用混合通訊協定的外部或內部 LoadBalancer 服務,同時處理 TCP 和 UDP 流量,公開在 Google Kubernetes Engine (GKE) 叢集中執行的應用程式。

如要進一步瞭解 L4 負載平衡器,請參閱「關於 LoadBalancer 服務」。

總覽

如要公開同時使用 TCP 和 UDP 通訊協定的應用程式,可以使用兩個個別的 GKE LoadBalancer 服務,並手動協調共用 IP 位址。不過,這種做法效率不彰,因為您必須為單一應用程式管理多個服務,而且可能會導致設定錯誤或 IP 位址配額用盡等問題。

混合通訊協定 LoadBalancer 服務可讓您使用單一服務,同時管理 TCP 和 UDP 的流量。使用單一 Service 可讓您同時使用這兩種通訊協定,並共用一組轉送規則和一個 IP 位址,簡化設定。這項功能支援區域性外部直通式網路負載平衡器和內部直通式網路負載平衡器。

GKE 支援 IPv4、IPv6 和雙重堆疊設定的混合通訊協定服務。混合通訊協定服務會使用第 3 層 (L3) 轉送規則。根據設計,這些規則會將所有抵達負載平衡器虛擬 IP (VIP) 位址的流量,直接轉送至叢集節點。

為維護安全性,GKE 會自動建立及管理優先順序為 999 的防火牆規則,只允許 Service 資訊清單中定義的特定 TCP 和 UDP 流量。所有其他導向負載平衡器 VIP 位址的未授權流量,都會遭到 GKE 管理的防火牆規則封鎖,優先順序為 1000。如果您建立優先順序較高的防火牆規則,請確保規則不會意外允許未經授權的流量連上節點。詳情請參閱「GKE 服務防火牆規則」。

事前準備

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

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。
  • 請確認您有現有的 Autopilot 或 Standard 叢集。如要建立新叢集,請參閱「建立 Autopilot 叢集」。

需求條件

如要建立使用混合通訊協定的 LoadBalancer 服務,叢集必須符合下列規定:

  • GKE 1.36.2-gke.1498000 以上版本正式支援混合通訊協定負載平衡。正式發布的版本支援外部和內部負載平衡器,以及 IPv4、IPv6 和雙重堆疊設定。
  • 在 1.34.1-gke.2190000 至 1.36.2-gke.1498000 版本中,混合通訊協定負載平衡僅適用於使用 IPv4 位址的外部負載平衡器。
  • 您必須在叢集上啟用 HttpLoadBalancing 外掛程式。
  • 如果是內部負載平衡器,叢集必須啟用 GKE 子設定
  • 如果是新的內部 LoadBalancer 服務,請在 Service 資訊清單中,將 spec.loadBalancerClass 欄位的值設為 networking.gke.io/l4-regional-internal。如果是現有的內部服務,資訊清單中已有 networking.gke.io/load-balancer-type: "Internal" 註解,您可以保留註解。
  • 如為新的外部 LoadBalancer 服務,請在 Service 資訊清單中將 spec.loadBalancerClass 欄位設為 networking.gke.io/l4-regional-external。如果是現有的外部服務,資訊清單中已有 cloud.google.com/l4-rbs: "enabled" 註解,您可以保留註解。

限制

  • 在 1.34.1-gke.2190000 到 1.36.2-gke.1498000 版本中,混合通訊協定負載平衡器僅支援 IPv4 位址。
  • 具有 gke.networking.io/l4-ilb-v1gke.networking.io/l4-netlb-v1 終止程式的現有服務,無法用於混合通訊協定負載平衡。如要在這些服務上使用混合通訊協定,請務必按照上述規定刪除並重新建立服務。
  • 更新服務上的通訊埠可能會導致透過負載平衡器轉送的所有流量短暫中斷。

定價

Google Cloud 會針對任何外部 IP 位址和傳送的資料,按轉送規則向您收費。下表說明指定設定使用的轉送規則和外部 IP 位址數量。詳情請參閱「虛擬私有雲網路定價」。

類型 傳輸層 網際網路層 轉送規則數量 外部 IP 位址數量
內部 單一或混合 (TCP、UDP 或兩者) IPv4 1 0
IPv6 1 0
IPv4 和 IPv6 (雙重堆疊) 2 0
外部 單一或混合 (TCP、UDP 或兩者) IPv4 1 1
IPv6 1 1
IPv4 和 IPv6 (雙重堆疊) 2 2

部署工作負載

本節說明如何部署同時監聽 TCP 和 UDP 連接埠的範例工作負載。請注意,無論您是使用混合通訊協定的 LoadBalancer 服務,還是兩個獨立的單一通訊協定 LoadBalancer 服務,Deployment 設定都相同。

  1. 下列資訊清單適用於範例應用程式,可監聽 TCP 和 UDP 流量的通訊埠 8080。請將下列資訊清單儲存為 mixed-app-deployment.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: mixed-app-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: mixed-app
      template:
        metadata:
          labels:
            app: mixed-app
        spec:
          containers:
          - image: gcr.io/kubernetes-e2e-test-images/agnhost:2.6
            name: agnhost
            args: ["serve-hostname", "--port=8080", "--tcp=true", "--udp=true", "--http=false"]
            ports:
              - name: tcp8080
                protocol: TCP
                containerPort: 8080
              - name: udp8080
                protocol: UDP
                containerPort: 8080
    
  2. 將資訊清單套用至叢集:

    kubectl apply -f mixed-app-deployment.yaml
    

建立混合通訊協定負載平衡器

建立 LoadBalancer 類型的服務,將部署項目同時公開給 TCP 和 UDP 流量。您可以建立外部或內部負載平衡器。

  1. 如要建立外部負載平衡器,請將下列資訊清單儲存為 mixed-protocol-lb.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: mixed-protocol-external-lb
    spec:
      loadBalancerClass: "networking.gke.io/l4-regional-external"
      type: LoadBalancer
      selector:
        app: mixed-app
      ports:
      - name: tcp-port
        protocol: TCP
        port: 8080
      - name: udp-port
        protocol: UDP
        port: 8080
    

    如要建立內部負載平衡器,請將 spec.loadBalancerClass 欄位的值設為 networking.gke.io/l4-regional-internal

    上述 Service 有兩個通訊埠,一個用於 TCP,另一個用於 UDP,兩者都位於通訊埠 8080。

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

    kubectl apply --server-side -f mixed-protocol-lb.yaml
    

驗證混合通訊協定負載平衡器

建立 Service 後,請確認 GKE 已成功建立負載平衡器。

  1. 檢查 Service:

    kubectl describe service SERVICE_NAME
    

    SERVICE_NAME 替換為您的服務名稱 (例如 mixed-protocol-lb)。

    輸出內容會顯示負載平衡器的 IP 位址和轉送規則。確認輸出內容中的下列詳細資料:

    • 已填入 status.loadBalancer.ingress.ip 欄位。
    • 如果是 1.34.1-gke.2190000 到 1.36.2-gke.1498000 版本的叢集,請確認外部負載平衡器有下列註解:
      • service.kubernetes.io/tcp-forwarding-rule
      • service.kubernetes.io/udp-forwarding-rule
    • 如果是透過 1.36.2-gke.1498000 以上版本建立的叢集,請視設定而定,確認負載平衡器是否具有下列註解:
      • IPv4service.kubernetes.io/l3-forwarding-rule
      • IPv6:service.kubernetes.io/l3-forwarding-rule-ipv6
      • 雙重堆疊:兩個註解。
    • Events」部分不含任何錯誤訊息。

更新混合通訊協定負載平衡器

如要更新混合通訊協定負載平衡器上的通訊埠,請編輯服務資訊清單。如要編輯服務,請執行下列指令:

kubectl edit service SERVICE_NAME

SERVICE_NAME 改為您的服務名稱。

更新連接埠

如要更新混合通訊協定負載平衡器上的通訊埠,請修改 Service 資訊清單的 ports 區段。您可以新增、移除或修改連接埠。

以下範例新增了串流用的 UDP 通訊埠,以及遊戲伺服器中繼資料用的 TCP 通訊埠:

apiVersion: v1
kind: Service
metadata:
  name: mixed-protocol-lb
spec:
  loadBalancerClass: "networking.gke.io/l4-regional-external"  # for internal LB, use: "networking.gke.io/l4-regional-internal"
  type: LoadBalancer
  selector:
    app: mixed-app
  ports:
  - name: tcp-port
    protocol: TCP
    port: 8080
  - name: streaming
    protocol: UDP
    port: 10100
  - name: gameserver-metadata
    protocol: TCP
    port: 10400
  - name: https
    protocol: TCP
    port: 443

將單一通訊協定負載平衡器更新為混合通訊協定

如要將單一通訊協定負載平衡器變更為混合通訊協定負載平衡器,請編輯 Service,加入 TCP 和 UDP 通訊協定的通訊埠。

以下範例會為現有的純 TCP 負載平衡器新增 DNS 的 UDP 連接埠:

apiVersion: v1
kind: Service
metadata:
  name: already-existing-single-protocol-lb
spec:
  loadBalancerClass: "networking.gke.io/l4-regional-external" # for internal LB, use: "networking.gke.io/l4-regional-internal"
  type: LoadBalancer
  selector:
    app: mixed-app
  ports:
  - name: http
    protocol: TCP
    port: 80
  - name: https
    protocol: TCP
    port: 443
  - name: dns
    protocol: UDP
    port: 53

將混合通訊協定負載平衡器更新為單一通訊協定

如要將混合通訊協定負載平衡器變更為單一通訊協定負載平衡器,請移除其中一個通訊協定的所有通訊埠。

以下範例會移除 DNS 的 UDP 連接埠,將負載平衡器轉換為僅限 TCP:

apiVersion: v1
kind: Service
metadata:
  name: already-existing-mixed-protocol-lb
spec:
  loadBalancerClass: "networking.gke.io/l4-regional-external" # for internal LB, use: "networking.gke.io/l4-regional-internal"
  type: LoadBalancer
  selector:
    app: mixed-app
  ports:
  - name: http
    protocol: TCP
    port: 80
  - name: https
    protocol: TCP
    port: 443

刪除混合通訊協定 LoadBalancer

如要刪除混合通訊協定 LoadBalancer 服務,請執行下列指令:

kubectl delete service SERVICE_NAME

SERVICE_NAME 替換為您的服務名稱 (例如 mixed-protocol-external-lb)。

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

疑難排解

本節說明如何解決混合通訊協定 LoadBalancer 服務的常見問題。

檢查錯誤事件

疑難排解的第一步是檢查與服務相關聯的事件。

  1. 取得服務詳細資料:

    kubectl describe service SERVICE_NAME
    

    SERVICE_NAME 改為您的服務名稱。

  2. 查看輸出內容結尾的 Events 部分,瞭解是否有任何錯誤訊息。

錯誤:LoadBalancer 不支援混合通訊協定

如果您使用 cloud.google.com/l4-rbs: "enabled" 註解建立服務,建立混合通訊協定負載平衡器後,您可能會看到原始服務控制器發出的警告事件:mixed-protocol is not supported for LoadBalancer

您可以放心忽略這則訊息,因為支援混合通訊協定的新控制器會正確佈建負載平衡器。

更新後缺少連接埠定義

症狀:

更新同時使用 TCP 和 UDP 的 Service 時 (例如通訊埠 8080),更新後的 Service 會缺少其中一個通訊埠定義。

原因:

這是 Kubernetes 的已知問題。在同一個通訊埠上更新具有多個通訊協定的服務時,用戶端修補程式計算可能會錯誤合併通訊埠清單,導致其中一個通訊埠定義遭到移除。這個問題會影響使用用戶端修補程式的用戶端,例如 kubectl apply 和 Go 用戶端 (含合併修補程式)。

解決方法:

這個問題的解決方法取決於您的用戶端。

  • kubectl:使用 --server-side 標記搭配 kubectl apply

    kubectl apply --server-side -f YOUR_SERVICE_MANIFEST.yaml
    

    YOUR_SERVICE_MANIFEST 改為您的服務資訊清單名稱。

  • Go 用戶端:請勿使用合併修補程式。請改用更新呼叫來取代服務。這需要使用 HTTP PUT 要求,並提供完整的 Service 物件規格。

後續步驟