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

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

外部パススルー ネットワーク ロードバランサの詳細については、バックエンド サービスベースの外部パススルー ネットワーク ロードバランサをご覧ください。

概要

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

混合プロトコル LoadBalancer Service を使用すると、単一の Service を使用して TCP と UDP の両方のトラフィックを管理できます。単一の Service を使用すると、両方のプロトコルに単一の 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 を削除して再作成する必要があります。

料金

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

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

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

このセクションでは、TCP ポートと UDP ポートの両方でリッスンするサンプル ワークロードをデプロイする方法について説明します。混合プロトコル LoadBalancer Service を使用しているか、2 つの個別の単一プロトコル LoadBalancer Service を使用しているかに関係なく、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
    

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

TCP トラフィックと UDP トラフィックの両方に Deployment を公開する 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 に関する一般的な問題を解決する方法について説明します。

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

トラブルシューティングの最初の手順は、サービスに関連付けられているイベントを確認することです。

  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 の場合: kubectl apply--server-side フラグを使用します。

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

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

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

次のステップ