Cloud Service Mesh の例: カナリア デプロイ


このチュートリアルでは、Cloud Service Mesh を使用してカナリア デプロイをロールアウトする一般的なユースケースを実施します。

カナリア デプロイとは

カナリア デプロイでは、トラフィックのごく一部を新しいバージョンのマイクロサービスに転送し、古いバージョンを段階的に廃止して、ユーザーベース全体に段階的にロールアウトできます。このプロセス中になんらかの問題が発生した場合に、トラフィックを古いバージョンに戻すことができます。Cloud Service Mesh では、新しいサービスを安全に導入できるよう、トラフィックを転送できます。

アプリケーションのデプロイとテストの戦略でカナリアテストの詳細をご確認いただけます。

費用

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

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

このチュートリアルの終了後に作成したリソースを削除すれば、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

始める前に

Online Boutique をデプロイする

  1. kubectl の現在のコンテキストを、Online Boutique をデプロイしたクラスタに設定します。

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. サンプル アプリケーションと Ingress ゲートウェイの名前空間を作成します。

    kubectl create namespace onlineboutique
    
  3. Envoy プロキシを自動的に挿入するには、onlineboutique 名前空間にラベルを付けます。自動サイドカー インジェクションを有効にする方法の手順を行います。

  4. サンプルアプリをデプロイする。このチュートリアルでは、マイクロサービスのデモアプリである Online Boutique をデプロイします。

    kubectl apply \
    -n onlineboutique \
    -f https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/shared/online-boutique/kubernetes-manifests.yaml
    
  5. 次のコマンドを実行して、productcatalog デプロイにラベル version=v1 を追加します。

    kubectl patch deployments/productcatalogservice -p '{"spec":{"template":{"metadata":{"labels":{"version":"v1"}}}}}' \
    -n onlineboutique
    

    デプロイしたサービスを表示します。

    kubectl get pods -n onlineboutique
    

    予想される出力:

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-m84m6               2/2     Running   0          2m7s
    cartservice-c77f6b866-m67vd              2/2     Running   0          2m8s
    checkoutservice-654c47f4b6-hqtqr         2/2     Running   0          2m10s
    currencyservice-59bc889674-jhk8z         2/2     Running   0          2m8s
    emailservice-5b9fff7cb8-8nqwz            2/2     Running   0          2m10s
    frontend-77b88cc7cb-mr4rp                2/2     Running   0          2m9s
    loadgenerator-6958f5bc8b-55q7w           2/2     Running   0          2m8s
    paymentservice-68dd9755bb-2jmb7          2/2     Running   0          2m9s
    productcatalogservice-84f95c95ff-c5kl6   2/2     Running   0          114s
    recommendationservice-64dc9dfbc8-xfs2t   2/2     Running   0          2m9s
    redis-cart-5b569cd47-cc2qd               2/2     Running   0          2m7s
    shippingservice-5488d5b6cb-lfhtt         2/2     Running   0          2m7s
    

    アプリケーションのすべての Pod が稼働状態になり、READY 列に 2/2 が入力されます。これは、Pod に Envoy サイドカー プロキシが正常に挿入されたことを示します。

  6. productcatalog の v1 に VirtualServiceDestinationRule をデプロイします。

    kubectl apply -f destination-vs-v1.yaml -n onlineboutique
    
    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: productcatalogservice
    spec:
      host: productcatalogservice
      subsets:
      - labels:
          version: v1
        name: v1
    ---
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: productcatalogservice
    spec:
      hosts:
      - productcatalogservice
      http:
      - route:
        - destination:
            host: productcatalogservice
            subset: v1

    なお、リソースには v1 のみが存在します。

  7. Ingress の外部 IP アドレスを使用して、ブラウザでアプリケーションにアクセスします。

    kubectl get services -n GATEWAY_NAMESPACE
    

次のセクションでは、Cloud Service Mesh の UI について説明し、指標を表示する方法を示します。

Google Cloud コンソールにサービスをデプロイして表示する

  1. Google Cloud コンソールで、[GKE Enterprise Services] ページに移動します。

    [GKE Enterprise Services] に移動

  2. デフォルトでは、[テーブル] ビューにサービスを表示します。

    テーブルの概要では、すべてのサービスと重要な指標を一目で確認できます。

    すべてのサービス ワークロード

  3. 右上の [トポロジ] をクリックします。ここでは、相互にサービスとそのインタラクションが表示されます。

    サービスを展開して、各サービスの 1 秒あたりのリクエスト数を表示するには、それらにカーソルを合わせます。

    すべてのサービス ワークロード トポロジ

  4. [テーブルビュー] に戻ります。

  5. [サービス テーブル] で productcatalogservice を選択します。ここでは、サービスの概要が表示されます。

  6. 画面左側にある [トラフィック] をクリックします。

  7. productcatalogservice への受信トラフィックの 100% がワークロード サービスに送信されるようにします。

    productcatalog svc トラフィック

次のセクションでは、productcatalog サービスの v2 を作成します。

サービスの v2 をデプロイする

  1. このチュートリアルでは、productcatalogservice-v2 を使用して、EXTRA_LATENCY フィールドを含むリクエストに 3 秒のレイテンシを設定します。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: productcatalogservice-v2
    spec:
      selector:
        matchLabels:
          app: productcatalogservice
      template:
        metadata:
          labels:
            app: productcatalogservice
            version: v2
        spec:
          containers:
          - env:
            - name: PORT
              value: '3550'
            - name: EXTRA_LATENCY
              value: 3s
            name: server
            image: gcr.io/google-samples/microservices-demo/productcatalogservice:v0.3.6
            livenessProbe:
              exec:
                command: ["/bin/grpc_health_probe", "-addr=:3550"]
            ports:
            - containerPort: 3550
            readinessProbe:
              exec:
                command: ["/bin/grpc_health_probe", "-addr=:3550"]
            resources:
              limits:
                cpu: 200m
                memory: 128Mi
              requests:
                cpu: 100m
                memory: 64Mi
          terminationGracePeriodSeconds: 5

    このリソースを onlineboutique 名前空間に適用します。

    kubectl apply -f productcatalog-v2.yaml -n onlineboutique
    
  2. アプリケーションの Pod を確認します。

    kubectl get pods -n onlineboutique
    

    予想される出力:

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-8wqfd                  2/2     Running   0          25h
    cartservice-c77f6b866-7jwcr                 2/2     Running   0          25h
    checkoutservice-654c47f4b6-n8c6x            2/2     Running   0          25h
    currencyservice-59bc889674-l5xw2            2/2     Running   0          25h
    emailservice-5b9fff7cb8-jjr89               2/2     Running   0          25h
    frontend-77b88cc7cb-bwtk4                   2/2     Running   0          25h
    loadgenerator-6958f5bc8b-lqmnw              2/2     Running   0          25h
    paymentservice-68dd9755bb-dckrj             2/2     Running   0          25h
    productcatalogservice-84f95c95ff-ddhjv      2/2     Running   0          25h
    productcatalogservice-v2-6df4cf5475-9lwjb   2/2     Running   0          8s
    recommendationservice-64dc9dfbc8-7s7cx      2/2     Running   0          25h
    redis-cart-5b569cd47-vw7lw                  2/2     Running   0          25h
    shippingservice-5488d5b6cb-dj5gd            2/2     Running   0          25h
    

    2 つの productcatalogservices が現在表示されていることに注意してください。

  3. DestinationRule は、サービスのサブセットを指定する方法です。このシナリオでは、productcatalogservice の v1 用と v2 用のサブセットがあります。

    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: productcatalogservice
    spec:
      host: productcatalogservice
      subsets:
      - labels:
          version: v1
        name: v1
      - labels:
          version: v2
        name: v2

    labels フィールドに注意してください。productcatalogservice のバージョンは、VirtualService によってトラフィックが転送された後に区別されます。

    DestinationRule を適用します。

    kubectl apply -f destination-v1-v2.yaml -n onlineboutique
    

v1 と v2 間のトラフィックを分割する

  1. VirtualService は、トラフィックのごく一部を productcatalogservice の v2 に設定する方法です。

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: productcatalogservice
    spec:
      hosts:
      - productcatalogservice
      http:
      - route:
        - destination:
            host: productcatalogservice
            subset: v1
          weight: 75
        - destination:
            host: productcatalogservice
            subset: v2
          weight: 25

    サブセット フィールドはバージョンを示し、重みフィールドはトラフィック分割の割合を示します。トラフィックの 75% が productcatalog の v1 に、25% が v2 に送信されます。

    VirtualService を適用します。

    kubectl apply -f vs-split-traffic.yaml -n onlineboutique
    

クラスタの Ingress の EXTERNAL_IP にアクセスすると、フロントエンドがロードされるのが定期的に遅くなっていることがわかります。

次のセクションでは、GKE Enterprise の Google Cloud コンソールでのトラフィック分割について説明します。

Google Cloud コンソールでトラフィック分割を確認する

  1. Google Cloud コンソールに戻り、[GKE Enterprise Services] ページに移動します。 [GKE Enterprise Services] に移動

  2. 右上の [トポロジ] をクリックします。

    productcatalogservice ワークロードを開きますproductcatalogserviceproductcatalogservice-v2 のデプロイが表示されます。

    productcatalog svc v1 v2 トラフィックのトポロジ

  3. [テーブルビュー] に戻ります。[サービス テーブル] で productcatalogservice をクリックします。左側のナビゲーション バーにある [トラフィック] に戻ります。

  4. 受信トラフィックが、VirtualService ファイルで指定されている割合で v1 と v2 に分割され、productcatalog サービスのワークロードが 2 つあることに注意してください。

    画面の右側にリクエスト、エラー率、レイテンシの指標が表示されます。Cloud Service Mesh では、各サービスにこれらの指標の概要が表示され、オブザーバビリティが確保されます。

    productcatalog svc v1 v2 トラフィック

特定バージョンへのロールアウトまたはロールバック

カナリア デプロイ中に指標を監視した後、新しいサービスにロールアウトするか、VirtualService リソースを使用して古いサービスにロールバックできます。

ロールアウト

v2 サービスの動作に問題がなければ、v2 サービスへのトラフィックの動作を徐々に増やします。最終的には、100% のトラフィックが新しいサービスに転送されます。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: productcatalogservice
spec:
  hosts:
  - productcatalogservice
  http:
  - route:
    - destination:
        host: productcatalogservice
        subset: v2

すべてのトラフィックを productcatalogservice の v2 に転送するには:

kubectl apply -f vs-v2.yaml -n onlineboutique

ロールバック

v1 サービスにロールバックする必要がある場合は、単に先ほどの destination-vs-v1.yaml を適用します。これにより、トラフィックは productcatalogservice の v1 にのみ転送されます。

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: productcatalogservice
spec:
  hosts:
  - productcatalogservice
  http:
  - route:
    - destination:
        host: productcatalogservice
        subset: v1

すべてのトラフィックを productcatalogservice の v1 に転送するには:

kubectl apply -f vs-v1.yaml -n onlineboutique

クリーンアップ

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

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

プロジェクトの削除

  1. Cloud Shell で、プロジェクトを削除します。

    gcloud projects delete PROJECT_ID
    

リソースの削除

  • 追加料金の発生を回避するには、クラスタを削除します。

    gcloud container clusters delete  CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  • クラスタを維持して Online Boutique のサンプルを削除するには:

    1. アプリケーションの名前空間を削除します。

      kubectl delete -f namespace onlineboutique
      

      予想される出力:

      namespace "onlineboutique" deleted
      
    2. サービス エントリを削除します。

      kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/main/istio-manifests/frontend.yaml -n onlineboutique
      kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/main/istio-manifests/frontend-gateway.yaml -n onlineboutique
      

      予想される出力:

      serviceentry.networking.istio.io "allow-egress-googleapis" deleted
      serviceentry.networking.istio.io "allow-egress-google-metadata" deleted
      

次のステップ