GKE Dataplane V2 で Maglev ロード バランシングを使用する

このドキュメントでは、GKE Dataplane V2 の Service の Maglev ロード バランシングを構成して検証する方法について説明します。

Maglev は、高スループットと低レイテンシのロード バランシングを提供する一貫性のあるハッシュ アルゴリズムです。Maglev は、バックエンド Pod のスケーリング、更新、再スケジュール時に、同じフローが同じバックエンドに一貫してマッピングされるようにすることで、パケットのドロップと接続の中断を最小限に抑えます。

詳細については、Maglev コンシステント ハッシュ法アルゴリズムの調査論文をご覧ください。

この機能は、バックエンドの変更によって既存のフローが中断されないようにする必要がある、有効期間の長い接続やステートフル アプリケーションを使用するワークロードにおすすめします。

リソースのオーバーヘッドとスケーラビリティに関する考慮事項については、GKE Dataplane V2 のコンセプトをご覧ください。

始める前に

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

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

前提条件と上限

  • GKE バージョン: 1.36.0-gke.2882000 以降
  • GKE Dataplane V2: 有効
  • クラスタモード: Autopilot と Standard

GKE Dataplane V2 を使用して GKE クラスタを作成する

Maglev を使用するには、GKE Dataplane V2 が有効になっている GKE クラスタが必要です。

Autopilot

Autopilot クラスタでは、デフォルトで GKE Dataplane V2 が有効になっています。Autopilot クラスタを作成して構成を取得するには、次のコマンドを実行します。

gcloud container clusters create-auto CLUSTER_NAME \
    --region=COMPUTE_REGION \
    --release-channel=rapid
gcloud container clusters get-credentials CLUSTER_NAME \
    --region=COMPUTE_REGION

Standard

Standard クラスタで GKE Dataplane V2 を有効にするには、--enable-dataplane-v2 フラグを使用します。Standard クラスタを作成してその構成を取得するには、次のコマンドを実行します。

gcloud container clusters create CLUSTER_NAME \
    --zone=COMPUTE_ZONE \
    --enable-dataplane-v2 \
    --cluster-version=1.36.0-gke.2882000
gcloud container clusters get-credentials CLUSTER_NAME \
    --zone=COMPUTE_ZONE

バックエンド アプリケーションをデプロイする

ロード バランシング サービスを構成する前に、トラフィックを処理するバックエンド アプリケーションをデプロイします。この Deployment は、hello-app サンプル アプリケーションの 5 つのレプリカを実行します。

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

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-backend
    spec:
      replicas: 5
      selector:
        matchLabels:
          app: echo-backend
      template:
        metadata:
          labels:
            app: echo-backend
        spec:
          containers:
          - name: hello
            image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
            ports:
            - containerPort: 8080
    
  2. 次のようにマニフェストを適用します。

    kubectl apply -f echo-backend.yaml
    

ロード バランシング サービスを構成する

Maglev ロード バランシング アルゴリズムまたはデフォルトのランダム ロード バランシング アルゴリズムを使用するように Service を構成できます。どちらの Service も、前の手順で作成した echo-backend Deployment をターゲットにしています。

Maglev サービスを構成する

Maglev ロード バランシングを有効にするには、作成時に gke.networking.io/lb-algorithm: "maglev" アノテーションを Service メタデータに追加します。

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

    apiVersion: v1
    kind: Service
    metadata:
      name: maglev-service
      annotations:
        gke.networking.io/lb-algorithm: "maglev"
    spec:
      selector:
        app: echo-backend
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    
  2. 次のようにマニフェストを適用します。

    kubectl apply -f maglev-service.yaml
    

ランダムな Service を構成する

デフォルトでは、Service はランダム ロード バランシング アルゴリズムを使用します。デフォルトのアルゴリズムを使用するためにアノテーションを指定する必要はありませんが、次の例では比較のために明示的に構成しています。

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

    apiVersion: v1
    kind: Service
    metadata:
      name: random-service
      annotations:
        gke.networking.io/lb-algorithm: "random"
    spec:
      selector:
        app: echo-backend
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    
  2. 次のようにマニフェストを適用します。

    kubectl apply -f random-service.yaml
    

トラフィックの整合性を確認する

Maglev とランダム ロード バランシングのルーティングの一貫性の違いを確認するには、固定ソースポートからトラフィックを送信するテスト クライアント Pod をデプロイします。

Maglev トラフィックの整合性を確認する

Maglev は、同じ送信元ポートからのリクエストを同じバックエンド Pod に一貫して転送します。

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

    apiVersion: v1
    kind: Pod
    metadata:
      name: client-maglev
    spec:
      restartPolicy: Never
      containers:
      - name: curl
        image: curlimages/curl:8.2.0
        command: ["/bin/sh", "-c"]
        args:
        - |
          while true; do
            curl -s -H "Connection: close" http://maglev-service:80 --local-port 54321 | grep Hostname
            sleep 0.5
          done
    

    --local-port フラグは送信元ポートを強制し、Connection: close ヘッダーは、クライアントが後続のリクエストですぐに送信元ポートを再利用できるようにします。

  2. 次のようにマニフェストを適用します。

    kubectl apply -f client-maglev.yaml
    
  3. Pod の実行中にログを確認します。

    kubectl logs client-maglev
    

    想定される出力:

    出力には、同じホスト名が繰り返し表示されます。これは、クライアントからのすべてのトラフィックが同じバックエンド Pod に一貫してルーティングされていることを示しています。

    Hostname: echo-backend-5c78f66dbf-abcde
    Hostname: echo-backend-5c78f66dbf-abcde
    

デフォルト(ランダム)のトラフィック分散を確認する

デフォルトの Service は、同じ送信元ポートからのトラフィックを異なるバックエンド Pod に分散します。

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

    apiVersion: v1
    kind: Pod
    metadata:
      name: client-random
    spec:
      restartPolicy: Never
      containers:
      - name: curl
        image: curlimages/curl:8.2.0
        command: ["/bin/sh", "-c"]
        args:
        - |
          while true; do
            curl -s -H "Connection: close" http://random-service:80 --local-port 54321 | grep Hostname
            sleep 0.5
          done
    
  2. 次のようにマニフェストを適用します。

    kubectl apply -f client-random.yaml
    
  3. Pod の実行中にログを確認します。

    kubectl logs client-random
    

    想定される出力:

    出力には複数の異なるホスト名が表示され、トラフィックが異なる Pod に分散されていることがわかります。

    Hostname: echo-backend-5c78f66dbf-abcde
    Hostname: echo-backend-5c78f66dbf-fghij
    Hostname: echo-backend-5c78f66dbf-klmno
    ...
    

クリーンアップ

このチュートリアルで使用したリソースをクリーンアップするには、次のコマンドを実行します。

  1. クライアント Pod、Service、Deployment を削除します。

    kubectl delete service maglev-service random-service
    kubectl delete deployment echo-backend
    kubectl delete pod client-maglev client-random
    
  2. GKE クラスタを削除します。

Autopilot

gcloud container clusters delete CLUSTER_NAME --region=COMPUTE_REGION

Standard

gcloud container clusters delete CLUSTER_NAME --zone=COMPUTE_ZONE