GKE クラスタでの高度なロード バランシング

このページでは、Kubernetes API を使用して、マネージド Cloud Service Mesh(TD)ユーザーの GKE クラスタで高度なロード バランシングを構成する方法について説明します。Google Cloud API を使用して高度なロード バランシングを構成する対応するユーザーガイドについては、高度なロード バランシングを設定するをご覧ください。

高度なロード バランシングを使用すると、次のことができます。

  • ローカル容量が使い果たされるまで、サービスゾーンへのトラフィックを維持します。
  • 「プライマリ」ロケーションのサービスにトラフィックを送信し、プライマリ ロケーションの十分なエンドポイントが異常になった場合はセカンダリ ロケーションにフェイルオーバーします。
  • フェイルオーバーが発生するタイミングを制御する(正常なホストの割合に基づく)。

制限事項

  • Google Cloud で高度なロード バランシングを使用する場合の一般的な制限事項が適用されます。
  • この機能は、Traffic Director をコントロール プレーンとして使用しているマネージド Cloud Service Mesh ユーザーのみが使用できます。データプレーン バージョン 1.19.10-asm.22 以降が必要です。
  • GCPTrafficDistributionPolicy と GCPBackendPolicy のすべてのフィールドが、managedCloud Service Mesh(TD)でサポートされているわけではありません。サポートされているフィールドは次のとおりです。
    • GCPTrafficDistributionPolicy
      • ServiceLbAlgorithm
      • AutoCapacityDrain
      • FailoverConfig
    • GCPBackendPolicy
      • MaxRatePerEndpoint
      • BackendPreference
  • 高度なロード バランシングは、 Google Cloudで実行されているワークロードを基盤とする Kubernetes サービスにのみ適用できます。外部サービスまたはワークロード(ServiceEntry など)はサポートされていません。
  • ロード バランシング ポリシーは、個々の Kubernetes サービスにのみ適用できます。Namespace 全体またはメッシュ全体のロード バランシング ポリシーはサポートされていません。
  • QPS 容量のみがサポートされます。
  • GKE バージョン 1.31.1 以降のみがサポートされます。
  • Service Mesh の高度なロード バランシング ポリシーは、メッシュ トラフィックのみを処理するサービスにのみ適用する必要があります。GKE Gateway バックエンドとして機能するサービスには適用しないでください。高度なロード バランシング トラフィックが、メッシュ トラフィックと GKE Gateway からのトラフィックの両方を処理する Kubernetes サービスをターゲットとしている場合、トラフィックの動作は未定義です。

高度なロード バランシングを構成する

次のカスタム リソースを使用して、GKE で高度なロード バランシングを構成できます。詳細なリソース定義については、gke-gateway-api リポジトリをご覧ください。

GCPTrafficDistributionPolicy

GCPTrafficDistributionPolicy は、Kubernetes サービスのサービスレベルのロード バランシング ポリシーを構成します。次のことが可能になります。

複数の GCPTrafficDistributionPolicy が同じサービスをターゲットとしている場合、最も古いポリシーが適用されます。

GCPBackendPolicy

GCPBackendPolicy は、ロード バランシング動作に影響するサービス バックエンドのプロパティを構成します。次に例を示します。

複数の GCPBackendPolicy がクラスタ内の同じサービスをターゲットとしている場合、最も古いポリシーが適用されます。

ポリシーのステータス

GCPTrafficDistributionPolicy と GCPBackendPolicy の両方に、ポリシーの接続ステータスを示す status フィールドがあります。

たとえば、kubectl describe gcpbackendpolicies example-policy -n example を実行すると、次のような出力が表示されます。

...
Status:
  Ancestors:
    Ancestor Ref:
      Group:
      Kind:       Service
      Name:       example-svc
      Namespace:  example
    Conditions:
      Last Transition Time:  2024-10-13T01:15:03Z
      Message:
      Observed Generation:   1
      Reason:                Attached
      Status:                True
      Type:                  Attached
    Controller Name:         gsmconfig.gke.io/controller

事前設定

このガイドを完了するには、GKE クラスタに Cloud Service Mesh をプロビジョニングする必要があります。

  1. CRD がインストールされていることを確認します。

    kubectl get crd
    

    出力は次のようになります。

    ...
    gcptrafficdistributionpolicies.networking.gke.io   2024-07-18T21:50:12Z
    gcpbackendpolicies.networking.gke.io               2024-07-18T21:50:12Z
    ...
    
  2. GCPBackendPolicy CRD がまだインストールされていない場合は、インストールします。

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcpbackendpolicies.yaml
    
  3. GCPTrafficDistributionPolicy CRD がまだインストールされていない場合は、インストールします。

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcptrafficdistributionpolicies.yaml
    

このユーザーガイドのサンプル ポリシーは、デモ用に Namespace foo 内の Service foo をターゲットとしています。次のコマンドを実行してテストサービスと Namespace を作成できます。必要に応じて、独自のサービスと Namespace を使用することもできます。

kubectl apply -f - <<EOF
kind: Namespace
apiVersion: v1
metadata:
  name: foo
  labels:
    istio-injection: enabled
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: foo
  namespace: foo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: test-backend
  template:
    metadata:
      labels:
        app: test-backend
    spec:
      containers:
      - name: whereami
        image: gcr.io/google-samples/whereami:v1.2.23
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: foo
  namespace: foo
spec:
  selector:
    app: test-backend
  ports:
  - port: 8080
    targetPort: 8080
EOF

ロード バランシング アルゴリズムの構成

デフォルトでは、サービスへのトラフィックは、Cloud Service Mesh サービス メッシュ内の正常なサービス バックエンドに均等に分散されます。次の GCPTrafficDistributionPolicy を作成すると、トラフィックがバックエンドの容量まで最も近いゾーンに分散されます。

kubectl apply -f - <<EOF
apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: lb-policy
  namespace: foo
spec:
  targetRefs:
  - kind: Service
    group: ""
    name: foo-service
  default:
    serviceLbAlgorithm: WATERFALL_BY_ZONE
EOF

デフォルトでは、サービス バックエンドは容量が無制限であるかのように扱われます。ローカルゾーンまたは最も近いゾーンに十分な正常なホストがある場合、特定のクライアント ロカリティのローカルゾーンまたは最も近いゾーン外にトラフィックが分散されることはありません。必要に応じて、GCPBackendPolicy を使用してサービス バックエンドの容量を構成し、単一のゾーンが過負荷にならないようにします。

kubectl apply -f - <<EOF
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: backend-policy
  namespace: foo
spec:
  targetRef:
    kind: Service
    group: ""
    name: foo-backend
  default:
    maxRatePerEndpoint: 5
EOF

フェイルオーバー動作のチューニング

デフォルトでは、プライマリ バックエンドで十分な割合のホストが正常である限り、フェイルオーバーはトリガーされません。プライマリ バックエンドなどの用語の詳細については、高度なロード バランシングの概要をご覧ください。GCPTrafficDistributionPolicy を使用すると、トラフィックがプライマリ バックエンドからフェイルオーバー バックエンドにシフトされるまでの正常なホストの割合のしきい値を構成できます。しきい値が大きいほど、フェイルオーバーがより早くトリガーされます。たとえば、プライマリ バックエンドで正常なホストの割合が 90% を下回るとすぐにフェイルオーバーをトリガーする場合は、次の GCPTrafficDistributionPolicy を構成できます。

kubectl apply -f - <<EOF
apiVersion: networking.gke.io/v1
kind: GCPTrafficDistributionPolicy
metadata:
  name: lb-policy
  namespace: foo
spec:
  targetRefs:
  - kind: Service
    group: ""
    name: foo-service
  default:
   failoverConfig:
     failoverHealthThreshold: 90
EOF

マルチクラスタ サービス メッシュで高度なロード バランシングを構成する

GCPTrafficDistributionPolicy と GCPBackendPolicy は、マルチクラスタ Service Mesh の異なるスコープに適用されます。

GCPTrafficDistributionPolicy がマルチクラスタ Service をターゲットとする場合は、すべてのクラスタでのサービスレベルのロード バランシング動作を定義します。特定のマルチクラスタ サービスに対して作成する必要がある GCPTrafficDistributionPolicy は 1 つだけです。Istio API を使用してサービス メッシュを構成する場合は、フリート内の任意のクラスタに GCPTrafficDistributionPolicy を作成できます。ポリシーが別のポリシーと競合しているかどうかを確認するには、ポリシーのステータスを調べます。

GCPBackendPolicy がマルチクラスタ サービスをターゲットとする場合は、ローカル クラスタ内のターゲティング サービスによって選択されたバックエンド Pod のバックエンド レベルの設定(Pod ごとの容量など)を定義します。同じマルチクラスタ サービスに対して、異なるクラスタで異なるバックエンド レベルの設定を定義できます。

次の例では、クラスタ A に GCPTrafficDistributionPolicy が作成され、フリート全体で使用されるロード バランシング アルゴリズムが定義されます。GCPBackendPolicies は各クラスタにあります。どちらの GCPBackendPolicy も、ローカル クラスタ内のバックエンド Pod に Pod あたり 10qps の容量を構成しますが、クラスタ A の GCPBackendPolicy は、クラスタ A のバックエンド Pod を優先バックエンドとして構成します。

これらのポリシーを組み合わせて、Service foo に送信されるメッシュ内トラフィックのロード バランシング動作を構成します。

  • クラスタ A のバックエンド Pod が Pod あたり 10 qps を処理する必要があるまで、どこからでもトラフィックはクラスタ A のバックエンドを優先します。
    • この動作は、クラスタ A で backendPreferencePREFERRED に設定する GCPBackendPolicy によって主に定義されます。
  • クラスタ A のバックエンドの構成容量を超えるトラフィックは、アルゴリズム WATERFALL_BY_ZONE を使用してクラスタ B にルーティングされます。優先バックエンドの詳細については、高度なロード バランシングの概要をご覧ください。
    • この動作は、主にクラスタ A の GCPTrafficDistributionPolicy(アルゴリズムを定義)と、クラスタ A とクラスタ B の両方の GCPBackendPolicy(バックエンド容量を定義)によって定義されます。

高度なロード バランシング マルチクラスタ サービス メッシュ

Istio では、サービス メッシュに複数のクラスタがあり、クラスタ境界にまたがってサービスが作成されている場合、通常の Kubernetes サービスは暗黙的に「マルチクラスタ」になります。次の GCPTrafficDistributionPolicy は通常の Kubernetes Service foo をターゲットにしていますが、2 つのクラスタ内の対応するワークロードで構成されるマルチクラスタ Service foo にも適用されます。

  1. クラスタ A の GCPTrafficDistributionPolicy を作成します。

    kubectl apply --context cluster-a-context -f - <<EOF
    kind: GCPTrafficDistributionPolicy
    apiVersion: networking.gke.io/v1
    metadata:
    name: foo-traffic-distribution-policy
    namespace: foo
    spec:
      targetRefs:
      - kind: Service
        group: ""
        name: foo-service
      default:
        serviceLbAlgorithm: WATERFALL_BY_ZONE
    
    EOF
    
  2. クラスタ A の GCPBackendPolicy を作成します。

    kubectl apply --context cluster-a-context -f - <<EOF
    kind: GCPBackendPolicy
    apiVersion: networking.gke.io/v1
    metadata:
    name: foo-backend-policy
    namespace: foo
    spec:
      default:
        maxRatePerEndpoint: 100
        backendPreference: PREFERRED
      targetRef:
        group: ""
        kind: Service
        name: foo-service
    EOF
    
  3. クラスタ B の GCPBackendPolicy を作成します。

    kubectl apply --context cluster-b-context -f - <<EOF
    kind: GCPBackendPolicy
    apiVersion: networking.gke.io/v1
    metadata:
    name: foo-backend-policy
    namespace: foo
    spec:
      default:
        maxRatePerEndpoint: 10
      targetRef:
        group: ""
        kind: Service
        name: foo-service
    EOF
    

次のステップ