混合プロトコルの外部ロードバランサを作成する

このドキュメントでは、TCP トラフィックと UDP トラフィックの両方に混合プロトコルの外部 LoadBalancer Service を使用して、Google Kubernetes Engine(GKE)クラスタで実行されているアプリケーションをインターネットに公開する方法について説明します。

外部パススルー ネットワーク ロードバランサの詳細については、Backend service-based external passthrough Network Load Balancerをご覧ください。

概要

TCP プロトコルと UDP プロトコルの両方を使用するアプリケーションは、手動で調整された共有 IP アドレスを持つ 2 つの別々の GKE LoadBalancer Service を使用して公開できます。ただし、このアプローチは、1 つのアプリケーションに対して複数の Service を管理する必要があるため非効率的であり、構成エラーや IP アドレス割り当ての枯渇などの問題が発生する可能性があります。

混合プロトコルの LoadBalancer Service を使用すると、1 つの Service で TCP と UDP の両方のトラフィックを管理できます。1 つの Service を使用すると、両方のプロトコルに 1 つの IPv4 アドレスと統合された転送ルールのセットを使用できるため、構成が簡素化されます。この機能は、外部パススルー ネットワーク ロードバランサでサポートされています。

始める前に

作業を始める前に、次のタスクが完了していることを確認してください。

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API の有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。gcloud CLI をインストール済みの場合は、gcloud components update コマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。
  • すでに Autopilot クラスタまたは Standard クラスタが存在していることを確認する。新しいクラスタを作成するには、Autopilot クラスタの作成をご覧ください。

要件

混合プロトコルを使用する外部 LoadBalancer Service を作成するには、クラスタが次の要件を満たしている必要があります。

  • 混合プロトコル ロード バランシングは、バージョン 1.34.1-gke.2190000 以降で使用できます。
  • クラスタで HttpLoadBalancing アドオンが有効になっている必要があります。
  • 新しい外部 LoadBalancer Service の場合、ロードバランサを実装するには、Service マニフェストで spec.loadBalancerClass フィールドを networking.gke.io/l4-regional-external に設定します。既存の Service の場合、マニフェストにはすでに cloud.google.com/l4-rbs: "enabled" アノテーションが含まれているため、アノテーションはそのままにしておくことができます。

制限事項

  • 混合プロトコル ロードバランサは IPv4 アドレスのみをサポートします。
  • 次のファイナライザを使用して、Service マニフェストで混合プロトコルを使用することはできません。

    • gke.networking.io/l4-ilb-v1
    • gke.networking.io/l4-netlb-v1

    マニフェストにこれらのファイナライザが含まれている場合は、上記の要件に従って Service を削除して再作成する必要があります。

料金

Cloud de Confiance は、転送ルールごと、外部 IP アドレスごと、送信データごとに課金されます。次の表に、指定された構成で使用される転送ルールと外部 IP アドレスの数を示します。詳細については、VPC ネットワークの料金をご覧ください。

タイプ トランスポート層 インターネット層 転送ルールの数 外部 IP アドレスの数
外部 単一(TCP または UDP) IPv4 1 1
IPv6 1 1
IPv4 と IPv6(デュアル スタック) 2 2
混合(TCP と UDP の両方) IPv4 2 1

ワークロードをデプロイする

このセクションでは、TCP ポートと UDP ポートの両方でリッスンするサンプル ワークロードをデプロイする方法について説明します。Deployment 構成は、混合プロトコルの LoadBalancer Service を使用しているか、2 つの別々の単一プロトコル LoadBalancer Service を使用しているかによって異なります。

  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
    

混合プロトコル ロードバランサを作成する

デプロイを TCP トラフィックと UDP トラフィックの両方に公開する LoadBalancer タイプの Service を作成します。

  1. 次のマニフェストを mixed-protocol-lb.yaml として保存します。

    apiVersion: v1
    kind: Service
    metadata:
      name: mixed-protocol-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
    

    上記の Service には、TCP 用と UDP 用の 2 つのポートがあり、どちらもポート 8080 にあります。

  2. マニフェストをクラスタに適用します。

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

混合プロトコル ロードバランサを確認する

Service を作成したら、GKE がロードバランサを正常に作成したことを確認します。

  1. サービスの検査:

    kubectl describe service mixed-protocol-lb
    

    出力には、ロードバランサの外部 IP アドレスと、TCP と UDP の両方の転送ルールが表示されます。出力で次の詳細を確認します。

    • status.loadBalancer.ingress.ip フィールドが入力されている。
    • 外部ロードバランサに次のアノテーションが存在することを確認します。
      • service.kubernetes.io/tcp-forwarding-rule
      • service.kubernetes.io/udp-forwarding-rule
    • Events セクションにエラー メッセージが含まれていない。

混合プロトコル ロードバランサを更新する

混合プロトコル ロードバランサのポートは、Service マニフェストを編集して更新できます。Service を編集するには、次のコマンドを実行します。

kubectl edit service SERVICE_NAME

SERVICE_NAME は、Service の名前に置き換えます。

ポートを更新する

混合プロトコル ロードバランサのポートを更新するには、Service マニフェストの ports セクションを変更します。ポートの追加、削除、変更が可能です。

次の例では、ストリーミング用の UDP ポートと、ゲームサーバー メタデータ用の TCP ポートを追加します。

apiVersion: v1
kind: Service
metadata:
  name: mixed-protocol-lb
spec:
  loadBalancerClass: "networking.gke.io/l4-regional-external"
  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

単一プロトコル ロードバランサを混合プロトコルに更新する

単一プロトコル ロードバランサを混合プロトコル ロードバランサに変更するには、TCP プロトコルと UDP プロトコルの両方のポートを含めるように Service を編集します。

次の例では、DNS 用の UDP ポートを既存の TCP 専用ロードバランサに追加します。

apiVersion: v1
kind: Service
metadata:
  name: already-existing-single-protocol-lb
spec:
  loadBalancerClass: "networking.gke.io/l4-regional-external"
  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"
  type: LoadBalancer
  selector:
    app: mixed-app
  ports:
  - name: http
    protocol: TCP
    port: 80
  - name: https
    protocol: TCP
    port: 443

混合プロトコル LoadBalancer を削除する

mixed-protocol-lb 外部 LoadBalancer Service を削除するには、次のコマンドを実行します。

kubectl delete service mixed-protocol-lb

GKE は、Service 用に作成されたすべてのロードバランサ リソースを自動的に削除します。

トラブルシューティング

このセクションでは、混合プロトコルの LoadBalancer Service に関する一般的な問題を解決する方法について説明します。

エラーイベントを確認する

トラブルシューティングの最初のステップは、Service に関連付けられたイベントを確認することです。

  1. Service の詳細を取得します。

    kubectl describe service mixed-protocol-lb
    
  2. 出力の末尾にある Events セクションで、エラー メッセージがないか確認します。

エラー: 混合プロトコルは LoadBalancer でサポートされていません

cloud.google.com/l4-rbs: "enabled" アノテーションを使用して Service を作成した場合、混合プロトコル ロードバランサの作成後に、元のサービス コントローラ から警告イベントが表示されることがあります: mixed-protocol is not supported for LoadBalancer

新しいコントローラは混合プロトコルをサポートしており、ロードバランサを正しくプロビジョニングするため、このメッセージは無視しても問題ありません。

更新後にポート定義が欠落している

症状:

TCP と UDP の両方に同じポート(ポート 8080 など)を使用する Service を更新すると、更新された Service からポート定義の 1 つが欠落します。

原因:

これは Kubernetes の既知の問題です。同じポートで複数のプロトコルを使用して Service を更新すると、クライアントサイドのパッチ計算でポートリストが誤ってマージされ、ポート定義の 1 つが削除されます。この問題は、クライアントサイドのパッチ適用を使用するクライアント(kubectl apply やマージパッチを使用する Go クライアントなど)に影響します。

ソリューション:

この問題の回避策は、クライアントによって異なります。

  • kubectl の場合: --server-side フラグを kubectl apply で使用します。

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

    YOUR_SERVICE_MANIFEST は、Service マニフェストの名前に置き換えます。

  • go-client の場合: マージパッチを使用しないでください。代わりに、update 呼び出しを使用して Service を置き換えます。これには、Service オブジェクト全体の仕様を含む HTTP PUT リクエストが必要です。

次のステップ