マルチクラスタ ネットワーキングは、リージョンごとの可用性を高める、レイテンシを短縮するためにグローバルに分散されたユーザーに接近する、チーム間で組織を分離する、などのユースケースを可能にする貴重なツールです。Google Kubernetes Engine(GKE)にはマルチクラスタ ネットワーキングの機能が組み込まれており、GKE クラスタのフリート全体で有効にして大規模に使用できます。この機能を使用すると、GKE Standard と Autopilot 間でデプロイされたインフラストラクチャの結合や移行を行って、各アプリケーションのアーキテクチャ ニーズに対応することもできます。
このドキュメントでは、いくつかのデプロイ トポロジを通じてこれらの機能について説明します。1 つの GKE クラスタにデプロイされたアプリケーションを、GKE Standard クラスタと Autopilot クラスタ間のマルチクラスタ デプロイに移行する方法について学習します。East-West トラフィックには GKE マルチクラスタ サービスを使用し、North-South マルチクラスタ ネットワーキングを有効にするにはマルチクラスタ Gateway を使用します。
このドキュメントは、複数の Kubernetes クラスタにサービスをデプロイするために GKE を使用する、または使用することを計画するクラウド アーキテクトと運用チームを対象としています。このドキュメントを読む前に、Kubernetes について理解しておいてください。
GKE Standard と GKE Autopilot
GKE は、高可用性コントロール プレーンを含む完全な機能セットを備えた、マネージド Kubernetes Deployment を実現します。GKE クラスタは迅速に起動でき、最大 15,000 個のノードまでスケーリングできます。GKE Autopilot クラスタでは、Google がコントロール プレーンやノードなどのインフラストラクチャを管理します。代わりにノードを構成および管理する場合、GKE にはStandard モードが用意されています。
モードの違いについては、クラスタ運用モードの選択をご覧ください。
マルチクラスタ Service とマルチクラスタ Gateway
Kubernetes は、異なるクラウドゾーン間で単一のコントロール プレーンを使用して動作し、サービスに復元力と高い可用性を実現できます。GKE では、この手順をさらに進めて、クラスタ間のサービス ディスカバリと呼び出しメカニズムを提供する GKE マルチクラスタ サービス(MCS)を提供します。この機能を使用するサービスは、仮想 IP を持つクラスタ間で検出とアクセスが可能になり、これは、クラスタでアクセス可能な ClusterIP
Service の動作と適合します。このアプローチには次のような利点があります。
- サービスは、同じリージョンまたは異なるリージョンの複数のクラスタ(East-West トラフィック)間でロードバランスできます。
- クロスリージョン サービスの高可用性オプションを実現します。
- ステートフル ワークロードとステートレス ワークロードは、個別のクラスタにデプロイして管理できます。
- 共有サービスは複数のクラスタで使用できます。
MCS をデプロイする方法の詳細については、マルチクラスタ Service の構成をご覧ください。
GKE は、GKE Gateway Controller を使用する Kubernetes Gateway API の実装を実現します。Gateway を使用すると、GKE は Google Cloud ロードバランサをデプロイし、GKE にデプロイされたサービスに対してインバウンド(north-south)トラフィックの転送を実現できます。また、GKE は GKE Gateway Controller を拡張して、異なる GKE クラスタにデプロイされたサービスにトラフィックを転送するマルチクラスタ Gateway(MCG)も備えています。
次の図は、MCS と MCG を組み合わせる場合に、サービスのデプロイとトラフィック ルーティングの補完的な側面を単一のコントロール プレーンから管理する方法を示しています。
詳細については、マルチクラスタ Gateway のデプロイをご覧ください。
移行の概要
GKE のマルチクラスタ ネットワーク機能は、さまざまなプロファイルのワークロードにメリットをもたらします。たとえば、トラフィックが急増しているステートレス コンポーネントで、より効率的なコストモデルを実現するために Autopilot に移行することが必要な場合があります。
また、アプリケーションのフロントエンドをユーザーの近くに配置したいと考える場合もあります。このアプローチは、レイテンシを短縮しキャッシュ保存を行うことで、アプリケーションのパフォーマンスとユーザー エクスペリエンスを改善します。また、1 つのロケーションにしか存在できないステートフル コンポーネントにアプリケーションが依存している場合があります。このような構成で、クライアント トラフィックをそのロケーションにある適切なクラスタに送信するには North-South マルチクラスタ ロード バランシングが必要になります。また、クラスタ間でトラフィックを送信してそのステートフル コンポーネントに到達させるには、East-West マルチクラスタ ロード バランシングも必要です。
このドキュメントでは、Online Boutique のクラウド マイクロサービスのデモ アプリケーションを使用して、シングルゾーン デモのデプロイを強化するために使用できるマルチクラスタ パターンについて説明します。アプリケーションのシングルゾーン バージョンから始めます。さらに、マルチクラスタ Service とマルチクラスタ Gateway を使用して高可用性と復元性の要素を追加し、Autopilot を活用して運用作業を軽減します。
単一クラスタの最初のデプロイ
次の図では、Online Boutique アプリケーションは、最初に std-west という名前の単一の GKE Standard モードクラスタにデプロイされ、LoadBalancer
Service を使用して公開されます。
マルチクラスタ Service への移行
次の中間ステップでは、2 つの追加クラスタを作成し、ステートレス サービスを追加のリージョンにデプロイします。単一の std-west GKE Standard クラスタとは別の 2 つの個別のリージョンに auto-east と auto-central という名前の 2 つの GKE Autopilot クラスタを作成し、そのクラスタを Google Cloud フリートに登録します。
フリートとは、複数のクラスタと他のリソースを論理的に編成するための Google Cloud のコンセプトです。フリートを使用することによって、マルチクラスタ機能の使用と管理、複数のシステム間での一貫したポリシーの適用が可能になります。
ServiceExport を使用して、onlineboutique 名前空間内の std-west クラスタの cartservice を新しいフリート クラスタにエクスポートします。Online Boutique の frontend Service を 3 つのクラスタすべてにデプロイし、ClusterIP サービスを介して公開します。次に、ServiceExports
を使用してサービスをフリートにエクスポートします。Online Boutique のミドルウェア レイヤなどのサービス(productcatalog、shipping、adservice など)も、3 つのクラスタすべてにデプロイされます。
フリート内の任意のクラスタで実行される Pod
は、そのサービスの ClusterSet
URI にリクエストを送信することで、エクスポートされた Service
にアクセスできます。リクエストは、サービスをバックアップするエンドポイントに転送されます。
frontend Service は、ミドルウェア サービス(productcatalogservice や currencyservice など)を同じクラスタ内でローカルに利用できます。このアーキテクチャは、受信リクエストをフロントエンドがリクエストに応答するリージョンにローカルに維持し、不要なリージョン間ネットワーク トラフィック課金を回避します。
次の図は、2 つのマルチクラスタ サービスを示しています。ステートレスの frontend Service が 3 つのクラスタにデプロイされ、ステートフルのバックエンド cartserviceが 1 つのクラスタにデプロイされます。また、この中間ステップでは、フロントエンドの外部 LoadBalancer
サービスによって作成された外部パススルー ネットワーク ロードバランサを使用して、フロントエンド サービスの受信トラフィックが引き続き us-west1 の元の GKE Standard クラスタにルーティングされることを示しています。
マルチクラスタ Gateway への移行
最後のステップでは、マルチクラスタ Gateway を使用して、frontend Service のインバウンド トラフィックを外部クライアント リクエストからフリート内の複数のクラスタのサービスにルーティングします。
この構成の一部として作成される Gateway と HTTPRoute リソースの構成をホストして管理するために、config-central という名前の 4 番目のクラスタがフリートに追加されます。HTTPRoute
リソースは、/ 接頭辞をフロントエンドの ServiceImport にマッピングします。Online Boutique のフロントエンドのトラフィックは、使用可能ないずれかのリージョンの正常なエンドポイントに送信されます。このアプローチにより、Online Boutique アプリケーション アーキテクチャに高可用性の要素が追加されます。
次の図では、マルチクラスタ Gateway がグローバル クラウド ロードバランサをデプロイしています。このロードバランサは、フリート内の 3 つのアプリケーション クラスタそれぞれにデプロイされたステートレスの frontend Service に外部トラフィックをルーティングします。
最終状態では、この独自のパターンは、アプリケーションのステートフル部分(cartservice と redis-cart)とステートレス部分(frontend、emailservice、checkoutservice、recommendationservice、paymentservice、productcatalogservice、currencyservice、shippingservice、adservice)の間の疎結合を示しています。このドキュメントの範囲外ですが、このアプローチにより、復元力と高可用性をステートフル サービスレイヤに追加できるようになります。
目標
- GKE Standard クラスタと Autopilot クラスタを作成して構成する。
- Online Boutique をゾーン GKE Standard クラスタにデプロイする。
- マルチクラスタ
Services
をエクスポートする。 - マニフェストを Standard クラスタと Autopilot クラスタにデプロイする。
- マルチクラスタ Gateway を有効にして構成する。
- マルチリージョン アプリケーションの動作をテストする。
費用
このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
始める前に
組織で定義されているセキュリティの制約により、次の手順を完了できない場合があります。トラブルシューティング情報については、制約のある Google Cloud 環境でアプリケーションを開発するをご覧ください。
開始する前に、次の要件を満たしていることを確認します。
- このガイドでは新しいプロジェクトを使用することをおすすめします。終了後にプロジェクトを削除することがクリーンアップの最も簡単な方法であるためです。
- このガイドでは、Google Cloud プロジェクトのオーナー IAM ロールがあることを前提としています。本番環境または実際の設定については、権限を最小権限の範囲にとどめておくことをおすすめします。詳細については、IAM の安全な使用と ID とアクセスの管理をご覧ください。
- Online Boutique マイクロサービスのデモ アプリケーション アーキテクチャを十分に理解します。
環境を準備する
このチュートリアルでは、Cloud Shell を使用してコマンドを入力します。Cloud Shell を使用すると Google Cloud コンソールのコマンドラインにアクセスできるほか、Google Cloud SDK や Google Cloud CLI などのツールも利用できます。Cloud Shell は、Google Cloud コンソールの下部にウィンドウとして表示されます。初期化が完了するまでに数分かかることもありますが、ウィンドウはすぐに表示されます。
In the Google Cloud console, activate Cloud Shell.
Cloud Shell で、このガイドで使用される環境変数を定義します。PROJECT_ID は実際のプロジェクト ID に置き換えます。
export PROJECT=PROJECT_ID gcloud config set project ${PROJECT}
このドキュメントに必要なサービスを有効にします。
gcloud services enable \ gkehub.googleapis.com \ multiclusteringress.googleapis.com \ dns.googleapis.com \ trafficdirector.googleapis.com \ cloudresourcemanager.googleapis.com \ multiclusterservicediscovery.googleapis.com \ container.googleapis.com gcloud container fleet multi-cluster-services enable
マルチクラスタ サービスでは、Cloud DNS、ファイアウォール ルール、Cloud Service Mesh などの Google Cloud コンポーネントを管理しているため、これらの API も有効にする必要があります。詳細については、Cloud Service Mesh の概要をご覧ください。
出力は次のようになります。
Operation "operations/acf.p2-822685001869-ee4ebe78-6dd8-465e-b0fd-3b0e5f964bad" finished successfully. Waiting for Feature Multi-cluster Services to be created...done.
マルチクラスタ Service が ACTIVE 状態になっていることを確認します。
gcloud container fleet multi-cluster-services describe
出力は次のようになります。
createTime: '2021-11-30T21:59:25.245190894Z' name: projects/PROJECT_ID/locations/global/features/multiclusterservicediscovery resourceState: state: ACTIVE spec: {} updateTime: '2021-11-30T21:59:27.459063070Z'
state の値が ACTIVE でない場合は、MCS ドキュメントのトラブルシューティングのセクションをご覧ください。
GKE クラスタを作成して構成する
マルチクラスタ パターンを示すために、3 つの独立したクラウド リージョンの 3 つのアプリケーション クラスタと、Gateway リソースの構成をホストする 1 つのクラスタを使用します。プロジェクトに関連付けられたフリートにすべてのクラスタを登録します。Google Cloud プロジェクトには 1 つのフリートのみを関連付けることができます。このプロジェクトは、フリート ホスト プロジェクトと呼ばれます。
Standard および Autopilot GKE クラスタを作成します。
gcloud container clusters create std-west \ --zone us-west1-a \ --num-nodes=6 \ --enable-ip-alias \ --release-channel regular \ --workload-pool=${PROJECT}.svc.id.goog \ --async gcloud container clusters create-auto auto-east \ --region us-east1 \ --release-channel regular \ --async gcloud container clusters create-auto auto-central \ --region us-central1 \ --release-channel regular \ --async gcloud container clusters create config-central \ --region us-central1 \ --num-nodes=1 \ --enable-ip-alias \ --release-channel regular \ --workload-pool=${PROJECT}.svc.id.goog \ --async
GKE 用 Workload Identity 連携は、GKE Autopilot クラスタでデフォルトで有効になるため、GKE Standard クラスタの場合と同様、これらのクラスタの作成時に
--workload-pool
フラグを使用する必要はありません。クラスタの STATUS が PROVISIONING から RUNNING に変わるまで待ちます。この処理には 10 分ほどかかることがあります。このドキュメントの以降の部分に進む前に、コーヒーを飲むか、軽いストレッチ体操をしながら、watch ループを使用して進行状況をモニタリングできます。
watch -n 20 --difference=permanent "gcloud container clusters list"
出力は次のようになります。
NAME: auto-central LOCATION: us-central1 MASTER_VERSION: 1.21.5-gke.1802 MASTER_IP: 107.178.213.138 MACHINE_TYPE: e2-medium NODE_VERSION: 1.21.5-gke.1802 NUM_NODES: 3 STATUS: PROVISIONING NAME: config-central LOCATION: us-central1 MASTER_VERSION: 1.21.5-gke.1802 MASTER_IP: MACHINE_TYPE: e2-medium NODE_VERSION: 1.21.5-gke.1802 NUM_NODES: 9 STATUS: PROVISIONING NAME: auto-east LOCATION: us-east1 MASTER_VERSION: 1.21.5-gke.1802 MASTER_IP: 35.229.88.209 MACHINE_TYPE: e2-medium NODE_VERSION: 1.21.5-gke.1802 NUM_NODES: 3 STATUS: PROVISIONING NAME: std-west LOCATION: us-west1-a MASTER_VERSION: 1.21.5-gke.1802 MASTER_IP: 35.197.93.113 MACHINE_TYPE: e2-medium NODE_VERSION: 1.21.5-gke.1802 NUM_NODES: 6 STATUS: PROVISIONING
すべてのクラスタが RUNNING 状態になったら、
CTRL-C
を押してコマンドを中断します。フリートホスト プロジェクトの MCS サービス アカウントに、自身のプロジェクトのネットワーク ユーザー ロールを付与する Identity and Access Management(IAM)ポリシー バインディングを追加します。
gcloud projects add-iam-policy-binding ${PROJECT} \ --member "serviceAccount:${PROJECT}.svc.id.goog[gke-mcs/gke-mcs-importer]" \ --role "roles/compute.networkViewer"
GKE 用 Workload Identity 連携を使用して、プロジェクトの VPC ネットワーク構成に対する読み取りアクセス権を MCS サービスに付与します。そのため、フリートホスト プロジェクトの MCS インポータ GKE サービス アカウントにはこのロールが必要です。
出力は次のようになります。
- members: - serviceAccount:PROJECT_ID.svc.id.goog[gke-mcs/gke-mcs-importer] role: roles/compute.networkViewer [...]
GKE Standard クラスタと Autopilot クラスタをプロジェクト フリートに登録します。詳細については、クラスタの登録をご覧ください。このステップには最長で 5 分ほどかかります
gcloud container fleet memberships register std-west \ --gke-cluster us-west1-a/std-west \ --enable-workload-identity \ --project=${PROJECT} gcloud container fleet memberships register auto-east \ --gke-cluster us-east1/auto-east \ --enable-workload-identity \ --project=${PROJECT} gcloud container fleet memberships register auto-central \ --gke-cluster us-central1/auto-central \ --enable-workload-identity \ --project=${PROJECT} gcloud container fleet memberships register config-central \ --gke-cluster us-central1/config-central \ --enable-workload-identity \ --project=${PROJECT}
各コマンドの出力は次の例のようになります。
Waiting for membership to be created...done. Created a new membership [projects/PROJECT_ID/locations/global/memberships/std-west] for the cluster [std-west] Generating the Connect Agent manifest... Deploying the Connect Agent on cluster [std-west] in namespace [gke-connect]... Deployed the Connect Agent on cluster [std-west] in namespace [gke-connect]. Finished registering the cluster [std-west] with the Hub.
クラスタに接続して kubeconfig エントリを生成します。
gcloud container clusters get-credentials std-west \ --zone us-west1-a --project $PROJECT gcloud container clusters get-credentials auto-east \ --region us-east1 --project $PROJECT gcloud container clusters get-credentials auto-central \ --region us-central1 --project $PROJECT gcloud container clusters get-credentials config-central \ --region us-central1 --project $PROJECT
各コマンドの出力は次の例のようになります。
Fetching cluster endpoint and auth data. kubeconfig entry generated for std-west.
このドキュメントの以降の部分で作業しやすくなるように、クラスタのコンテキストの名前を変更します。
kubectl config rename-context \ gke_${PROJECT}_us-west1-a_std-west \ std-west kubectl config rename-context \ gke_${PROJECT}_us-east1_auto-east \ auto-east kubectl config rename-context \ gke_${PROJECT}_us-central1_auto-central \ auto-central kubectl config rename-context \ gke_${PROJECT}_us-central1_config-central \ config-central
このガイドでは、コンテキストは場所に基づいて命名されます。代替名を指定することもできますが、このガイドの残りの手順では、この手順で使用されている名前を使用します。
GKE Standard に Online Boutique をデプロイする
デモデプロイの最初のステップでは、Online Boutique アプリケーション サービスの完全なセットを、us-west1 にある単一の GKE Standard クラスタ std-west にデプロイします。
std-west に onlineboutique という名前空間を作成します。
kubectl create namespace onlineboutique --context std-west
出力は次のようになります。
namespace/onlineboutique created
Online Boutique GitHub リポジトリのクローンを作成し、WORKDIR 変数を設定します。
cd ~ git clone --branch release/v0.4.1 \ https://github.com/GoogleCloudPlatform/microservices-demo.git cd microservices-demo/release && export WORKDIR=`pwd`
Online Boutique を std-west にデプロイします。このプロセスでは、Online Boutique のマイクロサービスのすべてに
Deployments
とServices
が作成され、また Online Boutique のフロントエンド サービスを外部に公開する LoadBalancer Service も含まれます。cd $WORKDIR kubectl apply -f kubernetes-manifests.yaml \ -n onlineboutique --context=std-west
LoadBalancer
Service が外部 IP を取得するまで待ちます。watch -n 20 --difference=permanent \ "kubectl get svc frontend-external -n onlineboutique --context=std-west"
最初、出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE frontend-external LoadBalancer 10.60.5.62 <pending> 80:30359/TCP 43s
Service
の準備が整うと、EXTERNAL-IP 列にロードバランサのパブリック IP アドレスが表示されます。Service
の準備ができたら、ロードバランサの外部 IP アドレスを取得し、curl を使用してフロントエンドの準備ができていることを確認します。この curl コマンドでエラーが返ってくる場合は、しばらく待ってからもう一度お試しください。curl $(kubectl get svc frontend-external \ -n onlineboutique --context=std-west \ -o=jsonpath="{.status.loadBalancer.ingress[0].ip}") | \ grep -e Cluster -e Zone -e Pod
curl コマンドの正常な出力は次の例のようになります。
<b>Cluster: </b>std-west<br/> <b>Zone: </b>us-west1-a<br/> <b>Pod: </b>frontend-b7bddcc97-wdjsk
これで、us-west1-a で実行される Online Boutique のシングルゾーン バージョンが作成されました。ウェブブラウザを使用して、frontend-external LoadBalancer
Service に割り当てられた外部 IP に移動し、アプリケーションにアクセスしてその動作を観察することもできます。次の図に、この最初の単一デプロイを示しています。
cartservice をマルチクラスタ サービスとしてエクスポートする
このセクションでは、高可用性の要素をアプリケーションに追加することを開始します。バックエンド cartservice をマルチクラスタ Service として GKE Autopilot クラスタにエクスポートします。
残りのクラスタに onlineboutique という名前空間を作成します。
kubectl create namespace onlineboutique --context auto-east kubectl create namespace onlineboutique --context auto-central kubectl create namespace onlineboutique --context config-central
各コマンドの出力は次の例のようになります。
namespace/onlineboutique created
cartservice を std-west クラスタから
ClusterSet
の他のすべてのクラスタにエクスポートします。ServiceExport
オブジェクトは、名前空間 onlineboutique が存在するフリート内のすべてのクラスタにエクスポートするために、GKE マルチクラスタ Service を使用して cartservice Service を登録します。詳細については、エクスポートするサービスの登録をご覧ください。cat <<EOF>> $WORKDIR/cartservice-export.yaml kind: ServiceExport apiVersion: net.gke.io/v1 metadata: namespace: onlineboutique name: cartservice EOF kubectl apply -f $WORKDIR/cartservice-export.yaml \ -n onlineboutique --context=std-west
マルチクラスタ パターンのアプリケーション マニフェストを適用する
このセクションでは、キュレートされた 2 つのマニフェストを適用して、マルチクラスタ パターンをデプロイします。これらのマニフェストには、以前に std-west クラスタに適用した kubernetes-manifests.yaml の選択された部分が含まれます。
- 最初のマニフェストは frontendの
Deployment
、Service
、ServiceExport
に使用されます。 - 2 番目のマニフェストは、ミドルウェア
Services
(emailservice、checkoutservice、recommendationservice、paymentservice、productcatalogservice、currencyservice、shippingservice、adservice)を、frontend が実行されているすべてのリージョンにデプロイします。リクエストをできるだけリージョンにローカルに保つことで、リージョン間で不要なネットワーク トラフィックが発生することを回避できます。
フリート内の任意のクラスタで実行される Pod
は、そのサービスの ClusterSet
URI に SERVICE_NAME.NAMESPACE.svc.clusterset.local
の形式でリクエストを送信することで、エクスポートされた Service
にアクセスできます。たとえば、3 つのサンプル クラスタの frontend Deployments
は、cartservice.onlineboutique.svc.clusterset.local へリクエスト送信することで、onlineboutique
名前空間で cartservice を使用できます。
このため、各マニフェストでは cartservice のホスト名を ClusterSet
URI に更新しています。この手順は重要です。このサービスのホスト名が更新されていない場合、frontend Service は cartservice.onlineboutique.svc.clusterset.local
ではなく kube-dns を cartservice
にリクエストします。この動作により、ローカル バージョンの cartservice が使用できないクラスタで HTTP Status 500
エラーが発生し、frontend Pod が異常になります。
マニフェストを含む GitHub リポジトリの環境変数を設定します。
export MANIFEST_REPO_PATH=https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/cluster-migration
マニフェストを適用して、3 つのワークロード クラスタすべてにフロントエンド レイヤをデプロイします。
kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-frontend-manifests.yaml \ -n onlineboutique --context=std-west kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-frontend-manifests.yaml \ -n onlineboutique --context=auto-east kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-frontend-manifests.yaml \ -n onlineboutique --context=auto-central
マニフェストを適用して、3 つのワークロード クラスタすべてにミドルウェア レイヤをデプロイします。
kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-middleware-manifests.yaml \ -n onlineboutique --context=std-west kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-middleware-manifests.yaml \ -n onlineboutique --context=auto-east kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-middleware-manifests.yaml \ -n onlineboutique --context=auto-central
フロントエンドの Deployment
、Service
、ServiceExport
が、クラスタ std-west、auto-east、auto-central で有効になりました。また、各クラスタには、Online Boutique ミドルウェア サービスが実行されています。ただし、次の図に示すように、外部トラフィックは us-west1 の初期クラスタで実行される Service
にのみ引き続きルーティングされます。
マルチクラスタ Gateway を有効にして構成する
このセクションでは、3 つのクラスタすべてにトラフィックをルーティングし、すべてのクラスタのフロントエンド間で外部トラフィックをロード バランシングします。この構成を実現するには、マルチクラスタ Gateway(MCG)を使用します。このドキュメントでは、マルチクラスタ Gateway の有効化の説明に沿って MCG を設定する手順を説明します。
このガイドでは、config-central クラスタを使用して Gateway リソースの構成をホストします。
すべてのクラスタが正常にフリートに登録されたことを確認します。
gcloud container fleet memberships list --project=$PROJECT
次の出力例は、すべてのクラスタが正常に登録されたことを示しています。
NAME: auto-central EXTERNAL_ID: 21537493-32ea-4a41-990d-02be2c1b319f NAME: config-central EXTERNAL_ID: 4369423e-ea7b-482d-a0eb-93b560e67b98 NAME: std-west EXTERNAL_ID: 7fcb048b-c796-476b-9698-001a00f91ab3 NAME: auto-east EXTERNAL_ID: aae2d2ff-b861-4a38-bcaf-612f14810012
config-central クラスタに Gateway API カスタム リソース定義をインストールします。
kubectl --context=config-central kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.5.0" \ | kubectl apply -f -
この手順では、
GatewayClass
リソース、Gateway
リソース、HTTPRoute
リソースなどの Gateway API カスタム リソースの定義をインストールします。カスタム リソースの定義は、Kubernetes Network Special Interest Group によって管理されています。インストールが完了すると、GKE Gateway Controller を使用できます。フリートのマルチクラスタ Ingress をまだ有効にしていない場合は、有効にします。この機能を有効にすると、マルチクラスタ Gateway コントローラも有効になります。
gcloud container fleet ingress enable \ --config-membership=config-central \ --project=$PROJECT gcloud container fleet ingress describe --project=$PROJECT
出力は次のようになります。
createTime: '2021-12-08T23:10:52.505888854Z' name: projects/PROJECT_ID/locations/global/features/multiclusteringress resourceState: state: ACTIVE spec: multiclusteringress: configMembership: projects/zl-mcs-expf61cbd13/locations/global/memberships/config-central state: state: code: OK description: Ready to use updateTime: '2021-12-08T23:11:37.994971649Z' updateTime: '2021-12-08T23:11:38.098244178Z'
state の値が ACTIVE でない場合は、マルチクラスタ Ingress のトラブルシューティングとオペレーションをご覧ください。
GatewayClasses
が config-central クラスタで利用可能なことを確認します。kubectl get gatewayclasses --context=config-central
出力は次のようになります。
NAME CONTROLLER AGE gke-l7-global-external-managed networking.gke.io/gateway 18s gke-l7-global-external-managed-mc networking.gke.io/gateway 19s gke-l7-regional-external-managed networking.gke.io/gateway 18s gke-l7-regional-external-managed-mc networking.gke.io/gateway 19s gke-l7-gxlb networking.gke.io/gateway 74s gke-l7-gxlb-mc networking.gke.io/gateway 16s gke-l7-rilb networking.gke.io/gateway 74s gke-l7-rilb-mc networking.gke.io/gateway 16s
GatewayClass
リソースによって機能が異なります。どのタイプをいつ使用するかについては、GatewayClass の機能をご覧ください。external-http
Gateway リソースをconfig-central
にデプロイします。cat <<EOF>> $WORKDIR/external-http-gateway.yaml kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http namespace: onlineboutique spec: gatewayClassName: gke-l7-global-external-managed-mc listeners: - protocol: HTTP port: 80 name: http EOF kubectl apply -f external-http-gateway.yaml \ -n onlineboutique --context=config-central
gatewayClassName
フィールドで示されているように、このリソースはGatewayClass
が gke-l7-global-external-managed-mc で、レイヤ 7 外部 Cloud Load Balancing を管理し、マルチクラスタ アプリケーションを公開します。config-central に public-frontend-route という名前の
HTTPRoute
をデプロイします。cat <<EOF>> $WORKDIR/public-frontend-route.yaml kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: public-frontend-route namespace: onlineboutique spec: parentRefs: - name: "external-http" hostnames: - "store.example.com" rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: frontend group: net.gke.io kind: ServiceImport port: 80 EOF kubectl apply -f public-frontend-route.yaml \ -n onlineboutique --context=config-central
デプロイされた
HTTPRoute
リソースは外部レイヤ 7 Cloud Load Balancing リソースを作成し、std-west、auto-east、auto-central クラスタで実行中のフロントエンド サービスにより、フロントエンドServiceImport
を公開します。次の図は、マルチクラスタ Gateway がデプロイされた後に、3 つのアプリケーション クラスタのいずれかのフロントエンド マルチクラスタ Service のいずれかにトラフィックをルーティングする方法を示しています。
プロビジョニングされた外部 IP アドレスがロードバランサで使用できる状態になるまで待ってから、次のステップに進みます。IP アドレスが割り振られるまで 10 分ほどかかることがあります。ウォッチループを使用して進行状況をモニタリングできます。ロードバランサには、gkemcg-onlineboutique-external-http-k09mfhk74gop のようなパターンの名前が付いています。
watch -n 20 --difference=permanent \ "gcloud compute forwarding-rules list \ | grep -A 5 NAME..*external-http"
出力は次のようになります。
NAME: gkemcg-onlineboutique-external-http-k09mfhk74gop REGION: IP_ADDRESS: 34.149.29.176 IP_PROTOCOL: TCP TARGET: gkemcg-onlineboutique-external-http-k09mfhk74gop
ロードバランサの準備が完了したら、Cloud Shell で次のコマンドを実行して、external-http-gateway.yaml と public-frontend-route.yaml マニフェストを適用して作成したロードバランサの外部 IP アドレスをエクスポートします。
export EXTERNAL_LB_IP=$(kubectl --context=config-central \ -n onlineboutique get gateway external-http \ -o=jsonpath='{.status.addresses[0].value}')
適切なヘッダーを使用してロードバランサにリクエストを送信すると、フロントエンド サービスによって配信される HTML コンテンツが返されます。たとえば、
store.example.com
ホスト名をフロントエンドのServiceImport
にマッピングするようにHTTPRoute
リソースを構成したため、HTTP リクエストを送信する場合はHOST
ヘッダーを指定する必要があります。次の curl の例でエラーが返ってくる場合は、数分待ってからもう一度お試しください。curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \ grep -e Cluster -e Zone -e Pod
curl コマンドの正常な出力は次の例のようになります。
<b>Cluster: </b>auto-central<br/> <b>Zone: </b>us-central1-f<br/> <b>Pod: </b>frontend-7c7d596ddc-jdh8f
アプリケーションのマルチリージョン ルーティング動作をテストする
マルチクラスタ サービスとマルチクラスタ Gateway を使用して得られる優れた機能の一つは、外部リクエストが地理的に最も近いクラスタにルーティングされることです。
アプリケーションのマルチリージョンの動作をテストするには、クラスタをデプロイしたさまざまなリージョンから発信されるトラフィックを生成します。サービス提供クラスタ(std-west、auto-east、auto-central)のそれぞれに 1 つずつ、3 つの小規模な Pod を作成し、HTTP リクエストをロードバランサ エンドポイントに送信するために使用できます。結果では、どのフロントエンド Pod
が応答するかを確認できます。
クライアント Pod を作成します。
kubectl run --context=std-west \ --image=radial/busyboxplus:curl client-west \ -- sh -c 'while sleep 3600; do :; done' kubectl run --context=auto-east \ --image=radial/busyboxplus:curl client-east \ -- sh -c 'while sleep 3600; do :; done' kubectl run --context=auto-central \ --image=radial/busyboxplus:curl client-central \ -- sh -c 'while sleep 3600; do :; done'
Pod が使用可能になったら、curl コマンドを使用して、std-west クラスタのクライアント
Pod
からロードバランサ エンドポイントにリクエストを送信し、レスポンスを確認します。kubectl exec -it --context=std-west client-west \ -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \ grep -e Cluster -e Zone -e Pod
curl コマンドの正常な出力は次の例のようになります。
<b>Cluster: </b>std-west<br/> <b>Zone: </b>us-west1-a<br/> <b>Pod: </b>frontend-7cf48b79cf-trzc4
auto-east クラスタのクライアント
Pod
から同じ curl リクエストを実行し、レスポンスを確認します。kubectl exec -it --context=auto-east client-east \ -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \ grep -e Cluster -e Zone -e Pod
curl コマンドの正常な出力は次の例のようになります。
<b>Cluster: </b>auto-east<br/> <b>Zone: </b>us-east1-d<br/> <b>Pod: </b>frontend-6784b6df98-scdws
これは Autopilot クラスタであるため、
Pod
をスケジュールするために、クラスタで追加のリソースのプロビジョニングが必要になることがあります。次の例のような出力が表示された場合は、しばらく待ってから再試行してください。Error from server (BadRequest): pod client-east does not have a host assigned
auto-central クラスタのクライアント
Pod
から curl を実行し、レスポンスを確認します。kubectl exec -it --context=auto-central client-central \ -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \ grep -e Cluster -e Zone -e Pod
curl コマンドの正常な出力は次の例のようになります。
<b>Cluster: </b>auto-central<br/> <b>Zone: </b>us-central1-b<br/> <b>Pod: </b>frontend-6784b6df98-x2fv4
この結果により、トラフィックがリクエスト元に最も近いロケーションの対応する Pod にルーティングされることが確認できます。
アプリケーションのマルチリージョンの復元性をテストする
効率的なトラフィック ルーティングに加えて、複数のリージョンでサービスを実行すると、発生する可能性は低いが依然として発生する可能性はあるインフラストラクチャ障害の復元力を高めることができます。
特定のクラスタで frontend Deployments
を削除して動作をテストしてから、そのリージョンのクライアント Pod
から curl コマンドを再試行します。アプリケーションがまだ使用可能であることを確認し、リクエストに応答する Pod
のロケーションを確認します。
std-west クラスタの client-west
Pod
から curl コマンドを実行し、結果が us-west1 のフロントエンドから届いたものであることを確認します。kubectl exec -it --context=std-west client-west \ -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \ grep -e Cluster -e Zone -e Pod
curl コマンドの正常な出力は次の例のようになります。
<b>Cluster: </b>std-west<br/> <b>Zone: </b>us-west1-a<br/> <b>Pod: </b>frontend-7cf48b79cf-trzc4
std-west クラスタの frontend
Deployment
を削除します。kubectl delete deploy frontend \ -n onlineboutique --context=std-west
出力は次のようになります。
deployment.apps "frontend" deleted
std-west クラスタの client-west
Pod
から別のリクエストを送信します。auto-east クラスタか auto-central クラスタにある残りの frontendDeployments
のうちの 1 つからレスポンスが届くはずです。kubectl exec -it --context=std-west client-west \ -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \ grep -e Cluster -e Zone -e Pod
次の例のような出力は、このリクエストに応答する正常な
Pod
のロケーションを示しています。<b>Cluster: </b>auto-central<br/> <b>Zone: </b>us-central1-b<br/> <b>Pod: </b>frontend-6784b6df98-x2fv4
または
<b>Cluster: </b>auto-east<br/> <b>Zone: </b>us-east1-d<br/> <b>Pod: </b>frontend-6784b6df98-scdws
このコマンドを数回実行して、結果が交互に変わるのを確認します。
このデモデプロイでは、マルチクラスタ Service とマルチクラスタ Gateway を使用して、Online Boutique アプリケーションに復元力と地理的分散の要素を追加しています。リクエストは地理的に最も近いリージョンにルーティングされ、あるリージョンのフロントエンドやミドルウェア サービスで障害が発生しても、エンドユーザーはアプリケーションを正常に使用できます。
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
次のステップ
- Google Cloud フリートとマルチクラスタ管理の詳細を確認する。
- GKE Enterprise クラスタなど、クラスタを Google Cloud フリートに登録する方法について学習する。
- Kubernetes Gateway API と GKE Gateway の詳細を確認する。
- Google Cloud に関するリファレンス アーキテクチャ、図、ベスト プラクティスを確認する。Cloud アーキテクチャ センターをご覧ください。