Istio を使用して ASP.NET Core アプリを Google Kubernetes Engine にデプロイする(パート 2)

1. 概要

ラボの最初のパートでは、ASP.NET Core アプリケーションを作成してコンテナ化し、Google Kubernetes Engine(GKE)にデプロイし、Istio で管理されるようにトラフィックを構成しました。

このラボの後半では、最初のラボで作成した Kubernetes クラスタとアプリケーションがすでに実行されていることを前提としています。Istio が最小限のコード変更でサービスの管理、モニタリング、保護にどのように役立つかについて説明します。具体的には、指標、トレース、サービスの可視化、動的トラフィック管理、フォールト インジェクションなどの Istio の機能について確認します。

学習内容

  • Prometheus を使用して指標をクエリする方法。
  • Grafana を使用して指標を可視化する方法。
  • サービスの新しいバージョンを作成する方法。
  • サービスを特定のバージョンに固定する方法。
  • バージョン間でトラフィックを分割する方法。
  • サービス呼び出しに障害を挿入する方法。

必要なもの

このチュートリアルの利用方法をお選びください。

通読するのみ 内容を読んで演習を完了する

Google Cloud Platform のご利用経験について、いずれに該当されますか?

<ph type="x-smartling-placeholder"></ph> 初心者 中級 上達 をご覧ください。

2. 設定と要件

セルフペース型の環境設定

  1. Cloud Console にログインし、新しいプロジェクトを作成するか、既存のプロジェクトを再利用します(Gmail アカウントまたは G Suite アカウントをお持ちでない場合は、アカウントを作成する必要があります)。

H_hgylo4zxOllHaAbPKJ7VyqCKPDUnDhkr-BsBIFBsrB6TYSisg6LX-uqmMhh4sXUy_hoa2Qv87C2nFmkg-QAcCiZZp0qtpf6VPaNEEfP_iqt29KVLD-gklBWugQVeOWsFnJmNjHDw

dcCPqfBIwNO4R-0fNQLUC4aYXOOZhKhjUnakFLZJGeziw2ikOxGjGkCHDwN5x5kCbPFB8fiOzZnX-GfuzQ8Ox-UU15BwHirkVPR_0RJwl0oXrhqZmMIvZMa_uwHugBJIdx5-bZ6Z8Q

jgLzVCxk93d6E2bbonzATKA4jFZReoQ-fORxZZLEi5C3D-ubnv6nL-eP-iyh7qAsWyq_nyzzuEoPFD1wFOFZOe4FWhPBJjUDncnTxTImT3Ts9TM54f4nPpsAp52O0y3Cb19IceAEgQ

プロジェクト ID を忘れないようにしてください。プロジェクト ID はすべての Google Cloud プロジェクトを通じて一意の名前にする必要があります(上記の名前はすでに使用されているので使用できません)。以降、このコードラボでは PROJECT_ID と呼びます。

  1. 次に、Google Cloud リソースを使用するために、Cloud Console で課金を有効にする必要があります。

このコードラボを実行しても、費用はほとんどかからないはずです。このチュートリアル以外で請求が発生しないように、リソースのシャットダウン方法を説明する「クリーンアップ」セクションの手順に従うようにしてください。Google Cloud の新規ユーザーは $300 の無料トライアル プログラムをご利用いただけます。

Cloud Shell の起動

Google Cloud はノートパソコンからリモートで操作できますが、この Codelab では、Google Cloud 上で動作するコマンドライン環境である Google Cloud Shell を使用します。

Cloud Shell をアクティブにする

  1. Cloud Console で、[Cloud Shell をアクティブにする] dnDTxS9j60RcXdTjea12HLB9paS9Gzf7PfFLE9RW8g0Qx1bz7nmCzyCu4rjluX3bOEwavOpDwioXEkzOf6xtZp6-ZbJa08jwJqtqv9-ZbJa08jwJqtqv9W8jZlyF をクリックします。

yzBQBp2RC1EFvSSLYVkMA2m6LHqGsp22O81rUS5tGb9Y1FqlVhoRj_ka8V_uEjtpcirZRULMy1IjNr848uYvb9mC9RcGGqeayaLcXFfRwUGeXWChZPtWkHzUshTcqx_wJHis0X8viA

Cloud Shell を起動したことがない場合、その内容を説明する中間画面が(スクロールしなければ見えない範囲に)が表示されます。その場合は、[続行] をクリックします(以後表示されなくなります)。この中間画面は次のようになります。

はじめて

Cloud Shell のプロビジョニングと接続に少し時間がかかる程度です。

7RuYr-LCKzdiE1veTFmL_lYrVxsMZ6-xDoxAnfwPPc5uFA0utmFGejvu81jGmTdbqnqxrytW3KcHT6xrMIRc3bskctnDZC5nJdpqw-LRxu3r35hL4A0BSBTtbtirfh3PKv-eOKt8Rg

この仮想マシンには、必要な開発ツールがすべて用意されています。5 GB の永続ホーム ディレクトリが用意されており、Google Cloud で稼働するため、ネットワーク パフォーマンスが充実しており認証もスムーズです。このコードラボでの作業のほとんどは、ブラウザまたは Chromebook から実行できます。

Cloud Shell に接続すると、すでに認証は完了しており、プロジェクトに各自のプロジェクト ID が設定されていることがわかります。

  1. Cloud Shell で次のコマンドを実行して、認証されたことを確認します。
gcloud auth list

コマンド出力

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
gcloud config list project

コマンド出力

[core]
project = <PROJECT_ID>

上記のようになっていない場合は、次のコマンドで設定できます。

gcloud config set project <PROJECT_ID>

コマンド出力

Updated property [core/project].

3. アプリケーションをテストする

ラボを開始する前に、アプリケーションが前のラボで動作していることを確認します。前述のとおり、EXTERNAL-IP の下に表示されているゲートウェイの外部 IP とポートは次のように表示されます。

kubectl get svc istio-ingressgateway -n istio-system

アプリケーションを表示するには、ブラウザを開いて http://<gatewayurl> に移動します。

f579a9baedc108a9.png

アプリケーションが表示されない場合は、前のラボに戻って、すべての手順を行ったこと、アプリケーションと Istio の両方がインストールされて正常に実行されていることを確認します。

ここで、「Istio のメリットは何ですか?」と疑問に思われるかもしれません。Istio にアプリケーションのトラフィックを管理させると、指標、トレース、動的トラフィック管理、サービスの可視化、フォールト インジェクションなどの機能を無料で利用することができます。

次のステップでは、指標の確認から始めます。

4. Grafana と Prometheus での指標

デフォルトでは、Istio はいくつかの指標を生成します。アドオンを使用すると、これらのデフォルトの指標をクエリして可視化できます。

Prometheus

Prometheus はオープンソースのモニタリング ソリューションです。Prometheus を使用して、Istio によって生成された指標をクエリできますが、最初に Prometheus アドオンをインストールする必要があります。

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/prometheus.yaml

Prometheus が実行されていることを確認します。

kubectl get svc prometheus -n istio-system

NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
prometheus   ClusterIP   10.31.243.62   <none>        9090/TCP   1d

http://<gatewayurl> に数回アクセスするか、curl コマンドを実行して、アプリケーションにトラフィックを送信します。

Prometheus UI のポート転送を設定します。

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') 8080:9090

これで、Cloud Shell の右上にある [ウェブでプレビュー] ボタンをクリックし、[ポート 8080 でプレビュー] をクリックして、クエリを実行できるようになりました。

772a5248aa493025.png

新しいタブに Prometheus UI が表示されます。

272ee63c1fe0be16.png

Prometheus の詳細については、Prometheus を使用した指標のクエリをご覧ください。

Grafana

Grafana も、指標を可視化するためのアドオンです。

Grafana をインストールします。istio-version は、現在の Istio バージョン(1.0.3-gke.3 など)に置き換えます。

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/grafana.yaml

Grafana が実行されていることを確認します。

kubectl get svc grafana -n istio-system

NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
grafana   ClusterIP   10.31.248.230   <none>        3000/TCP   1d

http://<gatewayurl> に数回アクセスするか、curl コマンドを実行して、アプリケーションにトラフィックを送信します。

Grafana UI のポート転送を設定します。

kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 8080:3000

ウェブでプレビューにアクセスすることで、Grafana ダッシュボードを表示できます。

806d696d85267a37.png

524cb9f6d66f8655.png

Granfana の詳細については、Grafana を使用して指標を可視化するをご覧ください。

5. アプリケーションの新しいバージョンを作成する

本番環境にデプロイしたアプリケーションは、いずれかの時点でバグ修正や追加機能の実装が必要になります。そのプロセスを見てみましょう

まず、アプリケーションを修正しましょう。Cloud Shell からコードエディタを開きます。

mxrggIJ2Zz8E47ULCEo4NywjM-EpSkZF5c3TQgfGx4nODwP2obiQXrwQjEEaXuBhJDA2jJ5evR7TuHIy1gsqqDRFm0Wh3xhZUu9tn_xb1ygFlBm1HKJqLdfz_aK7WJS33u2IBDO2oQ

HelloWorldAspNetCore > Views > HomeIndex.cshtml に移動し、カルーセル メッセージのいずれかを更新します。

次の行を探します。

Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core 

これを次のように変更します。

Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core on Google Cloud

変更を保存して、Cloud Shell に戻ります。HelloWorldAspNetCore, 内で Docker イメージをビルドします。

docker build -t gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v2 . 

Container Registry に push します。

docker push gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v2 

コンテナ イメージを push したら、次のステップで新しいバージョンをデプロイできます。

6. 新しい Deployment を作成する

新しいバージョンをデプロイするには、まず Kubernetes で新しい Deployment を作成する必要があります。aspnetcore.yaml ファイルの末尾に以下を追加します。

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: aspnetcore-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aspnetcore
      version: v2
  template:
    metadata:
      labels:
        app: aspnetcore
        version: v2
    spec:
      containers:
      - name: aspnetcore
        image: gcr.io/YOUR-PROJECT-ID/hello-dotnet:v2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

kubectl を使用して、新しいバージョンをデフォルトの Namespace にデプロイします。

kubectl apply -f aspnetcore.yaml
service "aspnetcore" unchanged
deployment.extensions "aspnetcore-v1" unchanged
deployment.extensions "aspnetcore-v2" created

想定した Pod が実行されていることを確認します。

kubectl get pods
NAME                          READY     STATUS    RESTARTS   AGE
aspnetcore-v1-6cf64748-mddb   2/2       Running   0          34s
aspnetcore-v2-5d765db-l9xmg   2/2       Running   0          1m

次に、アプリケーションを再度テストします。ゲートウェイの外部 IP を取得します。

kubectl get svc istio-ingressgateway -n istio-system

EXTERNAL-IP の下に表示されます。シークレット ブラウザを開いて http://<replace-with-external-ip> にアクセスします。

更新すると、「ASP.NET Core を使用したウェブアプリのビルドの詳細」というメッセージが表示されることがあります。

11d528132dbb6cee.png

それ以外の場合は、「Google Cloud で ASP.NET Core を使用したウェブアプリのビルドの詳細」というメッセージが表示されます。

3eb0d5be1b4cb40b.png

これは、v1v2 の両方が同じ Kubernetes Service(aspnetcore-service)の背後で公開され、前のラボで作成した VirtualService(aspnetcore-virtualservice)がそのサービスをホストとして使用するためです。

次のステップでは、DestinationRule を使用して、サービスを v2 Deployment に固定します。

7. サービスを新しいバージョンに固定する

このステップでは、v2 Deployment を使用するようにサービスを固定します。これは DestinationRule を使用します。DestinationRule は、VirtualService ルーティング オペレーションが発生した後にリクエストに適用される一連のポリシーを構成します。

DestinationRule はまた、対応する宛先ホストのアドレス指定可能なサブセット(名前付きバージョン)も定義します。これらのサブセットは、特定バージョンのサービスにトラフィックを送信するときに VirtualService ルートの仕様で使用されます。

aspnetcore-destinationrule.yaml という名前の新しいファイルを作成します。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: aspnetcore-destinationrule
spec:
  host: aspnetcore-service
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

次に、DestinationRule を作成します。これにより、VirtualService から使用できる 2 つのサブセット(v1 と v2)が作成されます。

kubectl apply -f aspnetcore-destinationrule.yaml
destinationrule.networking.istio.io "aspnetcore-destionationrule" created

次に、aspnetcore-virtualservice.yaml ファイルに戻り、v2 サブセットを使用するように VirtualService を更新します。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service
        subset: v2

VirtualService を更新します。

kubectl apply -f aspnetcore-virtualservice.yaml

ブラウザを開き、http://<replace-with-external-ip>. にアクセスします。更新を複数回行っても、「Google Cloud で ASP.NET Core を使用したウェブアプリの構築の詳細について学ぶ」というメッセージが表示されます。

3eb0d5be1b4cb40b.png

8. バージョン間でのトラフィックの分割

テストのためにバージョン間でトラフィックを分割したい場合があります。たとえば、トラフィックの 75% を v1 に送信し、トラフィックの 25% を v2 バージョンの Service に送信するとします。Istio を使用すると、これは簡単に実現できます。重みの異なる 2 つの部分集合を参照する新しい aspnetcore-virtualservice-weights.yaml ファイルを作成します。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service
        subset: v1
      weight: 75
    - destination:
        host: aspnetcore-service
        subset: v2
      weight: 25

VirtualService を更新します。

kubectl apply -f aspnetcore-virtualservice-weights.yaml

ブラウザを更新すると、v1 と v2 のバージョンがほぼ 3:1 の比率で表示されます。

詳細については、Istio でのトラフィック分割をご覧ください。

9. 障害の注入

テストに役立つもう一つの開発タスクは、トラフィックに障害や遅延を注入し、それに対するサービスの動作を確認することです。

たとえば、v1 バージョンへのトラフィックの 50% に対して不正なリクエスト(HTTP 400)レスポンスを返すとします。以下に一致する aspnetcore-virtualservice-fault-abort.yaml ファイルを作成します。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - fault:
      abort:
        percentage:
          value: 50
        httpStatus: 400
    route:
    - destination:
        host: aspnetcore-service
        subset: v1

VirtualService を更新します。

kubectl apply -f aspnetcore-virtualservice-fault-abort.yaml

ブラウザを更新すると、その半分の時間で v1 サービスが HTTP 400s レスポンス コードを返していることがわかります。

あるいは、リクエストに 5 秒の遅延を追加したい場合があります。以下に一致する aspnetcore-virtualservice-fault-delay.yaml ファイルを作成します。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - fault:
      delay:
        fixedDelay: 5s
        percentage:
          value: 100
    route:
    - destination:
        host: aspnetcore-service
        subset: v1

VirtualService を更新します。

kubectl apply -f aspnetcore-virtualservice-fault-delay.yaml

ブラウザを更新すると、リクエストが 5 秒遅れていることがわかります。

タイムアウト、再試行、条件付きルール、サーキット ブレーカーなどの Istio 機能の詳細については、トラフィック管理機能をご覧ください。

10. 完了

このラボで、Istio ですぐに使用できるサービスの概要を理解できたのではないでしょうか。Istio と GKE の詳細。

次のステップ

ライセンス

この作業はクリエイティブ・コモンズの表示 2.0 汎用ライセンスにより使用許諾されています。

11. クリーンアップ

アプリを削除して Istio をアンインストールすることも、Kubernetes クラスタを削除することもできます。

アプリケーションを削除する

アプリケーションを削除するには:

kubectl delete -f aspnetcore-gateway.yaml
kubectl delete -f aspnetcore-virtualservice.yaml
kubectl delete -f aspnetcore-destinationrule.yaml
kubectl delete -f aspnetcore.yaml

アプリケーションが削除されたことを確認するには:

kubectl get gateway 
kubectl get virtualservices
kubectl get destinationrule
kubectl get pods

Istio をアンインストールする

Istio を削除するには:

kubectl delete -f install/kubernetes/istio-demo-auth.yaml

Istio がなくなったことを確認するには:

kubectl get pods -n istio-system

Kubernetes クラスタを削除する

gcloud container clusters delete hello-dotnet-cluster