Anthos Service Mesh を使用した GKE 限定公開クラスタでの分散サービスの実行

Last reviewed 2021-07-12 UTC

このドキュメントでは、Anthos Service Mesh を使用して、Google Cloud の複数の Google Kubernetes Engine(GKE)クラスタで分散サービスを実行する方法について説明します。また、マルチクラスタ Ingress と Anthos Service Mesh を使用して分散サービスを公開する方法についても説明します。このドキュメントを使用して、非限定公開 GKE クラスタを構成できます。このドキュメントでは、限定公開クラスタを念頭に置いた構成について説明します。

このドキュメントは、Kubernetes の基本的な知識を持つプラットフォーム管理者とサービス オペレータを対象としています。必須ではありませんが、サービス メッシュに関する知識は約に立ちます。Anthos Service Mesh は、オープンソースの Istio テクノロジーをベースとしています。サービス メッシュと Istio の詳細については、istio.io をご覧ください。

分散サービスは、単一の論理サービスとして機能する Kubernetes Service です。分散 Service は、同じ Namespace 内の複数の Kubernetes クラスタで実行されるため、Kubernetes サービスよりも復元力があります。正常なクラスタが目的の負荷を処理できる限り、1 つ以上の GKE クラスタが停止しても、分散サービスは引き続き機能します。

Kubernetes Services が認識するのは、実行するクラスタの Kubernetes API サーバーのみです。Kubernetes クラスタがダウンしている場合(定期メンテナンス中など)、そのクラスタ上で実行されているすべての Kubernetes Services もダウンします。分散サービスを実行すると、他のクラスタがトラフィックを処理している間に、メンテナンスやアップグレードのためにクラスタを止めることができます。分散サービスを作成するために、Anthos Service Mesh が提供するサービス メッシュ機能を使用して、複数のクラスタで実行中のサービスをリンクし、1 つの論理サービスとして機能させることができます。

GKE 限定公開クラスタを使用すると、Virtual Private Cloud(VPC)ネットワーク上でのみ利用可能なプライベート リソースとしてノードと API サーバーを構成できます。GKE 限定公開クラスタで分散サービスを実行すると、企業に安全で信頼性の高いサービスが提供されます。

アーキテクチャ

このチュートリアルでは、次の図に示すアーキテクチャを使用します。

Anthos Service Mesh を使用した GKE 限定公開クラスタ上の分散サービスのアーキテクチャ

上図では、アーキテクチャに次のクラスタが含まれています。

  • 2 つのクラスタ(gke-central-privgke-west-priv)は、2 つの異なるリージョンで同じ GKE 限定公開クラスタとして機能します。
  • 別のクラスタ(ingress-config)は、マルチクラスタ Ingress を構成するコントロール プレーン クラスタとして機能します。

このチュートリアルでは、2 つの GKE 限定公開クラスタ(gke-central-privgke-west-priv)に Bank of Anthos のサンプル アプリケーションをデプロイします。Bank of Anthos は、オンライン バンキング アプリをシミュレートする複数のマイクロサービスと SQL データベースで構成されるサンプル マイクロサービス アプリケーションです。このアプリケーションは、クライアントがアクセスできるウェブ フロントエンドと、銀行をシミュレートする残高、台帳、アカウント サービスなどの複数のバックエンド サービスで構成されます。

アプリケーションには、StatefulSet として Kubernetes にインストールされる 2 つの PostgreSQL データベースが含まれています。1 つのデータベースはトランザクションに使用され、もう 1 つのデータベースはユーザー アカウントに使用されます。この 2 つのデータベースを除くすべてのサービスは分散サービスとして実行されます。つまり、すべてのサービスの Pod が同じ名前空間内の両方のアプリケーション クラスタ内で実行され、各サービスが 1 つの論理サービスとして表示されるように Anthos Service Mesh が構成されます。

目標

  • 3 つの GKE クラスタを作成します。
  • GKE クラスタのうち 2 つを限定公開クラスタ(gke-central-privgke-west-priv)として構成します。
  • 1 つの GKE クラスタ(ingress-config)を中央構成クラスタとして構成します。 このクラスタは、マルチクラスタ Ingress の構成クラスタとして機能します。
  • クラスタ間のトラフィックと 2 つの限定公開 GKE のクラスタからの下り(外向き)トラフィックを許可するように、ネットワーキング(NAT ゲートウェイ、Cloud Router、ファイアウォール ルール)を構成します。
  • Cloud Shell から 2 つの限定公開 GKE クラスタへの API サービスによるアクセスを許可するように、承認済みネットワークを構成します。
  • マルチクラスタの Anthos Service Mesh をマルチプライマリ モードで 2 つの限定公開クラスタにデプロイして構成します。マルチプライマリ モードでは、両方のクラスタに Anthos Service Mesh コントロール プレーンをデプロイします。
  • Bank of Anthos アプリケーションを 2 つの限定公開クラスタにデプロイします。データベース以外のすべてのサービスは、分散サービス(両方の限定公開クラスタで実行されている Pod)としてデプロイされます。
  • Anthos Service Mesh を使用してサービスをモニタリングします。
  • Bank of Anthos の frontend サービスでマルチクラスタ Ingress を構成します。これにより、外部クライアント(ウェブブラウザなど)は、限定公開 GKE クラスタのフリートで実行されている分散サービスにアクセスできます。

料金

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

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

始める前に

  1. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  2. Google Cloud プロジェクトで課金が有効になっていることを確認します

  3. Google Cloud コンソールで、「Cloud Shell をアクティブにする」をクリックします。

    Cloud Shell をアクティブにする

    Google Cloud コンソールの下部で Cloud Shell セッションが開始し、コマンドライン プロンプトが表示されます。Cloud Shell はシェル環境です。Google Cloud CLI がすでにインストールされており、現在のプロジェクトの値もすでに設定されています。セッションが初期化されるまで数秒かかることがあります。

    このチュートリアルでは、Cloud Shell からすべてのコマンドを実行します。

  4. このチュートリアル全体を通して使用する環境変数を定義します。変数は、このチュートリアルで使用するクラスタ名、リージョン、ゾーン、IP アドレス範囲、Anthos Service Mesh バージョンを定義します。

    1. YOUR_PROJECT_ID を、実際のプロジェクト ID に置き換えてください。

      export PROJECT_ID=YOUR_PROJECT_ID
      gcloud config set project ${PROJECT_ID}
      
    2. 残りの環境変数を設定します。

      export PROJECT_NUM=$(gcloud projects describe ${PROJECT_ID} --format='value(projectNumber)')
      export CLUSTER_1=gke-west-priv
      export CLUSTER_2=gke-central-priv
      export CLUSTER_1_ZONE=us-west2-a
      export CLUSTER_1_REGION=us-west2
      export CLUSTER_1_MASTER_IPV4_CIDR=172.16.0.0/28
      export CLUSTER_2_ZONE=us-central1-a
      export CLUSTER_2_REGION=us-central1
      export CLUSTER_2_MASTER_IPV4_CIDR=172.16.1.0/28
      export CLUSTER_INGRESS=gke-ingress
      export CLUSTER_INGRESS_ZONE=us-west1-a
      export CLUSTER_INGRESS_REGION=us-west1
      export CLUSTER_INGRESS_MASTER_IPV4_CIDR=172.16.2.0/28
      export WORKLOAD_POOL=${PROJECT_ID}.svc.id.goog
      export MESH_ID="proj-${PROJECT_NUM}"
      export ASM_VERSION=1.10
      export CLOUDSHELL_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
      

環境の設定

  1. Cloud Shell で API を有効にします。

    gcloud services enable \
      --project=${PROJECT_ID} \
      container.googleapis.com \
      mesh.googleapis.com \
      gkehub.googleapis.com
    
  2. プロジェクトで Anthos Service Mesh Fleet を有効にします。

    gcloud container fleet mesh enable --project=${PROJECT_ID}
    

限定公開 GKE クラスタ用のネットワーキングの準備

このセクションでは、分散サービスの実行に使用する限定公開 GKE クラスタ用にネットワーキングを準備します。

限定公開 GKE クラスタノードには、パブリック IP アドレスが割り当てられません。限定公開 GKE クラスタ内のすべてのノードには、プライベート VPC IP アドレス(RFC 1918 アドレス空間)が割り当てられます。つまり、外部リソース(VPC ネットワーク外)にアクセスする必要がある Pod には Cloud NAT ゲートウェイが必要となります。Cloud NAT ゲートウェイは、内部 IP アドレスを持つ Pod がインターネットと通信できるようにするリージョン NAT ゲートウェイです。このチュートリアルでは、2 つの各リージョンに Cloud NAT ゲートウェイを構成します。リージョン内の複数のクラスタが同じ NAT ゲートウェイを使用できます。

  1. Cloud Shell で、2 つの NAT ゲートウェイ用に 2 つの外部 IP アドレスを作成して予約します。

    gcloud compute addresses create ${CLUSTER_1_REGION}-nat-ip \
      --project=${PROJECT_ID} \
      --region=${CLUSTER_1_REGION}
    
    gcloud compute addresses create ${CLUSTER_2_REGION}-nat-ip \
      --project=${PROJECT_ID} \
      --region=${CLUSTER_2_REGION}
    
  2. IP アドレスと IP アドレスの名前を変数に保存します。

    export NAT_REGION_1_IP_ADDR=$(gcloud compute addresses describe ${CLUSTER_1_REGION}-nat-ip \
      --project=${PROJECT_ID} \
      --region=${CLUSTER_1_REGION} \
      --format='value(address)')
    
    export NAT_REGION_1_IP_NAME=$(gcloud compute addresses describe ${CLUSTER_1_REGION}-nat-ip \
      --project=${PROJECT_ID} \
      --region=${CLUSTER_1_REGION} \
      --format='value(name)')
    
    export NAT_REGION_2_IP_ADDR=$(gcloud compute addresses describe ${CLUSTER_2_REGION}-nat-ip \
      --project=${PROJECT_ID} \
      --region=${CLUSTER_2_REGION} \
      --format='value(address)')
    
    export NAT_REGION_2_IP_NAME=$(gcloud compute addresses describe ${CLUSTER_2_REGION}-nat-ip \
      --project=${PROJECT_ID} \
      --region=${CLUSTER_2_REGION} \
      --format='value(name)')
    
  3. 限定公開 GKE クラスタの 2 つのリージョンに Cloud NAT ゲートウェイを作成します。

    gcloud compute routers create rtr-${CLUSTER_1_REGION} \
      --network=default \
      --region ${CLUSTER_1_REGION}
    
    gcloud compute routers nats create nat-gw-${CLUSTER_1_REGION} \
      --router=rtr-${CLUSTER_1_REGION} \
      --region ${CLUSTER_1_REGION} \
      --nat-external-ip-pool=${NAT_REGION_1_IP_NAME} \
      --nat-all-subnet-ip-ranges \
      --enable-logging
    
    gcloud compute routers create rtr-${CLUSTER_2_REGION} \
      --network=default \
      --region ${CLUSTER_2_REGION}
    
    gcloud compute routers nats create nat-gw-${CLUSTER_2_REGION} \
      --router=rtr-${CLUSTER_2_REGION} \
      --region ${CLUSTER_2_REGION} \
      --nat-external-ip-pool=${NAT_REGION_2_IP_NAME} \
      --nat-all-subnet-ip-ranges \
      --enable-logging
    
  4. Pod 間の通信と Pod から API サーバーへの通信を可能にするファイアウォール ルールを作成します。Pod 間通信により、分散サービスは GKE クラスタ間で相互に通信できます。Pod から API サーバーへの通信により、Anthos Service Mesh のコントロール プレーンは GKE クラスタに対してサービス ディスカバリのクエリを行います。

    gcloud compute firewall-rules create all-pods-and-master-ipv4-cidrs \
      --project ${PROJECT_ID} \
      --network default \
      --allow all \
      --direction INGRESS \
      --source-ranges 10.0.0.0/8,${CLUSTER_1_MASTER_IPV4_CIDR},${CLUSTER_2_MASTER_IPV4_CIDR},${CLUSTER_INGRESS_MASTER_IPV4_CIDR}
    

これでネットワークの準備が完了しました。このチュートリアルでは、すべての IP 範囲を含む 10.0.0.0/8 IP アドレス範囲全体を使用します。条件と要件に基づいて、本番環境でより厳密なファイアウォール ルールを作成することをおすすめします。

限定公開 GKE クラスタの作成

このセクションでは、サンプルアプリがデプロイされている 2 つの限定公開 GKE クラスタを作成します。このチュートリアルでは、プライベート GKE クラスタノードにプライベート IP アドレスがあり、API サーバーにパブリック エンドポイントがあります。ただし、API サーバーへのアクセスは承認済みネットワークを使用して制限されています。

  1. Cloud Shell で、認可済みネットワークを持つ 2 つの限定公開クラスタを作成します。ターミナルからクラスタにアクセスできるように、(Anthos Service Mesh コントロール プレーンの)Pod IP CIDR 範囲と、Cloud Shell からのアクセスを許可するクラスタを構成します。

    gcloud container clusters create ${CLUSTER_1} \
      --project ${PROJECT_ID} \
      --zone=${CLUSTER_1_ZONE} \
      --machine-type "e2-standard-4" \
      --num-nodes "3" --min-nodes "3" --max-nodes "5" \
      --enable-ip-alias --enable-autoscaling \
      --workload-pool=${WORKLOAD_POOL} \
      --enable-private-nodes \
      --master-ipv4-cidr=${CLUSTER_1_MASTER_IPV4_CIDR} \
      --enable-master-authorized-networks \
      --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32 \
      --labels=mesh_id=${MESH_ID} --async
    
    gcloud container clusters create ${CLUSTER_2} \
      --project ${PROJECT_ID} \
      --zone=${CLUSTER_2_ZONE} \
      --machine-type "e2-standard-4" \
      --num-nodes "3" --min-nodes "3" --max-nodes "5" \
      --enable-ip-alias --enable-autoscaling \
      --workload-pool=${WORKLOAD_POOL} \
      --enable-private-nodes \
      --master-ipv4-cidr=${CLUSTER_2_MASTER_IPV4_CIDR} \
      --enable-master-authorized-networks \
      --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32 \
      --labels=mesh_id=${MESH_ID}
    

    認可済みネットワークには、Cloud NAT ゲートウェイのパブリック IP アドレスが含まれています。限定公開クラスタの API サーバー エンドポイントは、パブリック エンドポイントのため、限定公開クラスタで実行される Pod は、Cloud NAT ゲートウェイを使用してパブリック API サーバー エンドポイントにアクセスする必要があります。

    Cloud Shell の IP アドレスは認可済みネットワークの一部でもあり、Cloud Shell ターミナルからクラスタにアクセスして管理できます。Cloud Shell の一般公開 IP アドレスは動的なアドレスのため、Cloud Shell を起動するたびに、異なるパブリック IP アドレスが取得される場合があります。新しい IP アドレスを取得すると、その新しい IP アドレスは 2 つのクラスタの認可済みネットワークに含まれていないため、クラスタにアクセスできなくなります。

    クラスタにアクセスできなくなった場合は、クラスタの認可済みネットワークを更新して新しい Cloud Shell IP アドレスを追加します。

    1. 更新された Cloud Shell のパブリック IP アドレスを取得します。

      export CLOUDSHELL_IP=$(dig +short myip.opendns.com @resolver1.opendns.com)
      
    2. 2 つのクラスタの認可済みネットワークを更新します。

      gcloud container clusters update ${CLUSTER_1} \
        --zone=${CLUSTER_1_ZONE} \
        --enable-master-authorized-networks \
        --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32
      
      gcloud container clusters update ${CLUSTER_2} \
        --zone=${CLUSTER_2_ZONE} \
        --enable-master-authorized-networks \
        --master-authorized-networks $NAT_REGION_1_IP_ADDR/32,$NAT_REGION_2_IP_ADDR/32,$CLOUDSHELL_IP/32
      
  2. すべてのクラスタが実行されていることを確認します。

    gcloud container clusters list
    

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

    NAME              LOCATION       MASTER_VERSION    MASTER_IP      MACHINE_TYPE   NODE_VERSION      NUM_NODES  STATUS
    gke-central-priv  us-central1-a  1.16.15-gke.6000  35.238.99.104  e2-standard-4  1.16.15-gke.6000  3          RUNNING
    gke-west-priv     us-west2-a     1.16.15-gke.6000  34.94.188.180  e2-standard-4  1.16.15-gke.6000  3          RUNNING
    
  3. 両方のクラスタに接続して、kubeconfig ファイルにエントリを生成します。

    touch ~/asm-kubeconfig && export KUBECONFIG=~/asm-kubeconfig
    gcloud container clusters get-credentials ${CLUSTER_1} --zone ${CLUSTER_1_ZONE}
    gcloud container clusters get-credentials ${CLUSTER_2} --zone ${CLUSTER_2_ZONE}
    

    kubeconfig ファイルを使用してクラスタに対して認証を行うには、クラスタごとにユーザーとコンテキストを作成します。kubeconfig ファイルにエントリを生成した後、クラスタ間でコンテキストをすばやく切り替えることができます。

  4. 便宜上、クラスタ コンテキストの名前を変更します。

    kubectl config rename-context \
    gke_${PROJECT_ID}_${CLUSTER_1_ZONE}_${CLUSTER_1} ${CLUSTER_1}
    
    kubectl config rename-context \
    gke_${PROJECT_ID}_${CLUSTER_2_ZONE}_${CLUSTER_2} ${CLUSTER_2}
    
  5. 両方のクラスタ コンテキストの名前が正しく変更され構成されていることを確認します。

    kubectl config get-contexts --output="name"
    

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

    gke-central-priv
    gke-west-priv
    
  6. フリートにクラスタを登録します。

    gcloud container fleet memberships register ${CLUSTER_1} --gke-cluster=${CLUSTER_1_ZONE}/${CLUSTER_1} --enable-workload-identity
    gcloud container fleet memberships register ${CLUSTER_2} --gke-cluster=${CLUSTER_2_ZONE}/${CLUSTER_2} --enable-workload-identity
    

これで、限定公開 GKE クラスタの作成と名前の変更が完了しました。

Anthos Service Mesh のインストール

このセクションでは、Anthos Service Mesh を 2 つの GKE クラスタにインストールし、クラスタ間でサービス ディスカバリを行うようにクラスタを構成します。

  1. Cloud Shell で、fleet API を使用して Anthos Service Mesh を両方のクラスタにインストールします。

    gcloud container fleet mesh update --management automatic --memberships ${CLUSTER_1},${CLUSTER_2}
    
  2. クラスタでマネージド Anthos Service Mesh を有効にしたら、インストールするメッシュの監視を設定します。

    watch -g "gcloud container fleet mesh describe | grep 'code: REVISION_READY'"
    
  3. 両方のクラスタに Anthos Service Mesh Ingress ゲートウェイをインストールします。

    kubectl --context=${CLUSTER_1} create namespace asm-ingress
    kubectl --context=${CLUSTER_1} label namespace asm-ingress istio-injection=enabled --overwrite
    kubectl --context=${CLUSTER_2} create namespace asm-ingress
    kubectl --context=${CLUSTER_2} label namespace asm-ingress istio-injection=enabled --overwrite
    
    cat <<'EOF' > asm-ingress.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
    spec:
      type: LoadBalancer
      selector:
        asm: ingressgateway
      ports:
      - port: 80
        name: http
      - port: 443
        name: https
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
    spec:
      selector:
        matchLabels:
          asm: ingressgateway
      template:
        metadata:
          annotations:
            # This is required to tell Anthos Service Mesh to inject the gateway with the
            # required configuration.
            inject.istio.io/templates: gateway
          labels:
            asm: ingressgateway
        spec:
          containers:
          - name: istio-proxy
            image: auto # The image will automatically update each time the pod starts.
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: asm-ingressgateway-sds
      namespace: asm-ingress
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: asm-ingressgateway-sds
      namespace: asm-ingress
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: asm-ingressgateway-sds
    subjects:
    - kind: ServiceAccount
      name: default
    EOF
    
    kubectl --context=${CLUSTER_1} apply -f asm-ingress.yaml
    kubectl --context=${CLUSTER_2} apply -f asm-ingress.yaml
    
  4. Anthos Service Mesh Ingress ゲートウェイがデプロイされていることを確認します。

    kubectl --context=${CLUSTER_1} get pod,service -n asm-ingress
    kubectl --context=${CLUSTER_2} get pod,service -n asm-ingress
    

    両方のクラスタの出力は次のようになります。

    NAME                                        READY   STATUS    RESTARTS   AGE
    pod/asm-ingressgateway-5894744dbd-zxlgc   1/1     Running   0          84s
    
    NAME                           TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)                      AGE
    service/asm-ingressgateway   LoadBalancer   10.16.2.131   34.102.100.138   80:30432/TCP,443:30537/TCP   92s
    

    Anthos Service Mesh のコントロール プレーンと Ingress ゲートウェイを両方のクラスタにインストールすると、フリート API でクラスタ間のサービス ディスカバリが有効になります。クラスタ間のサービス ディスカバリを使用すると、2 つのクラスタで異なるクラスタからサービス エンドポイントを検出できます。分散サービスは、同じ Namespace 内の複数のクラスタで実行されます。

    Anthos Service Mesh の両方のコントロール プレーンが分散サービスのすべてのエンドポイントを検出するには、Anthos Service Mesh が分散サービスを実行しているすべてのクラスタにアクセスできる必要があります。この例では 2 つのクラスタを使用しているため、両方のクラスタで相手のクラスタに対してサービス エンドポイントのクエリを実行できる必要があります。フリート API でマネージド Anthos Service Mesh を有効にすると、エンドポイントの検出が自動的に構成されます。

これで、クラスタと Anthos Service Mesh が構成されました。

Bank of Anthos アプリケーションのデプロイ

  1. Cloud Shell で、Bank of Anthos GitHub リポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/bank-of-anthos.git ${HOME}/bank-of-anthos
    
  2. 両方のクラスタで bank-of-anthos Namespace を作成してラベルを付けます。このラベルを使用すると、ラベルが付けられた Namespace 内のすべての Pod にサイドカー Envoy プロキシを自動的に挿入できます。

    # cluster_1
    kubectl create --context=${CLUSTER_1} namespace bank-of-anthos
    kubectl label --context=${CLUSTER_1} namespace bank-of-anthos istio-injection=enabled
    
    # cluster_2
    kubectl create --context=${CLUSTER_2} namespace bank-of-anthos
    kubectl label --context=${CLUSTER_2} namespace bank-of-anthos istio-injection=enabled
    
  3. Bank of Anthos アプリケーションを bank-of-anthos Namespace の両方のクラスタにデプロイします。

    # The following secret is used for user account creation and authentication
    kubectl --context=$CLUSTER_1 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/extras/jwt/jwt-secret.yaml
    kubectl --context=$CLUSTER_2 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/extras/jwt/jwt-secret.yaml
    
    # Deploy all manifests to both clusters
    kubectl --context=$CLUSTER_1 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/kubernetes-manifests
    kubectl --context=$CLUSTER_2 -n bank-of-anthos apply -f ${HOME}/bank-of-anthos/kubernetes-manifests
    

    サービス ディスカバリには、Kubernetes サービスが両方のクラスタに存在する必要があります。いずれかのクラスタのサービスがリクエストを試行すると、まず、ホスト名の DNS ルックアップを実行して IP アドレスを取得します。GKE では、クラスタで実行されている kube-dns サーバーがこのルックアップを処理します。そのため、構成された Service の定義が必要です。

  4. 一方のクラスタから StatefulSets を削除し、2 つの PostgreSQL データベースがもう一方のクラスタにのみ存在するようにします。

    # Delete the two DB statefulSets from Cluster2
    kubectl --context=$CLUSTER_2 -n bank-of-anthos delete statefulset accounts-db
    kubectl --context=$CLUSTER_2 -n bank-of-anthos delete statefulset ledger-db
    
  5. すべての Pod が両方のクラスタで実行されるようにします。

    1. cluster_1 から Pod を取得します。

      kubectl --context=${CLUSTER_1} -n bank-of-anthos get pod
      

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

      NAME                                  READY   STATUS    RESTARTS   AGE
      accounts-db-0                         2/2     Running   0          9m54s
      balancereader-c5d664b4c-xmkrr         2/2     Running   0          9m54s
      contacts-7fd8c5fb6-wg9xn              2/2     Running   1          9m53s
      frontend-7b7fb9b665-m7cw7             2/2     Running   1          9m53s
      ledger-db-0                           2/2     Running   0          9m53s
      ledgerwriter-7b5b6db66f-xhbp4         2/2     Running   0          9m53s
      loadgenerator-7fb54d57f8-g5lz5        2/2     Running   0          9m52s
      transactionhistory-7fdb998c5f-vqh5w   2/2     Running   1          9m52s
      userservice-76996974f5-4wlpf          2/2     Running   1          9m52s
      
    2. cluster_2 から Pod を取得します。

      kubectl --context=${CLUSTER_2} -n bank-of-anthos get pod
      

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

      NAME                                  READY   STATUS    RESTARTS   AGE
      balancereader-c5d664b4c-bn2pl         2/2     Running   0          9m54s
      contacts-7fd8c5fb6-kv8cp              2/2     Running   0          9m53s
      frontend-7b7fb9b665-bdpp4             2/2     Running   0          9m53s
      ledgerwriter-7b5b6db66f-297c2         2/2     Running   0          9m52s
      loadgenerator-7fb54d57f8-tj44v        2/2     Running   0          9m52s
      transactionhistory-7fdb998c5f-xvmtn   2/2     Running   0          9m52s
      userservice-76996974f5-mg7t6          2/2     Running   0          9m51s
      
  6. Anthos Service Mesh 構成を両方のクラスタにデプロイします。これにより、asm-ingress Namespace 内の Gatewayfrontend Service に対する bank-of-anthos Namespace 内の VirtualService が作成され、上り(内向き)トラフィックを frontend サービスに転送できます。

    Gateways は通常、プラットフォーム管理者またはネットワーク管理者チームが所有します。したがって、Gateway リソースは、プラットフォーム管理者が所有する Ingress Gateway Namespace に作成され、独自の VirtualService エントリを介して他の Namespace で使用できます。これは「共有ゲートウェイ」モデルです。

    cat <<'EOF' > asm-vs-gateway.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
    spec:
      selector:
        asm: ingressgateway
      servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
            - "*"
    ---
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: frontend
      namespace: bank-of-anthos
    spec:
      hosts:
      - "*"
      gateways:
      - asm-ingress/asm-ingressgateway
      http:
      - route:
        - destination:
            host: frontend
            port:
              number: 80
    EOF
    
    kubectl --context=$CLUSTER_1 apply -f asm-vs-gateway.yaml
    
    kubectl --context=$CLUSTER_2 apply -f asm-vs-gateway.yaml
    

これで、Bank of Anthos アプリケーションが 2 つの限定公開 GKE クラスタにデプロイされました。データベースを除くすべてのサービスは、分散サービスとして実行されます。

分散サービスの検査

このセクションでは、ictioctl ツールを使用して、任意のプロキシのプロキシ構成を検査します。これにより、サイドカー プロキシはすべてのサービスで 2 つの Pod を確認し、各クラスタで 1 つの Pod が実行されていることを確認できます。

  1. Cloud Shell で、cluster_1frontend Pod のプロキシ構成エンドポイント リストを調べます。

    export FRONTEND1=$(kubectl get pod -n bank-of-anthos -l app=frontend \
      --context=${CLUSTER_1} -o jsonpath='{.items[0].metadata.name}')
    istioctl proxy-config endpoints \
    --context $CLUSTER_1 -n bank-of-anthos $FRONTEND1 | grep bank-of-anthos
    

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

    10.12.0.6:5432                   HEALTHY     OK                outbound|5432||accounts-db.bank-of-anthos.svc.cluster.local
    10.12.0.7:8080                   HEALTHY     OK                outbound|8080||balancereader.bank-of-anthos.svc.cluster.local
    10.12.0.8:8080                   HEALTHY     OK                outbound|8080||transactionhistory.bank-of-anthos.svc.cluster.local
    10.12.0.9:8080                   HEALTHY     OK                outbound|8080||userservice.bank-of-anthos.svc.cluster.local
    10.12.1.10:8080                  HEALTHY     OK                outbound|8080||ledgerwriter.bank-of-anthos.svc.cluster.local
    10.12.1.9:8080                   HEALTHY     OK                outbound|8080||contacts.bank-of-anthos.svc.cluster.local
    10.12.2.11:5432                  HEALTHY     OK                outbound|5432||ledger-db.bank-of-anthos.svc.cluster.local
    10.12.2.13:8080                  HEALTHY     OK                outbound|80||frontend.bank-of-anthos.svc.cluster.local
    10.76.1.10:8080                  HEALTHY     OK                outbound|8080||transactionhistory.bank-of-anthos.svc.cluster.local
    10.76.1.8:8080                   HEALTHY     OK                outbound|8080||balancereader.bank-of-anthos.svc.cluster.local
    10.76.1.9:8080                   HEALTHY     OK                outbound|80||frontend.bank-of-anthos.svc.cluster.local
    10.76.2.10:8080                  HEALTHY     OK                outbound|8080||userservice.bank-of-anthos.svc.cluster.local
    10.76.2.8:8080                   HEALTHY     OK                outbound|8080||contacts.bank-of-anthos.svc.cluster.local
    10.76.2.9:8080                   HEALTHY     OK                outbound|8080||ledgerwriter.bank-of-anthos.svc.cluster.local
    

    上記の出力では、各分散サービスに 2 つのエンドポイント IP アドレスがあります。これらは Pod の IP アドレスで、クラスタごとに 1 つあります。

Bank of Anthos へのアクセス

Bank of Anthos アプリケーションにアクセスするには、いずれかのクラスタから asm-ingressgateway Service のパブリック IP アドレスを使用します。

  1. 両方のクラスタから asm-ingressgateway IP アドレスを取得します。

    kubectl --context ${CLUSTER_1} \
    --namespace asm-ingress get svc asm-ingressgateway -o jsonpath='{.status.loadBalancer}' | grep "ingress"
    
    kubectl --context ${CLUSTER_2} \
    --namespace asm-ingress get svc asm-ingressgateway -o jsonpath='{.status.loadBalancer}' | grep "ingress"
    
    

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

    {"ingress":[{"ip":"35.236.4.18"}]}
    {"ingress":[{"ip":"34.68.94.81"}]}
    

    IP アドレスの 1 つをコピーして、次のステップで使用します。

  2. ウェブブラウザで新しいタブを開き、前の出力の IP アドレスのいずれかに移動します。Bank of Anthos のフロントエンドが表示され、ログイン、口座への入金、他の口座への送金を行うことができます。このアプリケーションは完全に機能します。

分散サービスの可視化

Anthos Service Mesh では分散サービスを可視化できます。

  1. サービスを表示するには、Google Cloud コンソールの [Anthos] > [サービス メッシュ] ページに移動します。

    [サービス メッシュ] に移動

    サービスは、[テーブル] ビューまたは [トポロジ] ビューで表示できます。デフォルトのビューはテーブルビューです。このビューには、表形式で実行されるすべての分散サービスが表示されます。ビューを変更するには、表示するビューをクリックします。

  2. [テーブル] ビューで [frontend distributed service] をクリックします。個々のサービスをクリックすると、接続されているサービスとともにサービスの詳細ビューが表示されます。

    サービスの詳細ビューで [タイムラインを表示] をクリックすると、SLO を作成し、サービスの履歴タイムラインを表示できます。

  3. ゴールデン シグナルを表示するには、サイドパネルで [指標] をクリックします。

  4. Requests per seconds のグラフで、[データの内訳基準] をクリックして [ロケーション] を選択します。

    結果では、2 つのリージョンに存在する両方のクラスタからの 1 秒あたりのリクエスト数が表示されます。分散サービスは正常であり、両方のエンドポイントがトラフィックを処理しています。

  5. サービス メッシュのトポロジを表示するには、サイドパネルで [Anthos Service Mesh] をクリックし、[Topology View] をクリックします。

  6. 補足データを表示するには、マウスポインタを frontend サービスの上に置きます。これにより、フロントエンドから他のサービスに対する 1 秒あたりの送受信リクエスト数などの情報が表示されます。

  7. さらに詳細を表示するには、frontend サービスで [展開] をクリックします。[Service] と [Workload] が表示されます。つづいて、[Workload] を 2 つの [Deployment] に展開し、[Deployment] を [ReplicaSet] に展開して、[ReplicaSet] を [Pod] に展開できます。すべての要素を展開すると、分散 frontend サービスを確認できます。これは、基本的には 1 つの Service と 2 つの Pod です。

複数クラスタ Ingress を構成する

このセクションでは、両方のクラスタで実行されている Bank of Anthos の frontend サービスにトラフィックを送信するマルチクラスタ Ingress を作成します。Cloud Load Balancing を使用して、両方のクラスタで asm-ingressgateway Service をバックエンドとして使用するロードバランサを作成します。ingress-config クラスタは、マルチクラスタ Ingress 構成のオーケストレーションに使用されます。

ロードバランサを作成するには、MultiClusterIngress と 1 つ以上の MultiClusterServices を使用します。MultiClusterIngress オブジェクトと MultiClusterService オブジェクトには、単一クラスタ コンテキストで使用される既存の Kubernetes Ingress および Service リソースとのマルチクラスタ類似性があります。

  1. 必要な Anthos、GKE Fleet、マルチクラスタ Ingress API を有効にします。

    gcloud services enable \
      anthos.googleapis.com \
      multiclusterservicediscovery.googleapis.com \
      multiclusteringress.googleapis.com
    
  2. ingress-config クラスタを作成します。任意のクラスタを使用できますが、ここでは個別のクラスタを作成することをおすすめします。

    gcloud container clusters create ${CLUSTER_INGRESS} \
      --zone ${CLUSTER_INGRESS_ZONE} \
      --num-nodes=1 \
      --enable-ip-alias \
      --workload-pool=${WORKLOAD_POOL}
    
  3. 便宜上、クラスタの認証情報を取得し、コンテキストの名前を変更します。

    gcloud container clusters get-credentials ${CLUSTER_INGRESS} \
      --zone ${CLUSTER_INGRESS_ZONE} --project ${PROJECT_ID}
    
    kubectl config rename-context \
      gke_${PROJECT_ID}_${CLUSTER_INGRESS_ZONE}_${CLUSTER_INGRESS} ${CLUSTER_INGRESS}
    
  4. マルチクラスタ Ingress を使用するには、参加するすべてのクラスタ(構成クラスタを含む)を Anthos Fleet に登録します。

  5. 構成クラスタを登録します。

    gcloud container fleet memberships register ${CLUSTER_INGRESS} \
      --project=${PROJECT_ID} \
      --gke-cluster=${CLUSTER_INGRESS_ZONE}/${CLUSTER_INGRESS} \
      --enable-workload-identity
    
  6. すべてのクラスタが Anthos Fleet に登録されていることを確認します。

    gcloud container fleet memberships list
    

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

    NAME            EXTERNAL_ID
    gke-west        7fe5b7ce-50d0-4e64-a9af-55d37b3dd3fa
    gke-central     6f1f6bb2-a3f6-4e9c-be52-6907d9d258cd
    gke-ingress     3574ee0f-b7e6-11ea-9787-42010a8a019c
    
  7. ingress-config クラスタでマルチクラスタ Ingress 機能を有効にします。これにより、クラスタに MulticlusterServiceMulticlusterIngress の CustomResourceDefinition(CRD)が作成されます。

    gcloud container fleet ingress enable \
      --config-membership=projects/${PROJECT_ID}/locations/global/memberships/${CLUSTER_INGRESS}
    
  8. ingress-config クラスタで、マルチクラスタ Ingress が有効になっていることを確認します。

    gcloud container fleet ingress describe
    

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

    membershipStates:
      projects/986443280307/locations/global/memberships/gke-central-priv:
        state:
          code: OK
          updateTime: '2022-09-29T13:57:02.972748202Z'
      projects/986443280307/locations/global/memberships/gke-ingress:
        state:
          code: OK
          updateTime: '2022-09-29T13:57:02.972744692Z'
      projects/986443280307/locations/global/memberships/gke-west-priv:
        state:
          code: OK
          updateTime: '2022-09-29T13:57:02.972746497Z'
    
  9. 2 つの CRD が ingress-config クラスタにデプロイされていることを確認します。

    kubectl --context=${CLUSTER_INGRESS} get crd | grep multicluster
    

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

    multiclusteringresses.networking.gke.io     2020-10-29T17:32:50Z
    multiclusterservices.networking.gke.io      2020-10-29T17:32:50Z
    
  10. ingress-config クラスタに asm-ingress 名前空間を作成します。

    kubectl --context ${CLUSTER_INGRESS} create namespace asm-ingress
    
  11. MultiClusterIngress リソースを作成します。

    cat <<EOF > ${HOME}/mci.yaml
    apiVersion: networking.gke.io/v1beta1
    kind: MultiClusterIngress
    metadata:
      name: asm-ingressgateway-multicluster-ingress
    spec:
      template:
        spec:
          backend:
           serviceName: asm-ingressgateway-multicluster-svc
           servicePort: 80
    EOF
    
  12. MultiClusterService リソースを作成します。

    cat <<'EOF' > $HOME/mcs.yaml
    apiVersion: networking.gke.io/v1beta1
    kind: MultiClusterService
    metadata:
      name: asm-ingressgateway-multicluster-svc
      annotations:
        beta.cloud.google.com/backend-config: '{"ports": {"80":"gke-ingress-config"}}'
    spec:
      template:
        spec:
          selector:
            asm: ingressgateway
          ports:
          - name: frontend
            protocol: TCP
            port: 80 # servicePort defined in Multi Cluster Ingress
      clusters:
      - link: "us-west2-a/gke-west-priv"
      - link: "us-central1-a/gke-central-priv"
    EOF
    
  13. ヘルスチェック用の BackendConfig リソースを作成します。

    cat <<EOF > $HOME/backendconfig.yaml
    apiVersion: cloud.google.com/v1beta1
    kind: BackendConfig
    metadata:
      name: gke-ingress-config
    spec:
      healthCheck:
        type: HTTP
        port: 15021
        requestPath: /healthz/ready
    EOF
    
  14. BackendConfigMultiClusterServiceMultiClusterIngress の各マニフェストを適用します。

    kubectl --context ${CLUSTER_INGRESS} -n asm-ingress apply -f ${HOME}/backendconfig.yaml
    kubectl --context ${CLUSTER_INGRESS} -n asm-ingress apply -f ${HOME}/mci.yaml
    kubectl --context ${CLUSTER_INGRESS} -n asm-ingress apply -f ${HOME}/mcs.yaml
    
  15. Ingress クラスタにデプロイした MultiClusterService によって、クラスタ 1 とクラスタ 2 に「ヘッドレス」 Service が作成されます。「ヘッドレス」Services が作成されていることを確認します。

    kubectl --context=${CLUSTER_1} -n asm-ingress \
      get services | grep multicluster-svc
    kubectl --context=${CLUSTER_2} -n asm-ingress \
      get services | grep multicluster-svc
    

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

    mci-frontend-multi-cluster-service-svc-f7rcyqry22iq8nmw   ClusterIP      None          <none>          80/TCP         77s
    mci-frontend-multi-cluster-service-svc-f7rcyqry22iq8nmw   ClusterIP      None          <none>          80/TCP         78s
    
  16. 次のコマンドを実行し、Cloud Load Balancing IP アドレスを取得するまで待ちます。

    watch kubectl --context ${CLUSTER_INGRESS} -n asm-ingress get multiclusteringress \
      -o jsonpath="{.items[].status.VIP}"
    

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

    35.35.23.11
    

    watch コマンドを終了するには、Ctrl+C キーを押します。

  17. ウェブブラウザで Cloud Load Balancing の IP アドレスに移動し、Bank of Anthos のフロントエンドに移動します。

    kubectl --context ${CLUSTER_INGRESS} \
      -n asm-ingress get multiclusteringress \
      -o jsonpath="{.items[].status.VIP}"
    

    404 エラー(または 502 エラー)が表示された場合は、数分待ってから、ウェブブラウザでページを更新します。

クリーンアップ

このチュートリアルで使用したリソースについて、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.

クラスタを削除する

  1. Cloud Shell で、blue クラスタと green クラスタの登録を解除して削除します。

    gcloud container fleet memberships unregister ${CLUSTER_1} \
      --project=${PROJECT} \
      --gke-uri=${CLUSTER_1_URI}
    gcloud container clusters delete ${CLUSTER_1} \
      --zone ${CLUSTER_1_ZONE} \
      --quiet
    
    gcloud container fleet memberships unregister ${CLUSTER_2} \
      --project=${PROJECT} \
      --gke-uri=${CLUSTER_2_URI}
    gcloud container clusters delete ${CLUSTER_2} \
      --zone ${CLUSTER_2_ZONE} \
      --quiet
    
  2. MuticlusterIngress リソースを Ingress-config クラスタから削除します。

    kubectl --context ${CLUSTER_INGRESS} -n istio-system delete -f $HOME/mci.yaml
    

    これにより、プロジェクトから Cloud Load Balancing リソースが削除されます。

  3. ingress-config クラスタの登録を解除して削除します。

    gcloud container fleet memberships unregister ${CLUSTER_INGRESS} \
      --project=${PROJECT} \
      --gke-uri=${CLUSTER_INGRESS_URI}
    gcloud container clusters delete ${CLUSTER_INGRESS} \
      --zone ${CLUSTER_INGRESS_ZONE} \
      --quiet
    
  4. すべてのクラスタが削除されていることを確認します。

    gcloud container clusters list
    

    次のような出力が表示されます。

    <null>
  5. kubeconfig ファイルをリセットします。

    unset KUBECONFIG
    

次のステップ