Google Kubernetes Engine(GKE)Autopilot クラスタと Standard クラスタを使用して、マルチクラスタ ネットワーキングに移行する

Last reviewed 2022-02-17 UTC

マルチクラスタ ネットワーキングは、リージョンごとの可用性を高める、レイテンシを短縮するためにグローバルに分散されたユーザーに接近する、チーム間で組織を分離する、などのユースケースを可能にする貴重なツールです。Google Kubernetes Engine(GKE)にはマルチクラスタ ネットワーキングの機能が組み込まれており、GKE クラスタのフリート全体で有効にして大規模に使用できます。この機能を使用すると、GKE Standard と Autopilot 間でデプロイされたインフラストラクチャの結合や移行を行って、各アプリケーションのアーキテクチャ ニーズに対応することもできます。

GKE Autopilot クラスタでは、Google がコントロール プレーンやノードなどのインフラストラクチャを管理します。代わりにノードを構成および管理する場合、GKE にはStandard モードが用意されています。モードの違いについては、クラスタ運用モードの選択をご覧ください。

このページでは、いくつかのデプロイ トポロジを通じてこれらの機能について説明します。1 つの GKE クラスタにデプロイされたアプリケーションを、GKE Standard クラスタと Autopilot クラスタ間のマルチクラスタ デプロイに移行する方法について学習します。East-West トラフィックには GKE マルチクラスタ サービスを使用し、North-South マルチクラスタ ネットワーキングを有効にするにはマルチクラスタ Gateway を使用します。

このページは、複数の Kubernetes クラスタにサービスをデプロイするために GKE を使用する、または使用することを計画するクラウド アーキテクトと運用チームを対象としています。このページを読む前に、Kubernetes について理解しておいてください。

マルチクラスタ 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 を組み合わせる場合に、サービスのデプロイとトラフィック ルーティングの補完的な側面を単一のコントロール プレーンから管理する方法を示しています。

マルチクラスタ サービスは、クラスタ内のサービス間の通信を容易にします。マルチクラスタ ゲートウェイでは、クラスタ間でトラフィックをルーティングするためにロードバランサをデプロイします。

詳細については、マルチクラスタ ゲートウェイのデプロイをご覧ください。

移行の概要

GKE のマルチクラスタ ネットワーク機能には、さまざまなプロファイルのワークロードに対するメリットがあります。たとえば、トラフィックが急増しているステートレス コンポーネントで、より効率的なコストモデルを実現するために Autopilot に移行することが必要な場合があります。

また、アプリケーションのフロントエンドをユーザーの近くに配置したいと考える場合もあります。このアプローチは、レイテンシを短縮しキャッシュ保存を行うことで、アプリケーションのパフォーマンスとユーザー エクスペリエンスを改善します。また、1 つのロケーションにしか存在できないステートフル コンポーネントにアプリケーションが依存している場合があります。このような構成で、クライアント トラフィックをそのロケーションにある適切なクラスタに送信するには North-South マルチクラスタ負荷分散が必要になります。また、クラスタ間でトラフィックを送信してそのステートフル コンポーネントに到達させるには、East-West マルチクラスタ負荷分散も必要です。

このページでは、Online Boutique のクラウド マイクロサービスのデモ アプリケーションを使用して、シングルゾーン デモのデプロイを強化するために使用できるマルチクラスタ パターンについて説明します。アプリケーションのシングルゾーン バージョンから始めます。さらに、マルチクラスタ Service とマルチクラスタ ゲートウェイを使用して高可用性と復元性の要素を追加し、Autopilot を活用して運用作業を軽減します。

単一クラスタの最初のデプロイ

次の図では、Online Boutique アプリケーションは、最初に std-west という名前の単一の GKE 標準モードクラスタにデプロイされ、LoadBalancer Service を使用して公開されます。

通常の HTTP 外部 LoadBalancer Service により公開されたすべてのサービスを実行する単一の標準モードの GKE クラスタ。

マルチクラスタ Service への移行

次の中間ステップでは、2 つの追加クラスタを作成し、ステートレス サービスを追加のリージョンにデプロイします。単一の std-west GKE Standard クラスタとは別の 2 つの個別のリージョンに auto-eastauto-central という名前の 2 つの GKE Autopilot クラスタを作成し、そのクラスタを Google Cloud フリートに登録します。

フリートとは、複数のクラスタと他のリソースを論理的に編成するための Google Cloud のコンセプトで、フリートを使用することによって、マルチクラスタ機能の使用と管理、複数のシステム間での一貫したポリシーの適用が可能になります。

ServiceExport を使用して、onlineboutique 名前空間内の std-west クラスタの cartservice を新しいフリート クラスタにエクスポートします。Online Boutique の frontend Service を 3 つのクラスタすべてにデプロイし、ClusterIP サービスを介して公開します。次に、ServiceExports を使用してサービスをフリートにエクスポートします。Online Boutique のミドルウェア レイヤなどのサービス(productcatalogshippingadservice など)も、3 つのクラスタすべてにデプロイされます。

フリート内の任意のクラスタで実行される Pod は、そのサービスの ClusterSet URI にリクエストを送信することで、エクスポートされた Service にアクセスできます。リクエストは、サービスをバックアップするエンドポイントに転送されます。

フロントエンド サービスは、ミドルウェア サービス(productcatalogservice や currencyservice など)を同じクラスタ内でローカルに利用できます。このアーキテクチャは、受信リクエストをフロントエンドがリクエストに応答するリージョンにローカルに維持し、不要なリージョン間ネットワーク トラフィック課金を回避します。

次の図は、2 つのマルチクラスタ サービスを示しています。ステートレス フロントエンド サービスが 3 つのクラスタにデプロイされ、ステートフル バックエンド カートサービスが 1 つのクラスタにデプロイされます。また、この中間ステップでは、フロントエンドの外部 LoadBalancer サービスによって作成された外部パススルー ネットワーク ロードバランサを使用して、フロントエンド サービスの受信トラフィックが引き続き us-west1 の元の GKE Standard クラスタにルーティングされることを示しています。

マルチクラスタ サービスは 3 つの GKE クラスタで実行されますが、トラフィックは通常の HTTP 外部ロードバランサ サービスで単一のクラスタに転送されます。

マルチクラスタ ゲートウェイへの移行

最後のステップでは、マルチクラスタ Gateway を使用して、frontend Service のインバウンド トラフィックを外部クライアント リクエストからフリート内の複数のクラスタのサービスにルーティングします。

この構成の一部として作成される GatewayHTTPRoute リソースの構成をホストして管理するために、config-central という名前の 4 番目のクラスタがフリートに追加されます。HTTPRoute リソースは、/ 接頭辞をフロントエンドの ServiceImport にマッピングします。Online Boutique のフロントエンドのトラフィックは、使用可能ないずれかのリージョンの正常なエンドポイントに送信されます。このアプローチにより、Online Boutique アプリケーション アーキテクチャに高可用性の要素が追加されます。

次の図では、マルチクラスタ ゲートウェイがグローバル クラウド ロードバランサをデプロイしています。このロードバランサは、フリート内の 3 つのアプリケーション クラスタそれぞれにデプロイされたステートレス フロントエンド サービスに外部トラフィックをルーティングします。

マルチクラスタ Service は 3 つの GKE クラスタで実行され、トラフィックはマルチクラスタの外部ゲートウェイを使用してすべてのクラスタのフロントエンド サービスに分散されます。

最終状態では、この独自のパターンは、アプリケーションのステートフル部分(cartservice と redis-cart)とステートレス部分(frontend、emailservice、checkoutservice、recommendationservice、paymentservice、productcatalogservice、currencyservice、shippingservice、adservice)の間の緩い結合を示しています。このページの範囲外ですが、このアプローチにより、復元力と高可用性をステートフル サービスレイヤに追加できるようになります。

目標

  • GKE Standard クラスタと Autopilot クラスタを作成して構成する。
  • Online Boutique をゾーン GKE 標準クラスタにデプロイする。
  • マルチクラスタ Services をエクスポートする。
  • マニフェストを Standard クラスタと Autopilot クラスタにデプロイする。
  • マルチクラスタ ゲートウェイを有効にして構成する。
  • マルチリージョン アプリケーションの動作をテストする。

費用

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい 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 コンソールの下部にウィンドウとして表示されます。初期化が完了するまでに数分かかることもありますが、ウィンドウはすぐに表示されます。

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

  2. Cloud Shell で、このガイドで使用される環境変数を定義します。PROJECT_ID は実際のプロジェクト ID に置き換えます。

    export PROJECT=PROJECT_ID
    gcloud config set project ${PROJECT}
    
  3. このページの手順に必要なサービスを有効にします。

    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.
    
  4. マルチクラスタ 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 でない場合は、マルチクラスタ サービスのトラブルシューティングの詳細をご覧ください。

GKE クラスタを作成して構成する

マルチクラスタ パターンを示すために、3 つの独立したクラウド リージョンの 3 つのアプリケーション クラスタと、ゲートウェイ リソースの構成をホストする 1 つのクラスタを使用します。プロジェクトに関連付けられたフリートにすべてのクラスタを登録します。Google クラウド プロジェクトには 1 つのフリートのみを関連付けることができます。このプロジェクトは、フリート ホスト プロジェクトと呼ばれます。

  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 フラグを使用する必要はありません。

  2. クラスタの STATUSPROVISIONING から RUNNING に変わるまで待ちます。この処理には 10 分ほどかかることがあります。ウォッチループを使用して進行状況をモニタリングできます。

    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
    
  3. すべてのクラスタが RUNNING 状態になったら、CTRL-C を押してコマンドを中断します。

  4. フリートホスト プロジェクトの 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
    [...]
    
  5. 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.
    
  6. クラスタに接続して 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.
    
  7. このページの残りの部分で作業しやすくなるように、クラスタのコンテキストの名前を変更します。

    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 標準クラスタ std-west にデプロイします。

  1. std-west に onlineboutique という名前空間を作成します。

    kubectl create namespace onlineboutique --context std-west
    

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

    namespace/onlineboutique created
    
  2. 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`
    
  3. Online Boutique を std-west にデプロイします。このプロセスでは、Online Boutique のマイクロサービスのすべてに DeploymentsServices が作成され、また Online Boutique のフロントエンド サービスを外部に公開する LoadBalancer Service も含まれます。

    cd $WORKDIR
    
    kubectl apply -f kubernetes-manifests.yaml \
        -n onlineboutique --context=std-west
    
  4. 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 アドレスが表示されます。

  5. 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 に移動し、アプリケーションにアクセスしてその動作を観察することもできます。次の図に、この最初の単一デプロイを示しています。

通常の HTTP 外部 LoadBalancer サービスにより公開されたすべてのサービスを実行する単一の Standard モードの GKE クラスタ。

カートサービスをマルチクラスタ サービスとしてエクスポートする

このセクションでは、高可用性の要素をアプリケーションに追加することを開始します。バックエンド cartservice をマルチクラスタ Service として GKE Autopilot クラスタにエクスポートします。

  1. 残りのクラスタに 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
    
  2. 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 の選択された部分が含まれます。

  • 最初のマニフェストはフロントエンドDeploymentServiceServiceExport に使用されます。
  • 2 番目のマニフェストは、ミドルウェア Services(emailservice、checkoutservice、recommendationservice、paymentservice、productcatalogservice、currencyservice、shippingservice、adservice)を、フロントエンドが実行されているすべてのリージョンにデプロイします。リクエストをできるだけリージョンにローカルに保つことで、リージョン間で不要なネットワーク トラフィックが発生することを回避できます。

フリート内の任意のクラスタで実行される Pod は、そのサービスの ClusterSet URI に SERVICE_NAME.NAMESPACE.svc.clusterset.local の形式でリクエストを送信することで、エクスポートされた Service にアクセスできます。たとえば、3 つのサンプル クラスタのフロントエンド Deploymentsは、cartservice.onlineboutique.svc.clusterset.local へリクエスト送信することで、onlineboutique 名前空間で cartservice を使用できます。

このため、各マニフェストでは cartservice のホスト名を ClusterSet URI に更新しています。ですから、この演習は大変重要です。このサービスのホスト名が更新されていない場合、frontend サービスは cartservice.onlineboutique.svc.clusterset.local ではなく kube-dns を cartservice にリクエストします。この動作により、ローカル バージョンの cartservice が使用できないクラスタで HTTP Status 500 エラーが発生し、frontend ポッドが異常になります。

  1. マニフェストを含む GitHub リポジトリの環境変数を設定します。

    export MANIFEST_REPO_PATH=https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/cluster-migration
    
  2. マニフェストを適用して、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. マニフェストを適用して、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
    

フロントエンドの DeploymentServiceServiceExportが、クラスタ std-westauto-eastauto-central で有効になりました。また、各クラスタには、Online Boutique ミドルウェア サービスが実行されています。ただし、次の図に示すように、外部トラフィックは us-west1 の初期クラスタで実行される Service にのみ引き続きルーティングされます。

マルチクラスタ サービスは 3 つの GKE クラスタで実行されますが、トラフィックは通常の HTTP 外部ロードバランサ サービスで単一のクラスタに転送されます。

マルチクラスタ ゲートウェイを有効にして構成する

このセクションでは、3 つのクラスタすべてにトラフィックをルーティングし、すべてのクラスタのフロントエンド間で外部トラフィックをロードバランシングします。この構成を実現するには、マルチクラスタ Gateway(MCG)を使用します。MCG を設定する手順は、マルチクラスタ Gateway の有効化で詳しく説明されているガイダンスに沿っています。

次の手順では、config-central クラスタを使用して Gateway リソースの構成をホストします。

  1. すべてのクラスタが正常にフリートに登録されたことを確認します。

    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
    
  2. 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 を使用できます。

  3. フリートのマルチクラスタ 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 のトラブルシューティングとオペレーションをご覧ください。

  4. 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 の機能をご覧ください。

  5. 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 フィールドで示されているように、このリソースは GatewayClassgke-l7-global-external-managed-mc で、レイヤ 7 外部 Cloud Load Balancing を管理し、マルチクラスタ アプリケーションを公開します。

  6. 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 のいずれかにトラフィックをルーティングする方法を示しています。

    マルチクラスタ Service は 3 つの GKE クラスタで実行され、トラフィックはマルチクラスタの外部ゲートウェイを使用してすべてのクラスタのフロントエンド サービスに分散されます。

  7. プロビジョニングされた外部 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
    
  8. ロードバランサの準備が完了したら、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}')
    
  9. 適切なヘッダーを使用してロードバランサにリクエストを送信すると、フロントエンド サービスによって配信される 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
    

アプリケーションのマルチリージョン ルーティング動作をテストする

マルチクラスタ サービスとマルチクラスタ ゲートウェイを使用して得られる強力な機能の 1 つは、外部リクエストが地理的に最も近いクラスタにルーティングされることです。

アプリケーションのマルチリージョンの動作をテストするには、クラスタをデプロイしたさまざまなリージョンから発信されるトラフィックを生成します。サービス提供クラスタ(std-westauto-eastauto-central)のそれぞれに 1 つずつ、3 つ小規模な Pod を作成し、HTTP リクエストをロードバランサ エンドポイントに送信するために使用できます。結果では、どのフロントエンド Pod が応答するかを確認できます。

  1. クライアント 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'
    
  2. 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
    
  3. 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
    
  4. 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 にルーティングされることが確認できます。

アプリケーションのマルチリージョンの復元性をテストする

効率的なトラフィック ルーティングに加えて、複数のリージョンでサービスを実行すると、発生する可能性は低いが依然として発生する可能性はあるインフラストラクチャ障害の復元力を高めることができます。

特定のクラスタでフロントエンド Deployments を削除して動作をテストしてから、そのリージョンのクライアント Pod から curl コマンドを再試行します。アプリケーションがまだ使用可能であることを確認し、リクエストに応答する Pod のロケーションを確認します。

  1. 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
    
  2. std-west クラスタの frontend Deployment を削除します。

    kubectl delete deploy frontend \
        -n onlineboutique --context=std-west
    

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

    deployment.apps "frontend" deleted
    
  3. std-west クラスタの client-west Pod から別のリクエストを送信します。auto-east クラスタか auto-central クラスタにある残りのフロントエンド Deployments のうちの 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 とマルチクラスタ ゲートウェイを使用して、Online Boutique アプリケーションに復元力と地理的分散の要素を追加しています。リクエストは地理的に最も近いリージョンにルーティングされ、あるリージョンのフロントエンドやミドルウェア サービスで障害が発生しても、エンドユーザーはアプリケーションを正常に使用できます。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

次のステップ