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 のすべてのフィールドが、マネージド Cloud Service Mesh(TD)でサポートされているわけではありません。サポートされているフィールドは次のとおりです。
- GCPTrafficDistributionPolicy
- ServiceLbAlgorithm
- AutoCapacityDrain
- FailoverConfig
- GCPBackendPolicy
- MaxRatePerEndpoint
- BackendPreference
ここに記載されていないフィールドはすべてサポートされていないフィールドです。サポートされていないフィールドが 1 つ以上構成されているポリシーは、Cloud Service Mesh で有効になりません。
- GCPTrafficDistributionPolicy
高度なロード バランシングは、 Google Cloudで実行されているワークロードを基盤とする Kubernetes Service にのみ適用できます。外部サービスまたはワークロード(ServiceEntry など)はサポートされていません。
ロード バランシング ポリシーは、個々の Kubernetes Service にのみ適用できます。名前空間全体またはメッシュ全体のロード バランシング ポリシーはサポートされていません。
QPS 容量のみがサポートされています。
GKE バージョン 1.31.1 以降のみがサポートされています。
Service Mesh の高度なロード バランシング ポリシーは、メッシュ トラフィックのみを処理するサービスにのみ適用する必要があります。GKE Gateway バックエンドとして機能するサービスには適用しないでください。高度なロード バランシング トラフィックが、メッシュ トラフィックと GKE Gateway からのトラフィックの両方を処理する Kubernetes Service をターゲットとしている場合、トラフィックの動作は未定義です。
高度なロード バランシングを構成する
次のカスタム リソースを使用して、GKE で高度なロード バランシングを構成できます。詳細なリソース定義については、gke-gateway-api リポジトリをご覧ください。
GCPTrafficDistributionPolicy
GCPTrafficDistributionPolicy は、Kubernetes Service のサービスレベルのロード バランシング ポリシーを構成します。次のことが可能です。
- カスタム ロード バランシング アルゴリズムを選択する。サポートされているアルゴリズムについては、高度なロード バランシング テーブルをご覧ください。
- 自動容量ドレインを有効にする。
- フェイルオーバー ヘルスしきい値を調整する。
複数の GCPTrafficDistributionPolicy が同じサービスをターゲットとしている場合、最も古いポリシーが適用されます。
GCPBackendPolicy
GCPBackendPolicy は、ロード バランシング動作に影響するサービス バックエンドのプロパティを構成します。次に例を示します。
- サービス バックエンドの容量。
- 優先バックエンドの指定。
複数の GCPBackendPolicy がクラスタ内の同じサービスをターゲットとしている場合、最も古いポリシーが適用されます。
ポリシーのステータス
GCPTrafficDistributionPolicy と GCPBackendPolicy の両方に、ポリシーの接続ステータスを示すステータス フィールドがあります。
たとえば、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 をプロビジョニングする必要があります。
CRD がインストールされていることを確認します。
kubectl get crd
出力は次のようになります。
... gcptrafficdistributionpolicies.networking.gke.io 2024-07-18T21:50:12Z gcpbackendpolicies.networking.gke.io 2024-07-18T21:50:12Z ...
GCPBackendPolicy CRD がまだインストールされていない場合は、インストールします。
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-gateway-api/refs/heads/main/config/crd/networking.gke.io_gcpbackendpolicies.yaml
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 をターゲットとしています。次のコマンドを実行してテストサービスと名前空間を作成できます。また、必要に応じて、独自のサービスと名前空間を使用することもできます。
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 は、マルチクラスタ サービス メッシュの異なるスコープに適用されます。
GCPTrafficDistributionPolicy がマルチクラスタ サービスをターゲットとする場合は、すべてのクラスタでのサービスレベルのロード バランシング動作を定義します。特定のマルチクラスタ サービスに対して作成する 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 で
backendPreference
をPREFERRED
に設定する GCPBackendPolicy によって主に定義されます。
- この動作は、クラスタ A で
- クラスタ A のバックエンドの構成容量を超えるトラフィックは、アルゴリズム
WATERFALL_BY_ZONE
を使用してクラスタ B にルーティングされます。優先バックエンドの詳しい説明については、高度なロード バランシングの概要をご覧ください。- この動作は、主にクラスタ A の GCPTrafficDistributionPolicy(アルゴリズムを定義)と、クラスタ A とクラスタ B の両方の GCPBackendPolicy(バックエンド容量を定義)によって定義されます。
Istio では、サービス メッシュに複数のクラスタがあり、クラスタ境界にまたがってサービスが作成されている場合、通常の Kubernetes Service は暗黙的に「マルチクラスタ」になります。次の GCPTrafficDistributionPolicy は通常の Kubernetes Service foo をターゲットにしていますが、2 つのクラスタ内の対応するワークロードで構成されるマルチクラスタ Service foo にも適用されます。
クラスタ 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
クラスタ 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
クラスタ 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
次のステップ
- 高度なロード バランシングの詳細を確認する