1. アルファ版ワークショップ
ワークショップの Codelab へのリンク bit.ly/asm-workshop
2. 概要
アーキテクチャ図
このワークショップは、GCP 上でグローバルに分散されたサービスを本番環境に設定する方法を説明する、実践的で実践的な経験です。使用される主なテクノロジーは、コンピューティング用の Google Kubernetes Engine(GKE)と、安全な接続、オブザーバビリティ、高度なトラフィック シェーピングを作成するための Istio サービス メッシュです。このワークショップで使用するプラクティスとツールはすべて、本番環境で使えるものと同じです。
アジェンダ
- モジュール 0 - 概要とプラットフォームの設定
- 概要とアーキテクチャ
- サービス メッシュと Istio/ASM の概要
- ラボ: インフラストラクチャの設定: ユーザー ワークフロー
- 休憩
- QnA
- モジュール 1 - ASM を使用してアプリケーションをインストール、保護、モニタリングする
- リポジトリ モデル: インフラストラクチャと Kubernetes のリポジトリについて
- ラボ: サンプル アプリケーションをデプロイする
- 分散サービスとオブザーバビリティ
- 昼食
- ラボ: Stackdriver によるオブザーバビリティ
- QNA
- モジュール 2 - DevOps - カナリア ロールアウト、ポリシー/RBAC
- マルチクラスタ サービス ディスカバリとセキュリティ/ポリシー
- ラボ: 相互 TLS
- カナリア デプロイ
- ラボ: カナリア デプロイ
- 安全なマルチクラスタ グローバル ロード バランシング
- 休憩
- ラボ: 認可ポリシー
- QNA
- モジュール 3 - インフラストラクチャ運用 - プラットフォームのアップグレード
- 分散 Service ビルディング ブロック
- ラボ: インフラストラクチャのスケーリング
- 次のステップ
スライド
このワークショップのスライドは次のリンクからご覧いただけます。
前提条件
このワークショップを進めるには、以下が必要です。
- GCP 組織ノード
- 請求先アカウント ID(ユーザーは、この請求先アカウントの課金管理者である必要があります)
- ユーザーの組織レベルでの組織管理者の IAM ロール
3. インフラストラクチャの設定 - 管理者ワークフロー
ブートストラップ ワークショップのスクリプトの説明
bootstrap_workshop.sh というスクリプトを使用して、ワークショップの初期環境を設定します。このスクリプトを使用して、自分用に 1 つの環境をセットアップすることも、このワークショップを複数のユーザーへのトレーニングとして実施する場合は複数のユーザー用に複数の環境をセットアップすることもできます。
ブートストラップ ワークショップ スクリプトには、入力として以下が必要です。
- 組織名(例:
yourcompany.com
)- これは、ワークショップ用の環境を作成する組織です。 - 請求 ID(例:
12345-12345-12345
)- この請求 ID は、ワークショップで使用されたすべてのリソースへの請求に使用されます。 - ワークショップ番号(例:
01
)- 2 桁の番号。これは、複数のワークショップを 1 日に実施し、それらを別々に把握したい場合に使用します。ワークショップ番号はプロジェクト ID の導出にも使用されます。ワークショップ番号が分かれていれば、毎回一意のプロジェクト ID を簡単に取得できます。ワークショップ番号に加えて、現在の日付(YYMMDD
の形式)もプロジェクト ID に使用されます。日付とワークショップ番号を組み合わせると、一意のプロジェクト ID が生成されます。 - 開始ユーザーの番号(例:
1
)- この数字は、ワークショップの最初のユーザーを示します。たとえば、10 人のユーザー用のワークショップを作成する場合、開始ユーザー番号を 1、エンドユーザー番号を 10 にします。 - エンドユーザー番号(例:
10
)- この番号は、ワークショップの最後のユーザーを表します。たとえば、10 人のユーザー用のワークショップを作成する場合、開始ユーザー番号を 1、エンドユーザー番号を 10 にします。(たとえば自社用に)単一の環境を設定する場合は、開始ユーザーとエンドユーザー番号を同じにします。これにより、環境が 1 つ作成されます。
- 管理 GCS バケット(例:
my-gcs-bucket-name
)- GCS バケットは、ワークショップに関連する情報を保存するために使用されます。この情報は、ブートストラップ ワークショップ スクリプト中に作成されたすべてのリソースを正常に削除するために、cleanup_workshop.sh スクリプトによって使用されます。ワークショップを作成する管理者には、このバケットに対する読み取り/書き込み権限が必要です。
ブートストラップ ワークショップ スクリプトは、上記の値を使用し、setup-terraform-admin-project.sh スクリプトを呼び出すラッパー スクリプトとして機能します。setup-terraform-admin-project.sh スクリプトは、1 人のユーザーのワークショップ環境を作成します。
ワークショップのブートストラップに必要な管理者権限
このワークショップには 2 種類のユーザーが参加します。このワークショップのリソースを作成、削除する ADMIN_USER
。2 人目は、ワークショップの手順を実施する MY_USER
です。MY_USER
は自身のリソースにのみアクセスできます。ADMIN_USER
はすべてのユーザー設定にアクセスできます。この設定を自分で作成する場合は、ADMIN_USER
と MY_USER
は同じです。教師が複数の生徒向けにこのワークショップを作成する場合、ADMIN_USER
と MY_USER
は異なります。
ADMIN_USER
には、次の組織レベルの権限が必要です。
- オーナー - 組織内のすべてのプロジェクトに対するプロジェクト オーナー権限。
- フォルダ管理者 - 組織内のフォルダを作成、削除できます。各ユーザーは、プロジェクト内のすべてのリソースを含む 1 つのフォルダを取得します。
- 組織管理者
- プロジェクト作成者 - 組織内でプロジェクトを作成できます。
- プロジェクト削除 - 組織内のプロジェクトを削除する権限。
- プロジェクト IAM 管理者 - 組織内のすべてのプロジェクトで IAM ルールを作成できます。
これらに加えて、ADMIN_USER
は、ワークショップに使用する請求 ID の課金管理者でもある必要があります。
ワークショップを実施するユーザー スキーマと権限
組織内のユーザー(自分以外)向けにこのワークショップを作成する場合は、MY_USERs
のユーザー命名規則に従う必要があります。bootstrap_workshop.sh スクリプトを実行する際、開始番号とエンドユーザー番号を指定します。これらの番号は、次のユーザー名の作成に使用されます。
user<3 digit user number>@<organization_name>
たとえば、yourcompany.com という組織に、開始ユーザー番号 1、エンドユーザー番号 3 でブートストラップ ワークショップ スクリプトを実行すると、次のユーザーのワークショップ環境が作成されます。
user001@yourcompany.com
user002@yourcompany.com
user003@yourcompany.com
これらのユーザー名には、setup_terraform_admin_project.sh スクリプト中に作成された特定のプロジェクトに対するプロジェクト オーナー ロールが割り当てられます。ブートストラップ スクリプトを使用するときは、このユーザー命名スキーマに従う必要があります。詳しくは、G Suite で複数のユーザーをまとめて追加する方法をご覧ください。
ワークショップに必要なツール
このワークショップは、Cloud Shell からブートストラップすることを想定しています。このワークショップには、以下のツールが必要です。
- gcloud(バージョン 270 以上)
- kubectl
- sed(Mac OS ではなく Cloud Shell/Linux 上の sed で動作)
- git(最新の状態であることを確認してください)
sudo apt update
sudo apt install git
- jq
- envsubst
- kustomize
自社用のワークショップを設定する(シングル ユーザー設定)
- Cloud Shell を開き、以下のすべての操作を Cloud Shell で実行します。以下のリンクをクリックしてください。
- 目的の管理者ユーザーで gcloud にログインしていることを確認します。
gcloud config list
WORKDIR
を作成し、ワークショップ リポジトリのクローンを作成します。
mkdir asm-workshop
cd asm-workshop
export WORKDIR=`pwd`
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git asm
- 組織名、請求 ID、ワークショップ番号、ワークショップで使用する管理者 GCS バケットを定義します。上記のセクションに記載されている、ワークショップの設定に必要な権限を確認してください。
gcloud organizations list
export ORGANIZATION_NAME=<ORGANIZATION NAME>
gcloud beta billing accounts list
export ADMIN_BILLING_ID=<ADMIN_BILLING ID>
export WORKSHOP_NUMBER=<two digit number for example 01>
export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
- bootstrap_workshop.sh スクリプトを実行します。このスクリプトが完了するまで数分かかることがあります。
cd asm
./scripts/bootstrap_workshop.sh --org-name ${ORGANIZATION_NAME} --billing-id ${ADMIN_BILLING_ID} --workshop-num ${WORKSHOP_NUMBER} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET} --set-up-for-admin
bootstrap_workshop.sh スクリプトが完了すると、組織内の各ユーザーに GCP フォルダが作成されます。フォルダ内に Terraform 管理プロジェクトが作成されます。このワークショップに必要な残りの GCP リソースの作成には、Terraform 管理プロジェクトを使用します。Terraform 管理プロジェクトで必要な API を有効にします。Cloud Build を使用して Terraform プランを適用します。Cloud Build サービス アカウントに適切な IAM ロールを付与し、GCP でリソースを作成できるようにします。最後に、Google Cloud Storage(GCS)バケットにリモート バックエンドを構成して、すべての GCP リソースの Terraform の状態を保存します。
Terraform 管理プロジェクトの Cloud Build タスクを表示するには、Terraform 管理プロジェクト ID が必要です。これは、asm ディレクトリの vars/vars.sh ファイルに保存されます。このディレクトリは、管理者として自分自身でワークショップを設定する場合にのみ保持されます。
- 変数ファイルを指定して環境変数を設定する
echo "export WORKDIR=$WORKDIR" >> $WORKDIR/asm/vars/vars.sh
source $WORKDIR/asm/vars/vars.sh
複数のユーザーを対象としたワークショップを設定する(マルチユーザー設定)
- Cloud Shell を開き、以下のすべての操作を Cloud Shell で実行します。以下のリンクをクリックしてください。
- 目的の管理者ユーザーで gcloud にログインしていることを確認します。
gcloud config list
WORKDIR
を作成し、ワークショップ リポジトリのクローンを作成します。
mkdir asm-workshop
cd asm-workshop
export WORKDIR=`pwd`
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git asm
- 組織名、請求 ID、ワークショップ番号、開始ユーザーとエンドユーザー番号、ワークショップで使用する管理者 GCS バケットを定義します。上記のセクションに記載されている、ワークショップの設定に必要な権限を確認してください。
gcloud organizations list
export ORGANIZATION_NAME=<ORGANIZATION NAME>
gcloud beta billing accounts list
export ADMIN_BILLING_ID=<BILLING ID>
export WORKSHOP_NUMBER=<two digit number for example 01>
export START_USER_NUMBER=<number for example 1>
export END_USER_NUMBER=<number greater or equal to START_USER_NUM>
export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
- bootstrap_workshop.sh スクリプトを実行します。このスクリプトが完了するまで数分かかることがあります。
cd asm
./scripts/bootstrap_workshop.sh --org-name ${ORGANIZATION_NAME} --billing-id ${ADMIN_BILLING_ID} --workshop-num ${WORKSHOP_NUMBER} --start-user-num ${START_USER_NUMBER} --end-user-num ${END_USER_NUMBER} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET}
- 管理者 GCS バケットから training.txt ファイルを取得して、Terraform プロジェクト ID を取得する。
export WORKSHOP_ID="$(date '+%y%m%d')-${WORKSHOP_NUMBER}"
gsutil cp gs://${ADMIN_STORAGE_BUCKET}/${ORGANIZATION_NAME}/${WORKSHOP_ID}/workshop.txt .
4. ラボの設定と準備
ラボパスを選択する
このワークショップのラボは、次の 2 つの方法のいずれかで実施できます。
- 「簡単に利用できるインタラクティブなスクリプト」方法
- 各手順を手動でコピーして貼り付ける方法
高速スクリプト スクリプトを使用すると、ラボごとに 1 つのインタラクティブなスクリプトを実行して、ラボのコマンドを自動的に実行し、ラボを進めることができます。コマンドはバッチで実行され、各ステップとその目的が簡潔に説明されています。各バッチの後、コマンドの次のバッチに進むように求められます。自分のペースでラボを進めることができます。高速トラック スクリプトはべき等です。つまり、これらのスクリプトを複数回実行しても同じ結果になります。
Fast Track スクリプトは、以下のように、各ラボの上部にある緑色のボックス内に表示されます。
コピー&ペースト方式は、個々のコマンド ブロックをコマンドの説明とともにコピーして貼り付ける従来の方法です。このメソッドは 1 回だけ実行することを想定しています。この方法でコマンドを再実行しても、同じ結果が得られるという保証はありません。
ラボを実施する場合は、2 つの方法のいずれかを選択してください。
Fast Track スクリプトの設定
ユーザー情報の取得
このワークショップは、ワークショップの管理者が作成した一時的なユーザー アカウント(またはラボアカウント)を使用して実施されます。ラボアカウントは、ワークショップのすべてのプロジェクトを所有します。ワークショップ管理者は、ワークショップを実施するユーザーにラボアカウントの認証情報(ユーザー名とパスワード)を提供します。ユーザーのすべてのプロジェクトの先頭に、ラボアカウントのユーザー名が付けられます。たとえば、ラボアカウント user001@yourcompany.com
の場合は、Terraform 管理プロジェクト ID が user001-200131-01-tf-abcde
となります。各ユーザーは、ワークショップ管理者から提供されたラボ アカウントでログインし、そのラボ アカウントを使用してワークショップを実施する必要があります。
- 下のリンクをクリックして Cloud Shell を開きます。
- ラボアカウントの認証情報を使用してログインします(企業アカウントや個人のアカウントでログインしないでください)。ラボのアカウントは
userXYZ@<workshop_domain>.com
のような形式です。 - このアカウントは新しいため、Google 利用規約に同意するよう求められます。[同意する] をクリックします。
4.次の画面で、チェックボックスをオンにして Google 利用規約に同意し、[Start Cloud Shell
] をクリックします。
この手順では、GCP リソースへのアクセスに使用する小さな Linux Debian VM をプロビジョニングします。各アカウントに Cloud Shell VM が割り当てられます。ラボのアカウントでログインすると、ラボアカウントの認証情報を使用してプロビジョニングされ、ログインされます。Cloud Shell に加えてコードエディタもプロビジョニングされており、構成ファイル(Terraform、YAML など)を簡単に編集できます。デフォルトでは、Cloud Shell の画面は Cloud Shell シェル環境(下部)と Cloud Code エディタ(上部)に分割されています。右上にある鉛筆アイコン とシェル プロンプト アイコン を使用すると、シェルとコードエディタを切り替えることができます。中央のセパレータ バーを上下にドラッグして各ウィンドウのサイズを手動で変更することもできます。5. このワークショップ用の WORKDIR を作成する。WORKDIR は、このワークショップのすべてのラボを実行するためのフォルダです。Cloud Shell で次のコマンドを実行して、WORKDIR を作成します。
mkdir -p ${HOME}/asm-workshop
cd ${HOME}/asm-workshop
export WORKDIR=`pwd`
- ラボアカウント ユーザーを、このワークショップで使用する変数としてエクスポートします。これは、Cloud Shell にログインしたときと同じアカウントです。
export MY_USER=<LAB ACCOUNT EMAIL PROVIDED BY THE WORKSHOP ADMIN>
# For example export MY_USER=user001@gcpworkshops.com
- WORKDIR 変数と MY_USER 変数をエコーし、次のコマンドを実行して両方が正しく設定されていることを確認します。
echo "WORKDIR set to ${WORKDIR}" && echo "MY_USER set to ${MY_USER}"
- ワークショップ リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git ${WORKDIR}/asm
5. インフラストラクチャの設定 - ユーザー ワークフロー
目標: インフラストラクチャと Istio のインストールを確認する
- ワークショップ ツールをインストールする
- ワークショップ リポジトリのクローンを作成する
Infrastructure
のインストールを確認k8s-repo
のインストールを確認- Istio のインストールを確認する
コピーして貼り付ける方法のラボの説明
ユーザー情報の取得
ワークショップを設定する管理者は、ユーザー名とパスワードの情報をユーザーに提供する必要があります。すべてのユーザーのプロジェクトの先頭にはユーザー名が付きます。たとえば、ユーザー user001@yourcompany.com
のユーザー名、Terraform 管理プロジェクト ID の user001-200131-01-tf-abcde
、残りのプロジェクト ID などです。各ユーザーは、自分のワークショップ環境にのみアクセスできます。
ワークショップに必要なツール
このワークショップは、Cloud Shell からブートストラップすることを想定しています。このワークショップには、以下のツールが必要です。
- gcloud(バージョン 270 以上)
- kubectl
- sed(Mac OS ではなく Cloud Shell/Linux 上の sed で動作)
- git(最新の状態であることを確認してください)
sudo apt update
sudo apt install git
- jq
- envsubst
- kustomize
- pv
Terraform 管理プロジェクトにアクセスする
bootstrap_workshop.sh スクリプトが完了すると、組織内の各ユーザーに GCP フォルダが作成されます。フォルダ内に Terraform 管理プロジェクトが作成されます。このワークショップに必要な残りの GCP リソースの作成には、Terraform 管理プロジェクトを使用します。setup-terraform-admin-project.sh スクリプトは、Terraform 管理プロジェクトで必要な API を有効にします。Cloud Build は、Terraform プランを適用するために使用されます。このスクリプトを使用して、Cloud Build サービス アカウントに適切な IAM ロールを付与し、GCP でリソースを作成できるようにします。最後に、リモート バックエンドを Google Cloud Storage(GCS)バケットに構成し、すべての GCP リソースの Terraform の状態を保存します。
Terraform 管理プロジェクトの Cloud Build タスクを表示するには、Terraform 管理プロジェクト ID が必要です。ブートストラップ スクリプトで指定された管理 GCS バケットに格納されます。ブートストラップ スクリプトを複数のユーザーで実行する場合、すべての Terraform 管理プロジェクト ID は GCS バケットに格納されます。
- 下のリンクをクリックして Cloud Shell を開きます([ラボの設定と準備] セクションでまだ開いていない場合)。
- kustomize を
$HOME/bin
フォルダにインストールし(まだインストールしていない場合)、$HOME/bin
フォルダを $PATH に追加します。
mkdir -p $HOME/bin
cd $HOME/bin
curl -s "https://raw.githubusercontent.com/\
kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
cd $HOME
export PATH=$PATH:${HOME}/bin
echo "export PATH=$PATH:$HOME/bin" >> $HOME/.bashrc
- pv をインストールして $HOME/bin/pv に移動します。
sudo apt-get update && sudo apt-get -y install pv
sudo mv /usr/bin/pv ${HOME}/bin/pv
- bash プロンプトを更新します。
cp $WORKDIR/asm/scripts/krompt.bash $HOME/.krompt.bash
echo "export PATH=\$PATH:\$HOME/bin" >> $HOME/.asm-workshop.bash
echo "source $HOME/.krompt.bash" >> $HOME/.asm-workshop.bash
alias asm-init='source $HOME/.asm-workshop.bash' >> $HOME/.bashrc
echo "source $HOME/.asm-workshop.bash" >> $HOME/.bashrc
source $HOME/.bashrc
- 目的のユーザー アカウントで gcloud にログインしていることを確認します。
echo "Check logged in user output from the next command is $MY_USER"
gcloud config list account --format=json | jq -r .core.account
- 次のコマンドを実行して、Terraform 管理者プロジェクト ID を取得します。
export TF_ADMIN=$(gcloud projects list | grep tf- | awk '{ print $1 }')
echo $TF_ADMIN
- ワークショップに関連するすべてのリソースは、変数として vars.sh ファイルに保管され、Terraform 管理プロジェクトの GCS バケットに格納されます。Terraform 管理プロジェクトの vars.sh ファイルを取得します。
mkdir $WORKDIR/asm/vars
gsutil cp gs://$TF_ADMIN/vars/vars.sh $WORKDIR/asm/vars/vars.sh
echo "export WORKDIR=$WORKDIR" >> $WORKDIR/asm/vars/vars.sh
- 表示されたリンクをクリックして Terraform 管理プロジェクトの Cloud Build ページを開き、ビルドが正常に完了したことを確認します。
source $WORKDIR/asm/vars/vars.sh
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_ADMIN}"
初めて Cloud コンソールにアクセスする場合は、Google 利用規約に同意します。
- [Cloud Build] ページが表示されたら、左側のナビゲーションから
History
リンクをクリックし、最新のビルドをクリックして、最初の Terraform 適用の詳細を表示します。次のリソースは、Terraform スクリプトの一部として作成されます。また、上記のアーキテクチャ図も参照してください。
- 組織内の 4 つの GCP プロジェクト。指定した請求先アカウントは、各プロジェクトに関連付けられています。
- 1 つのプロジェクトは、共有 VPC の
network host project
です。このプロジェクトには他のリソースは作成されません。 - 1 つのプロジェクトは、Istio コントロール プレーンの GKE クラスタに使用される
ops project
です。 - 2 つのプロジェクトは、それぞれのサービスに取り組む 2 つの異なる開発チームを表しています。
- 3 つの
ops
、dev1
、dev2
プロジェクトのそれぞれに 2 つの GKE クラスタが作成されます。 k8s-repo
という名前の CSR リポジトリが作成されます。このリポジトリには、Kubernetes マニフェスト ファイル用の 6 つのフォルダが含まれています。GKE クラスタごとに 1 つのフォルダ。このリポジトリは、GitOps 形式で Kubernetes マニフェストをクラスタにデプロイするために使用されます。k8s-repo
のマスター ブランチに対して commit が行われるたびに、それぞれのフォルダから GKE クラスタに Kubernetes マニフェストをデプロイするように、Cloud Build トリガーが作成されます。
terraform admin project
でビルドが完了すると、ops プロジェクトで別のビルドが開始されます。表示されたリンクをクリックしてops project
の Cloud Build ページを開き、k8s-repo Cloud Build が正常に終了したことを確認します。
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
インストールを確認する
- すべてのクラスタの kubeconfig ファイルを作成します。次のスクリプトを実行します。
$WORKDIR/asm/scripts/setup-gke-vars-kubeconfig.sh
このスクリプトにより、gke
フォルダに kubemesh
という新しい kubeconfig ファイルが作成されます。
- 新しい kubeconfig ファイルを指すように
KUBECONFIG
変数を変更します。
source $WORKDIR/asm/vars/vars.sh
export KUBECONFIG=$WORKDIR/asm/gke/kubemesh
- vars.sh 変数と KUBECONFIG 変数を Cloud Shell の .bashrc に追加して、Cloud Shell が再起動するたびに変数が取得されるようにします。
echo "source ${WORKDIR}/asm/vars/vars.sh" >> $HOME/.bashrc
echo "export KUBECONFIG=${WORKDIR}/asm/gke/kubemesh" >> $HOME/.bashrc
- クラスタ コンテキストを一覧表示します。6 つのクラスタが表示されます。
kubectl config view -ojson | jq -r '.clusters[].name'
`Output (do not copy)`
gke_tf05-01-ops_us-central1_gke-asm-2-r2-prod gke_tf05-01-ops_us-west1_gke-asm-1-r1-prod gke_tf05-02-dev1_us-west1-a_gke-1-apps-r1a-prod gke_tf05-02-dev1_us-west1-b_gke-2-apps-r1b-prod gke_tf05-03-dev2_us-central1-a_gke-3-apps-r2a-prod gke_tf05-03-dev2_us-central1-b_gke-4-apps-r2b-prod
Istio のインストールを確認する
- すべての Pod が実行されており、ジョブが完了したことを確認して、Istio が両方のクラスタにインストールされていることを確認します。
kubectl --context ${OPS_GKE_1} get pods -n istio-system
kubectl --context ${OPS_GKE_2} get pods -n istio-system
`Output (do not copy)`
NAME READY STATUS RESTARTS AGE grafana-5f798469fd-z9f98 1/1 Running 0 6m21s istio-citadel-568747d88-qdw64 1/1 Running 0 6m26s istio-egressgateway-8f454cf58-ckw7n 1/1 Running 0 6m25s istio-galley-6b9495645d-m996v 2/2 Running 0 6m25s istio-ingressgateway-5df799fdbd-8nqhj 1/1 Running 0 2m57s istio-pilot-67fd786f65-nwmcb 2/2 Running 0 6m24s istio-policy-74cf89cb66-4wrpl 2/2 Running 1 6m25s istio-sidecar-injector-759bf6b4bc-mw4vf 1/1 Running 0 6m25s istio-telemetry-77b6dfb4ff-zqxzz 2/2 Running 1 6m24s istio-tracing-cd67ddf8-n4d7k 1/1 Running 0 6m25s istiocoredns-5f7546c6f4-g7b5c 2/2 Running 0 6m39s kiali-7964898d8c-5twln 1/1 Running 0 6m23s prometheus-586d4445c7-xhn8d 1/1 Running 0 6m25s
`Output (do not copy)`
NAME READY STATUS RESTARTS AGE grafana-5f798469fd-2s8k4 1/1 Running 0 59m istio-citadel-568747d88-87kdj 1/1 Running 0 59m istio-egressgateway-8f454cf58-zj9fs 1/1 Running 0 60m istio-galley-6b9495645d-qfdr6 2/2 Running 0 59m istio-ingressgateway-5df799fdbd-2c9rc 1/1 Running 0 60m istio-pilot-67fd786f65-nzhx4 2/2 Running 0 59m istio-policy-74cf89cb66-4bc7f 2/2 Running 3 59m istio-sidecar-injector-759bf6b4bc-grk24 1/1 Running 0 59m istio-telemetry-77b6dfb4ff-6zr94 2/2 Running 4 60m istio-tracing-cd67ddf8-grs9g 1/1 Running 0 60m istiocoredns-5f7546c6f4-gxd66 2/2 Running 0 60m kiali-7964898d8c-nhn52 1/1 Running 0 59m prometheus-586d4445c7-xr44v 1/1 Running 0 59m
- 両方の
dev1
クラスタに Istio がインストールされていることを確認します。dev1
クラスタでは、Citadel、サイドカー インジェクタ、coredns のみが実行されます。これらのインスタンスは、ops-1 クラスタで実行されている Istio コントロール プレーンを共有します。
kubectl --context ${DEV1_GKE_1} get pods -n istio-system
kubectl --context ${DEV1_GKE_2} get pods -n istio-system
- 両方の
dev2
クラスタに Istio がインストールされていることを確認します。dev2
クラスタでは、Citadel、サイドカー インジェクタ、coredns のみが実行されます。これらのインスタンスは、ops-2 クラスタで実行されている Istio コントロール プレーンを共有します。
kubectl --context ${DEV2_GKE_1} get pods -n istio-system
kubectl --context ${DEV2_GKE_2} get pods -n istio-system
`Output (do not copy)`
NAME READY STATUS RESTARTS AGE istio-citadel-568747d88-4lj9b 1/1 Running 0 66s istio-sidecar-injector-759bf6b4bc-ks5br 1/1 Running 0 66s istiocoredns-5f7546c6f4-qbsqm 2/2 Running 0 78s
共有コントロール プレーンのサービス ディスカバリを確認する
- 必要に応じて、シークレットがデプロイされていることを確認します。
kubectl --context ${OPS_GKE_1} get secrets -l istio/multiCluster=true -n istio-system
kubectl --context ${OPS_GKE_2} get secrets -l istio/multiCluster=true -n istio-system
`Output (do not copy)`
For OPS_GKE_1: NAME TYPE DATA AGE gke-1-apps-r1a-prod Opaque 1 8m7s gke-2-apps-r1b-prod Opaque 1 8m7s gke-3-apps-r2a-prod Opaque 1 44s gke-4-apps-r2b-prod Opaque 1 43s For OPS_GKE_2: NAME TYPE DATA AGE gke-1-apps-r1a-prod Opaque 1 40s gke-2-apps-r1b-prod Opaque 1 40s gke-3-apps-r2a-prod Opaque 1 8m4s gke-4-apps-r2b-prod Opaque 1 8m4s
このワークショップでは、すべての GKE クラスタが作成される単一の共有 VPC を使用します。クラスタ間で Service を検出するには、オペレーション クラスタで Secret として作成された kubeconfig ファイル(各アプリケーション クラスタ用)を使用します。Pilot はこれらの Secret を使用して、(上記の Secret で認証された)アプリケーション クラスタの Kube API サーバーに対してクエリを実行し、Service を検出します。どちらの Ops クラスタも、kubeconfig によって作成された Secret を使用して、すべてのアプリ クラスタに対して認証できることがわかります。Ops クラスタは、kubeconfig ファイルをシークレット メソッドとして使用して、サービスを自動的に検出できます。そのためには、運用クラスタの Pilot が、他のすべてのクラスタの Kube API サーバーにアクセスできる必要があります。パイロットが Kube API サーバーにアクセスできない場合は、リモート サービスを ServiceEntries として手動で追加します。ServiceEntry は、サービス レジストリ内の DNS エントリと考えることができます。ServiceEntry は、完全修飾 DNS 名(FQDN)と到達可能な IP アドレスを使用してサービスを定義します。詳細については、Istio マルチクラスタのドキュメントをご覧ください。
6. インフラストラクチャ リポジトリの説明
インフラストラクチャ Cloud Build
ワークショップ用の GCP リソースは、Cloud Build と infrastructure
CSR リポジトリを使用して構築されています。ローカル ターミナルからブートストラップ スクリプト(scripts/bootstrap_workshop.sh
にあります)を実行しました。ブートストラップ スクリプトは、GCP フォルダ、Terraform 管理プロジェクト、Cloud Build サービス アカウント用の適切な IAM 権限を作成します。Terraform 管理プロジェクトは、Terraform の状態、ログ、その他のスクリプトを保存するために使用されます。これには、infrastructure
リポジトリと k8s_repo
CSR リポジトリが含まれています。これらのリポジトリについては、次のセクションで詳しく説明します。Terraform 管理プロジェクトに他のワークショップ リソースは組み込まれません。Terraform 管理プロジェクトの Cloud Build サービス アカウントは、ワークショップ用のリソースを構築するために使用されます。
infrastructure
フォルダにある cloudbuild.yaml
ファイルは、ワークショップ用の GCP リソースを作成するために使用されます。GCP リソースの作成に必要なすべてのツールを含むカスタム ビルダー イメージが作成されます。これらのツールには、gcloud SDK、Terraform、その他のユーティリティ(python、git、jq など)が含まれます。カスタム ビルダー イメージは、各リソースの terraform plan
と apply
を実行します。各リソースの Terraform ファイルは別々のフォルダにあります(詳細は次のセクションで説明します)。リソースは、通常のビルド方法の順に 1 つずつ構築されます(たとえば、プロジェクト内にリソースを作成する前に、GCP プロジェクトがビルドされます)。詳しくは、cloudbuild.yaml
ファイルをご確認ください。
Cloud Build は、infrastructure
リポジトリに commit があるたびにトリガーされます。インフラストラクチャに加えられた変更はすべて Infrastructure as Code(IaC)として保存され、リポジトリに commit されます。ワークショップの状態は常にこのリポジトリに保存されます。
フォルダ構造 - チーム、環境、リソース
インフラストラクチャ リポジトリは、ワークショップ用の GCP インフラストラクチャ リソースを設定します。フォルダとサブフォルダという構造になっています。リポジトリ内のベースフォルダは、特定の GCP リソースを所有する team
を表します。フォルダの次のレイヤは、チームの特定の environment
を表します(dev、stage、prod など)。環境内のフォルダの次のレイヤは、特定の resource
を表します(host_project、gke_clusters など)。必要なスクリプトと Terraform ファイルはリソース フォルダ内にあります。
このワークショップでは、次の 4 種類のチームが参加します。
- infrastructure - クラウド インフラストラクチャ チームを表します。他のチームのために GCP リソースを作成する役割を担います。リソースには Terraform 管理プロジェクトを使用します。インフラストラクチャ リポジトリ自体と Terraform の状態ファイル(以下で説明)は、Terraform 管理プロジェクト内にあります。これらのリソースは、ブートストラップ プロセス中に bash スクリプトによって作成されます(詳細については、「モジュール 0 - 管理者ワークフロー」をご覧ください)。
- network - ネットワーキング チームを表します。VPC リソースとネットワーキング リソースを担当します。オーナーには次の GCP リソースがあります。
host project
- 共有 VPC ホスト プロジェクトを表します。shared VPC
- 共有 VPC、サブネット、セカンダリ IP 範囲、ルート、ファイアウォール ルールを表します。- ops - 運用/開発チームを表します。このチームは以下のリソースを所有しています。
ops project
- すべての op リソースのプロジェクトを表します。gke clusters
- リージョンごとの Ops GKE クラスタ。Istio コントロール プレーンは、Ops の各 GKE クラスタにインストールされます。k8s-repo
- すべての GKE クラスタの GKE マニフェストを含む CSR リポジトリ。- apps - アプリケーション チームを表します。このワークショップでは、
app1
とapp2
の 2 つのチームをシミュレートします。このチームは以下のリソースを所有しています。 app projects
- すべてのアプリチームに独自のプロジェクト セットが割り当てられます。これにより、特定のプロジェクトに対する請求と IAM を制御できます。gke clusters
- アプリケーション コンテナ/Pod が実行されるアプリケーション クラスタです。gce instances
- GCE インスタンスで実行するアプリケーションがある場合(省略可)。このワークショップの app1 には、アプリケーションの一部が実行される GCE インスタンスがいくつかあります。
このワークショップでは、同じアプリ(Hipster Shop アプリ)で app1 と app2 の両方を表します。
プロバイダ、状態、出力 - バックエンドと共有状態
google
プロバイダと google-beta
プロバイダは gcp/[environment]/gcp/provider.tf
にあります。provider.tf
ファイルはすべてのリソース フォルダでシンボリック リンクされます。これにより、リソースごとにプロバイダを個別に管理するのではなく、プロバイダを 1 か所で変更できます。
すべてのリソースには、リソースの tfstate ファイルの場所を定義する backend.tf
ファイルが含まれています。この backend.tf
ファイルは、スクリプト(scripts/setup_terraform_admin_project
にあります)を使用してテンプレート(templates/backend.tf_tmpl
にあります)から生成され、それぞれのリソース フォルダに配置されます。バックエンドには Google Cloud Storage(GCS)バケットを使用します。GCS バケット フォルダ名がリソース名と一致している。すべてのリソース バックエンドは Terraform 管理プロジェクト内にあります。
値が相互に依存するリソースには output.tf
ファイルが含まれます。必要な出力値は、その特定のリソースのバックエンドで定義された tfstate ファイルに保存されます。たとえば、プロジェクトに GKE クラスタを作成するには、プロジェクト ID が必要です。プロジェクト ID は output.tf を介して tfstate ファイルに出力されます。tfstate は GKE クラスタ リソースの terraform_remote_state
データソースを介して使用できます。
shared_state ファイルは、リソースの tfstate ファイルを指す terraform_remote_state
データソースです。他のリソースからの出力を必要とするリソース フォルダに shared_state_[resource_name].tf
ファイルが存在する。たとえば、ops_gke
リソース フォルダには、ops_project
リソースと shared_vpc
リソースの shared_state ファイルがあります。これは、ops プロジェクトで GKE クラスタを作成するには、プロジェクト ID と VPC の詳細が必要なためです。shared_state ファイルは、スクリプト(scripts/setup_terraform_admin_project
にあります)を使用してテンプレート(templates/shared_state.tf_tmpl
にあります)から生成されます。すべてのリソースshared_state ファイルは gcp/[environment]/shared_states
フォルダに配置されます。必要な shared_state ファイルは、それぞれのリソース フォルダでシンボリック リンクされます。すべての shared_state ファイルを 1 つのフォルダに配置し、それらを適切なリソース フォルダにシンボリック リンクすることで、すべての状態ファイルを 1 か所で簡単に管理できます。
変数
すべてのリソース値は環境変数として格納されます。これらの変数は、Terraform 管理プロジェクトの GCS バケットにある vars.sh
というファイルに(エクスポート ステートメントとして)保存されます。これには、組織 ID、請求先アカウント、プロジェクト ID、GKE クラスタの詳細などが含まれます。設定の値を取得するには、任意のターミナルから vars.sh
をダウンロードして取得します。
Terraform 変数は vars.sh
に TF_VAR_[variable name]
として保存されます。これらの変数を使用して、それぞれのリソース フォルダに variables.tfvars
ファイルを生成します。variables.tfvars
ファイルには、すべての変数とその値が含まれています。variables.tfvars
ファイルは、スクリプト(scripts/setup_terraform_admin_project
にあります)を使用して、同じフォルダにあるテンプレート ファイルから生成されます。
K8s リポジトリの説明
k8s_repo
は、Terraform 管理プロジェクトにある CSR リポジトリ(インフラストラクチャ リポジトリとは別の)です。GKE マニフェストを保存してすべての GKE クラスタに適用するために使用されます。k8s_repo
はインフラストラクチャ Cloud Build によって作成されます(詳細については、前のセクションをご覧ください)。インフラストラクチャの初期 Cloud Build プロセスでは、合計 6 つの GKE クラスタが作成されます。k8s_repo
に、6 つのフォルダが作成されます。各フォルダ(GKE クラスタ名と一致する名前)は、それぞれのリソース マニフェスト ファイルを含む GKE クラスタに対応しています。インフラストラクチャの構築と同様に、Cloud Build を使用して k8s_repo を使用して Kubernetes マニフェストをすべての GKE クラスタに適用します。k8s_repo
リポジトリに commit が行われるたびに Cloud Build がトリガーされます。インフラストラクチャと同様に、すべての Kubernetes マニフェストは k8s_repo
リポジトリにコードとして保存され、各 GKE クラスタの状態は常にそれぞれのフォルダに保存されます。
初期インフラストラクチャの構築の一環として、k8s_repo
が作成され、すべてのクラスタに Istio がインストールされます。
プロジェクト、GKE クラスタ、Namespace
このワークショップのリソースは複数の GCP プロジェクトに分けられます。プロジェクトは、会社の組織(またはチーム)構造と一致している必要があります。組織内のさまざまなプロジェクト/プロダクト/リソースを担当するチームがそれぞれ異なる GCP プロジェクトを使用している。プロジェクトを分けることで、個別の IAM 権限セットを作成し、プロジェクト レベルで請求を管理できます。また、割り当てはプロジェクト レベルでも管理されます。
このワークショップでは 5 つのチームが構成され、それぞれに独自のプロジェクトがあります。
- GCP リソースを構築するインフラストラクチャ チームは
Terraform admin project
を使用します。CSR リポジトリ(infrastructure
)でインフラストラクチャをコードとして管理し、GCP で構築されたリソースに関するすべての Terraform の状態情報を GCS バケットに保存します。CSR リポジトリと Terraform 状態の GCS バケットへのアクセスを制御します。 host project
は、共有 VPC を構築するネットワーク チームが使用します。このプロジェクトには、VPC、サブネット、ルート、ファイアウォール ルールが含まれます。共有 VPC を使用することで、GCP リソースのネットワーキングを一元管理できます。すべてのプロジェクトで、ネットワーキング用にこの単一の共有 VPC を使用しました。ops project
は、GKE クラスタと ASM/Istio コントロール プレーンを構築する運用/プラットフォーム チームが使用します。GKE クラスタとサービス メッシュのライフサイクルを管理します。クラスタの強化、Kubernetes プラットフォームの復元力とスケールの管理を担当します。このワークショップでは、GitOps 手法を使用してリソースを Kubernetes にデプロイします。CSR リポジトリ(k8s_repo
)は ops プロジェクトにあります。- アプリケーションを構築する dev1 および dev2 チーム(2 つの開発チーム)は、独自の
dev1
とdev2 projects
を使用します。これらは、貴社が顧客に提供するアプリケーションとサービスです。これらは、運用チームが管理するプラットフォーム上に構築されています。リソース(Deployment、Service など)がk8s_repo
に push され、適切なクラスタにデプロイされます。このワークショップは CI/CD のベスト プラクティスとツールに重点を置かないことに注意してください。Cloud Build を使用して、Kubernetes リソースを GKE クラスタに直接デプロイします。実際の本番環境シナリオでは、適切な CI/CD ソリューションを使用して GKE クラスタにアプリケーションをデプロイします。
このワークショップでは、2 種類の GKE クラスタを使用します。
- 運用クラスタ - 運用チームが DevOps ツールを実行するために使用します。このワークショップでは、ASM/Istio コントロール プレーンを実行して、サービス メッシュを管理します。
- アプリケーション(アプリ)クラスタ - 開発チームがアプリケーションを実行するために使用します。このワークショップでは、Hipster Shop アプリを使用します。
アプリケーションを実行するクラスタから運用/管理ツールを分離することで、各リソースのライフサイクルを個別に管理できます。この 2 種類のクラスタは、それを使用するチーム/プロダクトに関連するプロジェクトにも存在するため、IAM 権限の管理も容易になります。
合計 6 つの GKE クラスタがあります。オペレーション プロジェクトに 2 つのリージョン オペレーション クラスタが作成されます。ASM/Istio コントロール プレーンは、両方の運用クラスタにインストールされます。各 Ops クラスタは異なるリージョンにあります。さらに、4 つのゾーン アプリケーション クラスタがあります。これらは独自のプロジェクトで作成されます。このワークショップでは、独自のプロジェクトを持つ 2 つの開発チームをシミュレートします。各プロジェクトには 2 つのアプリクラスタが含まれます。アプリクラスタは、異なるゾーンにあるゾーンクラスタです。4 つのアプリクラスタは、2 つのリージョンと 4 つのゾーンに配置されています。このようにして、リージョンとゾーンの冗長性を確保します。
このワークショップで使用するアプリケーション、Hipster Shop アプリを、4 つのアプリクラスタすべてにデプロイします。各マイクロサービスは、すべてのアプリクラスタの独自の Namespace に存在します。また、Hipster ショップ アプリの Deployment(Pod)は Ops クラスタにデプロイされません。ただし、すべてのマイクロサービスの Namespace と Service リソースも ops クラスタ内に作成されます。ASM/Istio コントロール プレーンは、サービス ディスカバリに Kubernetes サービス レジストリを使用します。(オペレーション クラスタに)Service がない場合、アプリクラスタで実行されているサービスごとに ServiceEntry を手動で作成する必要があります。
このワークショップでは、10 階層のマイクロサービス アプリケーションをデプロイします。このアプリケーションは、「Hipster Shop」ユーザーが商品を閲覧してカートに追加し、購入できるようにします。
Kubernetes マニフェストと k8s_repo
k8s_repo
を使用して、すべての GKE クラスタに Kubernetes リソースを追加します。これを行うには、Kubernetes マニフェストをコピーして、k8s_repo
に commit します。k8s_repo
に対するすべての commit により、Kubernetes マニフェストがそれぞれのクラスタにデプロイされる Cloud Build ジョブがトリガーされます。各クラスタのマニフェストは、クラスタ名と同じ名前の個別のフォルダにあります。
6 つのクラスタ名は次のとおりです。
- gke-asm-1-r1-prod - リージョン 1 のリージョン オペレーション クラスタ
- gke-asm-2-r2-prod - リージョン 2 のリージョン オペレーション クラスタ
- gke-1-apps-r1a-prod - リージョン 1 ゾーン a のアプリクラスタ
- gke-2-apps-r1b-prod - リージョン 1 ゾーン b のアプリクラスタ
- gke-3-apps-r2a-prod - リージョン 2 ゾーン a のアプリクラスタ
- gke-4-apps-r2b-prod - リージョン 2 ゾーン b のアプリクラスタ
k8s_repo
には、これらのクラスタに対応するフォルダがあります。これらのフォルダに配置されたマニフェストは、対応する GKE クラスタに適用されます。管理しやすいように、各クラスタのマニフェストはサブフォルダ(クラスタのメインフォルダ内)に配置されます。このワークショップでは、Kustomize を使用して、デプロイされたリソースを追跡します。詳細については、Kustomize の公式ドキュメントをご覧ください。
7. サンプルアプリをデプロイする
目標: Hipster ショップ アプリをアプリクラスタにデプロイする
k8s-repo
のクローン- Hipster ショップのマニフェストをすべてのアプリ クラスタにコピーする
- オペレーション クラスタで Hipster ショップ アプリ用の Service を作成する
- Ops クラスタで
loadgenerators
を設定してグローバル接続をテストする - Hipster Shop アプリへの安全な接続を確認する
コピーして貼り付ける方法のラボの説明
ops プロジェクトのソース リポジトリのクローンを作成する
最初の Terraform インフラストラクチャ構築の一環として、Ops プロジェクトに k8s-repo
がすでに作成されています。
- Git リポジトリ用の空のディレクトリを作成します。
mkdir $WORKDIR/k8s-repo
- git リポジトリを初期化し、リモート リポジトリからマスターを pull して追加します。
cd $WORKDIR/k8s-repo
git init && git remote add origin \
https://source.developers.google.com/p/$TF_VAR_ops_project_name/r/k8s-repo
- ローカル Git ローカル構成を設定します。
git config --local user.email $MY_USER
git config --local user.name "K8s repo user"
git config --local \
credential.'https://source.developers.google.com'.helper gcloud.sh
git pull origin master
マニフェストのコピー、commit と push
- Hipster Shop の名前空間とサービスをすべてのクラスタのソース リポジトリにコピーします。
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/.
- アプリフォルダ kustomization.yaml をすべてのクラスタにコピーします。
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/
- Hipster Shop の Deployment、RBAC、PodSecurityPolicy をアプリクラスタのソース リポジトリにコピーします。
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
- 1 つを除くすべての開発クラスタから、cartservice Deployment、rbac、podsecuritypolicy を削除します。また、Hipstershop はマルチクラスタ デプロイ用に構築されていないため、一貫性のない結果を避けるために、カートサービスは 1 つだけです。
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/rbac/cart-rbac.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/rbac/cart-rbac.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/rbac/cart-rbac.yaml
- 最初の開発クラスタ内の kustomization.yaml にのみ、cartservice Deployment、rbac、podsecuritypolicy を追加します。
cd ${WORKDIR}/k8s-repo/${DEV1_GKE_1_CLUSTER}/app
cd deployments && kustomize edit add resource app-cart-service.yaml
cd ../podsecuritypolicies && kustomize edit add resource cart-psp.yaml
cd ../rbac && kustomize edit add resource cart-rbac.yaml
cd ${WORKDIR}/asm
- オペレーション クラスタ kustomization.yaml から podsecuritypolicies、deployments、rbac ディレクトリを削除します
sed -i -e '/- deployments\//d' -e '/- podsecuritypolicies\//d' \
-e '/- rbac\//d' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/kustomization.yaml
sed -i -e '/- deployments\//d' -e '/- podsecuritypolicies\//d' \
-e '/- rbac\//d' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/kustomization.yaml
- RBAC マニフェストの PROJECT_ID を置き換えます。
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev1_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV1_GKE_1_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev1_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV1_GKE_2_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev2_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV2_GKE_1_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev2_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV2_GKE_2_CLUSTER}/app/rbac/*
- IngressGateway と VirtualService のマニフェストを Ops クラスタのソース リポジトリにコピーします。
cp -r $WORKDIR/asm/k8s_manifests/prod/app-ingress/* \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-ingress/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-ingress/* \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-ingress/
- Config Connector リソースを各プロジェクトのクラスタのいずれかにコピーします。
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-cnrm/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app-cnrm/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app-cnrm/
- Config Connector マニフェストの PROJECT_ID を置き換えます。
sed -i 's/${PROJECT_ID}/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-cnrm/*
sed -i 's/${PROJECT_ID}/'$TF_VAR_dev1_project_name'/g' \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app-cnrm/*
sed -i 's/${PROJECT_ID}/'$TF_VAR_dev2_project_name'/g' \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app-cnrm/*
loadgenerator
マニフェスト(Deployment、PodSecurityPolicy、RBAC)を Ops クラスタにコピーします。また、Hipster ショップ アプリは、グローバル Google Cloud ロードバランサ(GCLB)を使用して公開されます。GCLB は(frontend
を宛先とする)クライアント トラフィックを受信し、Service の最も近いインスタンスに送信します。両方の Ops クラスタにloadgenerator
を設定すると、Ops クラスタで実行されている両方の Istio Ingress ゲートウェイにトラフィックが送信されます。ロード バランシングについては、次のセクションで詳しく説明します。
cp -r $WORKDIR/asm/k8s_manifests/prod/app-loadgenerator/. \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-loadgenerator/. \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/.
- 両方の Ops クラスタの
loadgenerator
マニフェストの ops プロジェクト ID を置き換えます。
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/loadgenerator-deployment.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/loadgenerator-rbac.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/loadgenerator-deployment.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/loadgenerator-rbac.yaml
- 両方の ops クラスタの kustomization.yaml に
loadgenerator
リソースを追加します。
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/
kustomize edit add resource loadgenerator-psp.yaml
kustomize edit add resource loadgenerator-rbac.yaml
kustomize edit add resource loadgenerator-deployment.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/
kustomize edit add resource loadgenerator-psp.yaml
kustomize edit add resource loadgenerator-rbac.yaml
kustomize edit add resource loadgenerator-deployment.yaml
k8s-repo
に commit します。
cd $WORKDIR/k8s-repo
git add . && git commit -am "create app namespaces and install hipster shop"
git push --set-upstream origin master
- Ops プロジェクトの Cloud Build のステータスを表示するには、以前に開いたタブを使用するか、次のリンクをクリックします。
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
アプリケーションのデプロイを確認する
- カートを除くすべてのアプリケーションの Namespace の Pod が、すべての開発クラスタで Running 状態であることを確認します。
for ns in ad checkout currency email frontend payment product-catalog recommendation shipping; do
kubectl --context $DEV1_GKE_1 get pods -n $ns;
kubectl --context $DEV1_GKE_2 get pods -n $ns;
kubectl --context $DEV2_GKE_1 get pods -n $ns;
kubectl --context $DEV2_GKE_2 get pods -n $ns;
done;
Output (do not copy)
NAME READY STATUS RESTARTS AGE currencyservice-5c5b8876db-pvc6s 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE currencyservice-5c5b8876db-xlkl9 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE currencyservice-5c5b8876db-zdjkg 2/2 Running 0 115s NAME READY STATUS RESTARTS AGE currencyservice-5c5b8876db-l748q 2/2 Running 0 82s NAME READY STATUS RESTARTS AGE emailservice-588467b8c8-gk92n 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE emailservice-588467b8c8-rvzk9 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE emailservice-588467b8c8-mt925 2/2 Running 0 117s NAME READY STATUS RESTARTS AGE emailservice-588467b8c8-klqn7 2/2 Running 0 84s NAME READY STATUS RESTARTS AGE frontend-64b94cf46f-kkq7d 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE frontend-64b94cf46f-lwskf 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE frontend-64b94cf46f-zz7xs 2/2 Running 0 118s NAME READY STATUS RESTARTS AGE frontend-64b94cf46f-2vtw5 2/2 Running 0 85s NAME READY STATUS RESTARTS AGE paymentservice-777f6c74f8-df8ml 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE paymentservice-777f6c74f8-bdcvg 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE paymentservice-777f6c74f8-jqf28 2/2 Running 0 117s NAME READY STATUS RESTARTS AGE paymentservice-777f6c74f8-95x2m 2/2 Running 0 86s NAME READY STATUS RESTARTS AGE productcatalogservice-786dc84f84-q5g9p 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE productcatalogservice-786dc84f84-n6lp8 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE productcatalogservice-786dc84f84-gf9xl 2/2 Running 0 119s NAME READY STATUS RESTARTS AGE productcatalogservice-786dc84f84-v7cbr 2/2 Running 0 86s NAME READY STATUS RESTARTS AGE recommendationservice-5fdf959f6b-2ltrk 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE recommendationservice-5fdf959f6b-dqd55 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE recommendationservice-5fdf959f6b-jghcl 2/2 Running 0 119s NAME READY STATUS RESTARTS AGE recommendationservice-5fdf959f6b-kkspz 2/2 Running 0 87s NAME READY STATUS RESTARTS AGE shippingservice-7bd5f569d-qqd9n 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE shippingservice-7bd5f569d-xczg5 2/2 Running 0 13m NAME READY STATUS RESTARTS AGE shippingservice-7bd5f569d-wfgfr 2/2 Running 0 2m NAME READY STATUS RESTARTS AGE shippingservice-7bd5f569d-r6t8v 2/2 Running 0 88s
- カートの Namespace 内の Pod が最初の開発クラスタでのみ実行状態であることを確認します。
kubectl --context $DEV1_GKE_1 get pods -n cart;
Output (do not copy)
NAME READY STATUS RESTARTS AGE cartservice-659c9749b4-vqnrd 2/2 Running 0 17m
Hipster Shop アプリにアクセスする
グローバル ロード バランシング
これで、Hipster Shop アプリが 4 つのアプリクラスタすべてにデプロイされました。これらのクラスタは、2 つのリージョンと 4 つのゾーンにあります。クライアントは、frontend
サービスにアクセスすることで、Hipster ショップ アプリにアクセスできます。frontend
サービスは、4 つのアプリクラスタすべてで実行されます。Google Cloud ロードバランサ(GCLB)は、frontend
サービスの 4 つのインスタンスすべてにクライアント トラフィックを送信するために使用されます。
Istio Ingress ゲートウェイは Ops クラスタでのみ実行され、リージョン内の 2 つのゾーン アプリケーション クラスタに対するリージョン ロードバランサとして機能します。GCLB は、2 つの Istio Ingress ゲートウェイ(2 つの op クラスタで実行)をグローバル フロントエンド サービスへのバックエンドとして使用します。Istio Ingress ゲートウェイは GCLB からクライアント トラフィックを受信し、そのクライアント トラフィックをアプリケーション クラスタで実行されているフロントエンド Pod に送信します。
また、Istio Ingress ゲートウェイをアプリケーション クラスタに直接配置し、GCLB でバックエンドとして使用することもできます。
GKE Autoneg コントローラ
Istio Ingress ゲートウェイ Kubernetes Service は、ネットワーク エンドポイント グループ(NEG)を使用して GCLB のバックエンドとして自身を登録します。NEG を使用すると、GCLB を使用したコンテナ ネイティブのロード バランシングが可能になります。NEG は、Kubernetes Service の特別なアノテーションを使用して作成されるため、NEG コントローラに登録できます。Autoneg コントローラは、NEG の作成を自動化する特別な GKE コントローラであり、Service アノテーションを使用して NEG をバックエンドとして GCLB に割り当てます。Istio Ingress ゲートウェイを含む Istio コントロール プレーンは、Terraform Cloud Build の初期インフラストラクチャ中にデプロイされます。GCLB と autoNEG の構成は、初期の Terraform インフラストラクチャ Cloud Build の一部として行われます。
Cloud Endpoints とマネージド証明書を使用して Ingress を保護する
GCP マネージド証明書は、frontend
GCLB サービスへのクライアント トラフィックを保護するために使用されます。GCLB はグローバル frontend
サービスにマネージド証明書を使用し、証明書は GCLB で終端されます。このワークショップでは、マネージド証明書のドメインとして Cloud Endpoints を使用します。また、ドメインと frontend
の DNS 名を使用して GCP マネージド証明書を作成することもできます。
- Hipster ショップにアクセスするには、次のコマンドのリンク出力をクリックします。
echo "https://frontend.endpoints.$TF_VAR_ops_project_name.cloud.goog"
- 証明書が有効かどうかを確認するには、Chrome タブの URL バーにある鍵アイコンをクリックします。
グローバル ロード バランシングを確認する
アプリケーションのデプロイの一環として、両方のオペレーション クラスタに負荷生成ツールがデプロイされ、GCLBHipster ショップの Cloud Endpoints リンクへのテスト トラフィックが生成されます。GCLB がトラフィックを受信し、両方の Istio Ingress ゲートウェイに送信していることを確認します。
- GCLB を入手 >Hipster ショップ GCLB が作成される Ops プロジェクトの Monitoring リンク。
echo "https://console.cloud.google.com/net-services/loadbalancing/details/http/istio-ingressgateway?project=$TF_VAR_ops_project_name&cloudshell=false&tab=monitoring&duration=PT1H"
- 以下に示すように、[バックエンド] プルダウン メニューで [すべてのバックエンド] から [istio-ingressgateway] に変更します。
istio-ingressgateways
の両方に送信されるトラフィックを確認します。
istio-ingressgateway
ごとに 3 つの NEG が作成されます。Ops クラスタはリージョン クラスタであるため、リージョン内のゾーンごとに 1 つの NEG が作成されます。一方、istio-ingressgateway
Pod はリージョンごとに単一のゾーンで実行されます。istio-ingressgateway
Pod に送信されるトラフィックが表示されています。
両方のオペレーション クラスタで負荷生成ツールが実行され、それらが存在する 2 つのリージョンからのクライアント トラフィックをシミュレートします。Ops クラスタ リージョン 1 で生成された負荷をリージョン 2 の istio-ingressgateway
に送信しています。同様に、Ops クラスタ リージョン 2 で生成された負荷はリージョン 2 の istio-ingressgateway
に送信されています。
8. Stackdriver によるオブザーバビリティ
目標: Istio テレメトリーを Stackdriver に接続して検証する。
istio-telemetry
リソースをインストールする- Istio Services ダッシュボードを作成/更新する
- コンテナのログを表示
- Stackdriver で分散トレースを表示する
コピーして貼り付ける方法のラボの説明
Istio の主な機能の一つに、組み込みのオブザーバビリティ(「o11y」)があります。つまり、ブラックボックスで計測されていないコンテナであっても、オペレーターはこれらのコンテナに出入りするトラフィックを観察し、顧客にサービスを提供できます。この観測値は、指標、ログ、トレースといういくつかの異なる手法の形をとります。
また、Hipster Shop に組み込みの負荷生成システムも使用します。オブザーバビリティは、トラフィックのない静的システムではあまりうまく機能しないため、負荷を生成することで、その動作を確認できます。この読み込みはすでに実行されているので、このように確認できます。
- Istio を Stackdriver 構成ファイルにインストールします。
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-telemetry
kustomize edit add resource istio-telemetry.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-telemetry
kustomize edit add resource istio-telemetry.yaml
- k8s-repo に commit します。
cd $WORKDIR/k8s-repo
git add . && git commit -am "Install istio to stackdriver configuration"
git push
- Ops プロジェクトの Cloud Build のステータスを表示するには、以前に開いたタブを使用するか、次のリンクをクリックします。
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
- Istio → Stackdriver の統合を確認し、Stackdriver Handler CRD を取得します。
kubectl --context $OPS_GKE_1 get handler -n istio-system
出力に stackdriver という名前のハンドラが表示されます。
NAME AGE kubernetesenv 12d prometheus 12d stackdriver 69s # <== NEW!
- Stackdriver への Istio 指標のエクスポートが機能していることを確認します。このコマンドの出力のリンクをクリックします。
echo "https://console.cloud.google.com/monitoring/metrics-explorer?cloudshell=false&project=$TF_VAR_ops_project_name"
Ops プロジェクトにちなんだ名前の新しいワークスペースを作成するように求められたら、[OK] を選択します。新しい UI に関するプロンプトが表示されたら、ダイアログを閉じます。
Metrics Explorer の [Find resource type and metric] の下にあるタイプ「istio
」[Server Request Count] などのオプションが表示されます。「Kubernetes コンテナ」上で実行し、指定する必要があります。これは、指標がメッシュから Stackdriver に流れていることを示しています。
(以下の行を表示するには、destination_service_name ラベルでグループ化する必要があります)。
ダッシュボードで指標を可視化する:
指標が Stackdriver APM システムに取り込まれたので、指標を可視化する方法が必要です。このセクションでは、事前構築済みのダッシュボードをインストールします。このダッシュボードには、4 つの「ゴールデン シグナル」トラフィック(1 秒あたりのリクエスト数)、レイテンシ(この場合は 99 パーセンタイルと 50 パーセンタイル)、エラー(この例では [飽和度] を除く)の指標があります。
Istio の Envoy プロキシにはいくつかの指標が備わっていますが、最初に使用するにはこれらの指標を使用することをおすすめします。(すべてのリストはこちらで確認できます)。各指標には、フィルタや集計に使用できる一連のラベル(destination_service、source_workload_namespace、response_code、istio_tcp_received_bytes_total など)があります。
- 次に、あらかじめ用意された指標ダッシュボードを追加しましょう。ここでは、Dashboard API を直接使用します。これは、通常は手作業で API 呼び出しを生成したり、自動化システムの一部であったり、ウェブ UI でダッシュボードを手動で構築したりするような処理です。これで、すぐに作業を開始できます。
sed -i 's/OPS_PROJECT/'${TF_VAR_ops_project_name}'/g' \
$WORKDIR/asm/k8s_manifests/prod/app-telemetry/services-dashboard.json
OAUTH_TOKEN=$(gcloud auth application-default print-access-token)
curl -X POST -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards \
-d @$WORKDIR/asm/k8s_manifests/prod/app-telemetry/services-dashboard.json
- 以下の出力リンクに移動して、新しく追加された「サービス ダッシュボード」を表示します。
echo "https://console.cloud.google.com/monitoring/dashboards/custom/servicesdash?cloudshell=false&project=$TF_VAR_ops_project_name"
UX を使用してその場でダッシュボードを編集することもできますが、ここでは API を使用して簡単に新しいグラフを追加します。そのためには、ダッシュボードの最新バージョンをプルダウンして編集内容を適用し、HTTP PATCH メソッドを使用して再度ダッシュボードに反映する必要があります。
- 既存のダッシュボードを取得するには、Monitoring API にクエリを実行します。先ほど追加した既存のダッシュボードを取得します。
curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards/servicesdash > /tmp/services-dashboard.json
- 新しいグラフの追加:(50 パーセンタイル レイテンシ): [API リファレンス] コードでダッシュボードに新しいグラフ ウィジェットを追加できるようになりました。この変更は、同僚がレビューしてバージョン管理にチェックインできます。50 パーセンタイル レイテンシ(中央値レイテンシ)を表示するウィジェットを追加します。
取得したダッシュボードを編集して、新しいスタンザを追加してみましょう。
NEW_CHART=${WORKDIR}/asm/k8s_manifests/prod/app-telemetry/new-chart.json
jq --argjson newChart "$(<$NEW_CHART)" '.gridLayout.widgets += [$newChart]' /tmp/services-dashboard.json > /tmp/patched-services-dashboard.json
- 既存のサービス ダッシュボードを更新します。
curl -X PATCH -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards/servicesdash \
-d @/tmp/patched-services-dashboard.json
- 次の出力リンクに移動して、更新されたダッシュボードを表示します。
echo "https://console.cloud.google.com/monitoring/dashboards/custom/servicesdash?cloudshell=false&project=$TF_VAR_ops_project_name"
- 簡単なログ分析を行う。
Istio は、メッシュ内のすべてのネットワーク トラフィックに対して一連の構造化ログを提供し、Stackdriver Logging にアップロードします。これにより、1 つの強力なツールでクラスタ間の分析を行うことができます。ログには、クラスタ、コンテナ、アプリ、connection_id などのサービスレベルのメタデータでアノテーションが付けられます。
ログエントリの例(この場合は Envoy プロキシのアクセスログ)は次のようになります(削除しています)。
*** DO NOT PASTE ***
logName: "projects/PROJECTNAME-11932-01-ops/logs/server-tcp-accesslog-stackdriver.instance.istio-system"
labels: {
connection_id: "fbb46826-96fd-476c-ac98-68a9bd6e585d-1517191"
destination_app: "redis-cart"
destination_ip: "10.16.1.7"
destination_name: "redis-cart-6448dcbdcc-cj52v"
destination_namespace: "cart"
destination_owner: "kubernetes://apis/apps/v1/namespaces/cart/deployments/redis-cart"
destination_workload: "redis-cart"
source_ip: "10.16.2.8"
total_received_bytes: "539"
total_sent_bytes: "569"
...
}
ここでログを表示します。
echo "https://console.cloud.google.com/logs/viewer?cloudshell=false&project=$TF_VAR_ops_project_name"
Istio のコントロール プレーン ログを表示するには、[Resource] >「pilot」で検索を実行します。-
ここでは、Istio コントロール プレーンが各サンプルアプリ サービスのサイドカー プロキシにプロキシ構成を push していることがわかります。「CDS」、「LDS」「RDS」異なる Envoy API を表します(詳細)。
Istio のログだけでなく、コンテナのログや、インフラストラクチャやその他の GCP サービスのログをすべて同じインターフェースで見つけることもできます。GKE のサンプルログクエリをいくつか示します。ログビューアでは、ログから指標(例: 「文字列に一致するすべてのエラーをカウント」)を作成して、ダッシュボードやアラートの一部として使用することもできます。ログを BigQuery などの他の分析ツールにストリーミングすることもできます。
「流行に敏感な人」ショップのサンプル フィルタをいくつか紹介します。
resource.type="k8s_container" labels.destination_app="productcatalogservice"
resource.type="k8s_container" resource.labels.namespace_name="cart"
- 分散トレースを確認する。
分散システムで作業しているので、デバッグには分散トレースという新しいツールが必要です。このツールを使用すると、サービスがどのように相互作用しているかに関する統計情報を発見できます(下図の外れ値で発生しているイベントの検出など)。また、未加工のサンプル トレースを調べて、実際に何が起こっているかを詳しく調査できます。
タイムライン ビューには、Hipster スタックを介して最終的にエンドユーザーに応答するために、時間の経過に伴うすべてのリクエストがレイテンシまたは最初のリクエスト間の経過時間でグラフ化されて表示されます。点が高いほど、ユーザー エクスペリエンスが遅くなります(満足度が下がります)。
点をクリックすると、そのリクエストの詳細なウォーターフォール ビューが表示されます。集計された統計情報だけでなく、特定のリクエストの生の詳細を見つける機能は、サービス間の相互作用を把握するために不可欠です。特に、サービス間のまれで悪いやり取りをハンティングする場合に重要になります。
ウォーターフォール ビューはデバッガを使用したことがある人なら誰でも知っているはずですが、ここでは、1 つのアプリケーションのさまざまなプロセスで費やされた時間ではなく、メッシュ間を移動してサービス間を別々のコンテナで実行した時間を表示しています。
ここでトレースを確認できます。
echo "https://console.cloud.google.com/traces/overview?cloudshell=false&project=$TF_VAR_ops_project_name"
ツールのスクリーンショットの例:
9. 相互 TLS 認証
目標: マイクロサービス間の安全な接続(AuthN)。
- メッシュ全体の mTLS を有効にする
- ログを調べて mTLS を確認する
コピーして貼り付ける方法のラボの説明
アプリのインストールとオブザーバビリティの設定が完了したので、次はサービス間の接続を保護し、サービスが動作していることを確認します。
たとえば、Kiali ダッシュボードを見ると、当社のサービスが MTLS を使用していない(「鍵」アイコンがない)ことが確認できます。トラフィックは流れており、システムは正常に動作しています。StackDriver Golden Metrics ダッシュボードのおかげで、全体的に問題なく機能しているという安心感を得られます。
- オペレーション クラスタの MeshPolicy を確認します。mTLS は
PERMISSIVE
で、暗号化されたトラフィックと mTLS 以外のトラフィックの両方が許可されます。
kubectl --context $OPS_GKE_1 get MeshPolicy -o json | jq '.items[].spec'
kubectl --context $OPS_GKE_2 get MeshPolicy -o json | jq '.items[].spec'
`Output (do not copy)`
{
"peers": [
{
"mtls": {
"mode": "PERMISSIVE"
}
}
]
}
Istio は、IstioControlPlane カスタム リソース(CR)を使用する Istio オペレーターを使用して、すべてのクラスタで Istio が構成されます。IstioControlPlane CR と k8s-repo を更新して、すべてのクラスタで mTLS を構成します。グローバルの設定 >mTLS >enabled: IstioControlPlane CR で true を使用すると、Istio コントロール プレーンに次の 2 つの変更が行われます。
- MeshPolicy は、すべてのクラスタで実行されているすべての Service に対して mTLS メッシュ全体で有効にするように設定されています。
- すべてのクラスタで実行されている Service 間の ISTIO_MUTUAL トラフィックを許可する DestinationRule が作成されます。
- istioControlPlane CR に kustomize パッチを適用して、mTLS クラスタ全体で有効にします。すべてのクラスタの関連するディレクトリにパッチをコピーし、kustomize パッチを追加します。
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-replicated.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-replicated.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
- k8s-repo に commit します。
cd $WORKDIR/k8s-repo
git add . && git commit -am "turn mTLS on"
git push
- Ops プロジェクトの Cloud Build のステータスを表示するには、以前に開いたタブを使用するか、次のリンクをクリックします。
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
mTLS を確認する
- オペレーション クラスタで MeshPolicy をもう一度確認します。mTLS は
PERMISSIVE
ではなくなり、mTLS トラフィックのみ許可されます。
kubectl --context $OPS_GKE_1 get MeshPolicy -o json | jq .items[].spec
kubectl --context $OPS_GKE_2 get MeshPolicy -o json | jq .items[].spec
出力(コピーしないでください):
{ "peers": [ { "mtls": {} } ] }
- Istio オペレーター コントローラによって作成された DestinationRule を記述します。
kubectl --context $OPS_GKE_1 get DestinationRule default -n istio-system -o json | jq '.spec'
kubectl --context $OPS_GKE_2 get DestinationRule default -n istio-system -o json | jq '.spec'
出力(コピーしないでください):
{ host: '*.local', trafficPolicy: { tls: { mode: ISTIO_MUTUAL } } }
HTTP から HTTPS への移行もログで確認することができます。
1 つのログエントリをクリックし、表示するフィールドの値(この場合は [http])をクリックして、UI のログでこの特定のフィールドを公開できます。[protocol:
これにより、変化をわかりやすく可視化できます。
10. カナリア デプロイ
目標: フロントエンド サービスの新しいバージョンをロールアウトする。
frontend-v2
(次の本番環境バージョン)Service を 1 つのリージョンでロールアウトDestinationRules
とVirtualServices
を使用して、トラフィックを徐々にfrontend-v2
にステアリングk8s-repo
に対する一連の commit を調べて、GitOps デプロイ パイプラインを検証する
コピーして貼り付ける方法のラボの説明
カナリア デプロイは、新しいサービスを段階的にロールアウトします。カナリア デプロイでは、新しいバージョンに送信されるトラフィック量を増やしながら、残りの割合を現在のバージョンに送信します。一般的なパターンは、トラフィック分割の各ステージでカナリア分析を実行し、「ゴールデン シグナル」を比較するというものです。ベースラインと比較します(レイテンシ、エラー率、飽和度)。これにより、サービス停止を防ぎ、新しい「v2」の安定性を確保できます。トラフィック分割のあらゆる段階で サービスを提供します
このセクションでは、Cloud Build と Istio のトラフィック ポリシーを使用して、frontend サービスの新しいバージョン用の基本的なカナリア デプロイを作成する方法を学びます。
まず、DEV1 リージョン(us-west1)でカナリア パイプラインを実行し、そのリージョン内の両方のクラスタにフロントエンド v2 をロールアウトします。次に、DEV2 リージョン(us-central)でカナリア パイプラインを実行し、そのリージョン内の両方のクラスタに v2 をデプロイします。すべてのリージョンで並行してパイプラインを実行するのではなく、リージョンに対してパイプラインを順番に実行すると、構成の誤りや v2 アプリ自体のバグによって引き起こされるグローバルな停止を回避できます。
注: どちらのリージョンでもカナリア パイプラインを手動でトリガーしますが、本番環境では自動トリガー(レジストリに push された新しい Docker イメージタグなど)を使用します。
- 残りのコマンドの実行を簡素化するために、Cloud Shell で環境変数をいくつか定義します。
CANARY_DIR="$WORKDIR/asm/k8s_manifests/prod/app-canary/"
K8S_REPO="$WORKDIR/k8s-repo"
- repo_setup.sh スクリプトを実行して、ベースライン マニフェストを k8s-repo にコピーします。
$CANARY_DIR/repo-setup.sh
次のマニフェストがコピーされます。
- frontend-v2 Deployment
- frontend-v1 パッチ(「v1」ラベルと「/version」エンドポイントを含むイメージを含める)
- respy: HTTP レスポンスの分布を出力する小さな Pod です。これを使用して、カナリア デプロイをリアルタイムで可視化できます。
- frontend Istio DestinationRule - フロントエンド Kubernetes Service を「バージョン」に基づいて 2 つのサブセット(v1 と v2)に分割デプロイラベル
- frontend Istio VirtualService - トラフィックの 100% を frontend v1 にルーティングします。これは、すべての Dev1 リージョン トラフィックの 50% を直ちにフロントエンド v2 に送信する Kubernetes Service のデフォルトのラウンドロビン動作をオーバーライドします。
- 変更を k8s_repo に commit します。
cd $K8S_REPO
git add . && git commit -am "frontend canary setup"
git push
- Ops プロジェクトの Cloud Build のステータスを表示するには、以前に開いたタブを使用するか、次のリンクをクリックします。
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
- コンソールで、OPS1 プロジェクトの Cloud Build に移動します。Cloud Build パイプラインが完了するまで待機してから、両方の DEV1 クラスタのフロントエンド Namespace で Pod を取得します。次の結果が表示されます。
watch -n 1 kubectl --context $DEV1_GKE_1 get pods -n frontend
Output (do not copy)
NAME READY STATUS RESTARTS AGE frontend-578b5c5db6-h9567 2/2 Running 0 59m frontend-v2-54b74fc75b-fbxhc 2/2 Running 0 2m26s respy-5f4664b5f6-ff22r 2/2 Running 0 2m26s
tmux を使用して、Cloud Shell ウィンドウを 2 つのペインに分割します。
- 下のペインで watch コマンドを実行して、フロントエンド サービスの HTTP レスポンス分布を確認します。
- 上部のペインでは、実際のカナリア パイプライン スクリプトが実行されます。
- コマンドを実行して Cloud Shell ウィンドウを分割し、下部のペインで watch コマンドを実行します。
RESPY_POD=$(kubectl --context $DEV1_GKE_1 get pod \
-n frontend -l app=respy -o jsonpath='{..metadata.name}')
export TMUX_SESSION=$(tmux display-message -p '#S')
tmux split-window -d -t $TMUX_SESSION:0 -p33 \
-v "export KUBECONFIG=$WORKDIR/asm/gke/kubemesh; \
kubectl --context $DEV1_GKE_1 exec -n frontend -it \
$RESPY_POD -c respy /bin/sh -- -c 'watch -n 1 ./respy \
--u http://frontend:80/version --c 10 --n 500'; sleep 2"
出力(コピーしないでください)
500 requests to http://frontend:80/version... +----------+-------------------+ | RESPONSE | % OF 500 REQUESTS | +----------+-------------------+ | v1 | 100.0% | | | | +----------+-------------------+
- Dev1 リージョンでカナリア パイプラインを実行する。VirtualService で frontend-v2 トラフィックの割合を更新するスクリプトを用意しています(重みを 20%、50%、80%、100% に更新します)。次の更新までの間、スクリプトは Cloud Build パイプラインが完了するまで待機します。Dev1 リージョンのカナリア デプロイ スクリプトを実行します。注 - このスクリプトの実行には 10 分ほどかかります。
K8S_REPO=$K8S_REPO CANARY_DIR=$CANARY_DIR \
OPS_DIR=$OPS_GKE_1_CLUSTER OPS_CONTEXT=$OPS_GKE_1 \
${CANARY_DIR}/auto-canary.sh
respy コマンドを実行している下部のウィンドウに、リアルタイムでトラフィック分割が表示されます。たとえば、20% のところでは次のようになります。
出力(コピーしないでください)
500 requests to http://frontend:80/version... +----------+-------------------+ | RESPONSE | % OF 500 REQUESTS | +----------+-------------------+ | v1 | 79.4% | | | | | v2 | 20.6% | | | | +----------+-------------------+
- frontend-v2 の Dev2 のロールアウトが完了すると、スクリプトの最後に成功メッセージが表示されます。
Output (do not copy)
✅ 100% successfully deployed 🌈 frontend-v2 Canary Complete for gke-asm-1-r1-prod
- また、Dev2 Pod からのすべてのフロントエンド トラフィックが frontend-v2 に送信されるはずです。
Output (do not copy)
500 requests to http://frontend:80/version... +----------+-------------------+ | RESPONSE | % OF 500 REQUESTS | +----------+-------------------+ | v2 | 100.0% | | | | +----------+-------------------+
- 分割ペインを閉じます。
tmux respawn-pane -t ${TMUX_SESSION}:0.1 -k 'exit'
- 生成されたリンクで、Cloud Source Repositories に移動します。
echo https://source.developers.google.com/p/$TF_VAR_ops_project_name/r/k8s-repo
トラフィックの割合ごとに個別の commit が表示され、最新の commit がリストの先頭に表示されます。
Dev2 リージョンについても同じプロセスを繰り返します。Dev2 リージョンはまだ「ロック」されたままであるアップグレードされます。これは、ベースラインの repo_setup スクリプトで VirtualService を push してすべてのトラフィックを明示的に v1 に送信するためです。このようにして、Dev1 でリージョン カナリアを実行し、新しいバージョンをグローバルにロールアウトする前に正常に実行されることを確認できました。
- コマンドを実行して Cloud Shell ウィンドウを分割し、下部のペインで watch コマンドを実行します。
RESPY_POD=$(kubectl --context $DEV2_GKE_1 get pod \
-n frontend -l app=respy -o jsonpath='{..metadata.name}')
export TMUX_SESSION=$(tmux display-message -p '#S')
tmux split-window -d -t $TMUX_SESSION:0 -p33 \
-v "export KUBECONFIG=$WORKDIR/asm/gke/kubemesh; \
kubectl --context $DEV2_GKE_1 exec -n frontend -it \
$RESPY_POD -c respy /bin/sh -- -c 'watch -n 1 ./respy \
--u http://frontend:80/version --c 10 --n 500'; sleep 2"
出力(コピーしないでください)
500 requests to http://frontend:80/version... +----------+-------------------+ | RESPONSE | % OF 500 REQUESTS | +----------+-------------------+ | v1 | 100.0% | | | | +----------+-------------------+
- Dev2 リージョンでカナリア パイプラインを実行する。VirtualService で frontend-v2 トラフィックの割合を更新するスクリプトを用意しています(重みを 20%、50%、80%、100% に更新します)。次の更新までの間、スクリプトは Cloud Build パイプラインが完了するまで待機します。Dev1 リージョンのカナリア デプロイ スクリプトを実行します。注 - このスクリプトの実行には 10 分ほどかかります。
K8S_REPO=$K8S_REPO CANARY_DIR=$CANARY_DIR \
OPS_DIR=$OPS_GKE_2_CLUSTER OPS_CONTEXT=$OPS_GKE_2 \
${CANARY_DIR}/auto-canary.sh
出力(コピーしないでください)
500 requests to http://frontend:80/version... +----------+-------------------+ | RESPONSE | % OF 500 REQUESTS | +----------+-------------------+ | v1 | 100.0% | | | | +----------+-------------------+
- Dev2 の Respy Pod から、Dev2 Pod からのトラフィックがフロントエンド v1 から v2 に段階的に移動するのを確認します。スクリプトが完了すると、次のように表示されます。
出力(コピーしないでください)
500 requests to http://frontend:80/version... +----------+-------------------+ | RESPONSE | % OF 500 REQUESTS | +----------+-------------------+ | v2 | 100.0% | | | | +----------+-------------------+
- 分割ペインを閉じます。
tmux respawn-pane -t ${TMUX_SESSION}:0.1 -k 'exit'
このセクションでは、Istio をリージョン カナリア デプロイに使用する方法を紹介しました。本番環境では、手動スクリプトではなく、Container Registry に push された新しいタグ付きイメージなどのトリガーを使用して、このカナリア スクリプトを Cloud Build パイプラインとして自動的にトリガーできます。また、各ステップの間にカナリア分析を追加して、事前に定義された安全性しきい値に照らして v2 のレイテンシとエラー率を分析し、さらにトラフィックを送信することもできます。
11. 認可ポリシー
目標: マイクロサービス(AuthZ)間に RBAC を設定する。
- マイクロサービスへのアクセスを拒否する
AuthorizationPolicy
を作成する - マイクロサービスへの特定のアクセスを許可するために
AuthorizationPolicy
を作成する
コピーして貼り付ける方法のラボの説明
1 か所で実行されるモノリシック アプリケーションとは異なり、グローバルに分散したマイクロサービス アプリは、ネットワークの境界を越えて呼び出しを行います。つまり、アプリケーションへの侵入口が増え、不正な攻撃を受ける機会も増えるということです。また、Kubernetes Pod には一時的な IP が割り当てられるため、ワークロード間のアクセスを保護するには、従来の IP ベースのファイアウォール ルールでは不十分です。マイクロサービス アーキテクチャでは、セキュリティに対する新しいアプローチが必要です。Istio は、サービス アカウントなどの Kubernetes セキュリティ構成要素に基づいて構築されており、アプリケーションに柔軟な一連のセキュリティ ポリシーが用意されています。
Istio ポリシーは認証と認可の両方をカバーします。認証は ID(このサーバーは本人のものであるか)を確認し、認証は権限を確認します(このクライアントは許可されています)。Istio 認証については、モジュール 1(MeshPolicy)の相互 TLS のセクションで説明しました。このセクションでは、Istio の認可ポリシーを使用して、アプリケーション ワークロードの 1 つである currencyservice へのアクセスを制御する方法について説明します。
まず、4 つの Dev クラスタすべてに AuthorizationPolicy をデプロイし、currencyservice へのすべてのアクセスを閉じ、フロントエンドでエラーをトリガーします。次に、フロントエンド サービスのみが currencyservice にアクセスできるようにします。
currency-deny-all.yaml
の内容を調べます。このポリシーでは、Deployment ラベルセレクタを使用して、通貨サービスへのアクセスを制限します。spec
フィールドがないことに注意してください。これは、選択したサービスへのすべてのアクセスがこのポリシーによって拒否されることを意味します。
cat $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml
出力(コピーしないでください)
apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "currency-policy" namespace: currency spec: selector: matchLabels: app: currencyservice
- 両方のリージョンの運用クラスタ用に、通貨ポリシーを k8s-repo にコピーします。
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization
kustomize edit add resource currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization
kustomize edit add resource currency-policy.yaml
- 変更を push する。
cd $WORKDIR/k8s-repo
git add . && git commit -am "AuthorizationPolicy - currency: deny all"
git push
- 以前に開いたタブで、または次のリンクをクリックして、Ops プロジェクトの Cloud Build のステータスを確認します。
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
- ビルドが正常に完了したら、ブラウザで次のリンクからヒップスターショップのフロントエンドにアクセスしてみてください。
echo "https://frontend.endpoints.$TF_VAR_ops_project_name.cloud.goog"
currencyservice から承認エラーが表示されます。
- 通貨サービスがこの AuthorizationPolicy をどのように適用しているかを調べてみましょう。ブロックされた認証呼び出しはデフォルトではログに記録されないため、まず、いずれかの通貨 Pod の Envoy プロキシでトレースレベルのログを有効にします。
CURRENCY_POD=$(kubectl --context $DEV1_GKE_2 get pod -n currency | grep currency| awk '{ print $1 }')
kubectl --context $DEV1_GKE_2 exec -it $CURRENCY_POD -n \
currency -c istio-proxy -- curl -X POST \
"http://localhost:15000/logging?level=trace"
- 通貨サービスのサイドカー プロキシから RBAC(認可)ログを取得します。「enforced denied」と表示されるはずです。currencyservice がすべての受信リクエストをブロックするように設定されていることを示すメッセージです。
kubectl --context $DEV1_GKE_2 logs -n currency $CURRENCY_POD \
-c istio-proxy | grep -m 3 rbac
出力(コピーしないでください)
[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][rbac] [external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:67] checking request: remoteAddress: 10.16.5.15:37310, localAddress: 10.16.3.8:7000, ssl: uriSanPeerCertificate: spiffe://cluster.local/ns/frontend/sa/frontend, subjectPeerCertificate: , headers: ':method', 'POST' [Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][rbac] [external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:118] enforced denied [Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][http] [external/envoy/source/common/http/conn_manager_impl.cc:1354] [C115][S17310331589050212978] Sending local reply with details rbac_access_denied
- 次に、フロントエンドに currencyservice へのアクセスを許可しますが、他のバックエンド サービスはアクセスできないようにします。
currency-allow-frontend.yaml
を開き、内容を調べます。以下のルールが追加されていることに注目してください。
cat ${WORKDIR}/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml
出力(コピーしないでください)
rules: - from: - source: principals: ["cluster.local/ns/frontend/sa/frontend"]
ここでは、通貨サービスにアクセスするために特定の source.principal(クライアント)を許可リストに登録しています。この source.principal は、Kubernetes サービス アカウントによって定義されます。この場合、許可リストに登録するサービス アカウントは、フロントエンド Namespace のフロントエンド サービス アカウントです。
注: Istio AuthorizationPolicy で Kubernetes サービス アカウントを使用する場合は、モジュール 1 で行ったように、まずクラスタ全体の相互 TLS を有効にする必要があります。これは、サービス アカウントの認証情報がリクエストに確実にマウントされるようにするためです。
- 更新した通貨に関するポリシーをコピーします
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
- 変更を push する。
cd $WORKDIR/k8s-repo
git add . && git commit -am "AuthorizationPolicy - currency: allow frontend"
git push
- Ops プロジェクトの Cloud Build のステータスを表示するには、以前に開いたタブを使用するか、次のリンクをクリックします。
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
- ビルドが正常に完了したら、Hipstershop フロントエンドを再度開きます。今回は、ホームページにエラーは表示されません。これは、フロントエンドが現在のサービスへのアクセスを明示的に許可されているためです。
- 次に、カートに商品を追加して [注文する] をクリックして、購入手続きを実行してみましょう。今回は、通貨サービスからの価格換算エラーが表示されます。これは、フロントエンドのみが許可リストに登録されているため、購入手続きサービスが通貨サービスにアクセスできないためです。
- 最後に、currencyservice AuthorizationPolicy に別のルールを追加して、購入手続きサービスに通貨へのアクセスを許可します。なお、通貨へのアクセスは、フロントエンドと購入手続きのアクセスが必要な 2 つのサービスにのみ公開されています。他のバックエンドは引き続きブロックされます。
currency-allow-frontend-checkout.yaml
を開き、内容を調べます。ルールのリストは論理 OR として機能し、通貨はこれら 2 つのサービス アカウントのいずれかを持つワークロードからのリクエストのみを受け入れます。
cat ${WORKDIR}/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml
出力(コピーしないでください)
apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "currency-policy" namespace: currency spec: selector: matchLabels: app: currencyservice rules: - from: - source: principals: ["cluster.local/ns/frontend/sa/frontend"] - from: - source: principals: ["cluster.local/ns/checkout/sa/checkout"]
- 最終的な認可ポリシーを k8s-repo にコピーします。
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
- 変更を push
cd $WORKDIR/k8s-repo
git add . && git commit -am "AuthorizationPolicy - currency: allow frontend and checkout"
git push
- Ops プロジェクトの Cloud Build のステータスを表示するには、以前に開いたタブを使用するか、次のリンクをクリックします。
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
- ビルドが正常に終了したら、チェックアウトの実行を試します。正常に機能するはずです。
このセクションでは、Istio 認可ポリシーを使用して、サービスレベルできめ細かいアクセス制御を適用する方法を説明しました。本番環境では、サービスごとに 1 つの AuthorizationPolicy を作成し、たとえば、allow-all ポリシーを使用して、同じ Namespace 内のすべてのワークロードが相互にアクセスできるようにします。
12. インフラストラクチャのスケーリング
目標: 新しいリージョン、プロジェクト、クラスタを追加してインフラストラクチャをスケールする。
infrastructure
リポジトリのクローンを作成する- Terraform ファイルを更新して新しいリソースを作成する
- 新しいリージョンに 2 つのサブネット(運用プロジェクト用と新しいプロジェクト用)
- 新しいリージョン(新しいサブネット内)の新しい運用クラスタ
- 新しいリージョン用の新しい Istio コントロール プレーン
- 新しいリージョンの新しいプロジェクトに 2 つのアプリクラスタがある
infrastructure
リポジトリに commit- インストールを確認する
コピーして貼り付ける方法のラボの説明
プラットフォームをスケーリングする方法はいくつかあります。既存のクラスタにノードを追加することで、コンピューティングをさらに追加できます。リージョン内にクラスタを追加できます。プラットフォームにリージョンを追加することもできます。プラットフォームのどの部分をスケールするかは、要件によって決まります。たとえば、リージョン内の 3 つのゾーンすべてにクラスタがある場合は、既存のクラスタにノード(またはノードプール)を追加するだけで十分な場合があります。ただし、1 つのリージョン内の 3 つのゾーンのうち 2 つにクラスタがある場合、3 つ目のゾーンに新しいクラスタを追加すると、スケーリングと追加の障害ドメイン(新しいゾーン)ができてしまいます。リージョンに新しいクラスタを作成するもう 1 つの理由は、規制やコンプライアンス上の理由から、単一のテナント クラスタを作成する必要がある場合です(PCI、PII 情報を格納するデータベース クラスタなど)。ビジネスやサービスが拡大するにつれ、サービスを顧客により近い場所で提供するためには、新しいリージョンを追加することが必須となります。
現在のプラットフォームは 2 つのリージョンと、リージョンごとに 2 つのゾーンのクラスタで構成されています。プラットフォームは、次の 2 つの方法でスケーリングできます。
- 垂直方向 - コンピューティングを追加して各リージョン内。これを行うには、既存のクラスタにノード(またはノードプール)を追加するか、リージョン内に新しいクラスタを追加します。これは、
infrastructure
リポジトリを介して行います。最も簡単な方法は、既存のクラスタにノードを追加する方法です。追加の構成は必要ありません。新しいクラスタを追加するには、サブネット(およびセカンダリ範囲)の追加、適切なファイアウォール ルールの追加、リージョン ASM/Istio サービス メッシュ コントロール プレーンへの新しいクラスタの追加、新しいクラスタへのアプリケーション リソースのデプロイが必要になる場合があります。 - 水平方向 - 地域を追加します。現在のプラットフォームでは、リージョン用のテンプレートが用意されています。ASM/Istio コントロールが存在するリージョンの運用クラスタと、アプリケーション リソースがデプロイされている 2 つ(またはそれ以上)のゾーン アプリケーション クラスタで構成されています。
このワークショップでは、プラットフォームを「水平方向に」スケーリングします。業種別ユースケースのステップも含まれていますプラットフォームに新しいリージョン(r3)を追加して水平方向にスケーリングするには、次のリソースを追加する必要があります。
- 新しい運用クラスタとアプリケーション クラスタ用のリージョン r3 にあるホスト プロジェクトの共有 VPC のサブネット。
- ASM/Istio コントロール プレーンが存在するリージョン r3 のリージョン Ops クラスタ。
- リージョン r3 の 2 つのゾーンにある 2 つのゾーン アプリケーション クラスタ。
- k8s-repo を更新します。
- ASM/Istio コントロール プレーン リソースをリージョン r3 の運用クラスタにデプロイする。
- ASM/Istio 共有コントロール プレーン リソースをリージョン r3 のアプリ クラスタにデプロイします。
- 新しいプロジェクトを作成する必要はありませんが、ワークショップの手順では、プラットフォームに新しいチームを追加するユースケースに対応するため、新しいプロジェクト dev3 の追加を実演しています。
インフラストラクチャ リポジトリは、前述の新しいリソースを追加するために使用されます。
- Cloud Shell で WORKDIR に移動し、
infrastructure
リポジトリのクローンを作成します。
mkdir -p $WORKDIR/infra-repo
cd $WORKDIR/infra-repo
git init && git remote add origin https://source.developers.google.com/p/${TF_ADMIN}/r/infrastructure
git config --local user.email ${MY_USER}
git config --local user.name "infra repo user"
git config --local credential.'https://source.developers.google.com'.helper gcloud.sh
git pull origin master
- ワークショップのソース リポジトリ
add-proj
ブランチのクローンをadd-proj-repo
ディレクトリに作成します。
cd $WORKDIR
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git add-proj-repo -b add-proj
- ソース ワークショップ リポジトリの
add-proj
ブランチからファイルをコピーします。add-proj
ブランチには、このセクションの変更が含まれています。
cp -r $WORKDIR/add-proj-repo/infrastructure/* $WORKDIR/infra-repo/
- add-proj リポジトリ ディレクトリの
infrastructure
ディレクトリをinfra-repo
ディレクトリへのシンボリック リンクに置き換えて、ブランチ上のスクリプトを実行できるようにします。
rm -rf $WORKDIR/add-proj-repo/infrastructure
ln -s $WORKDIR/infra-repo $WORKDIR/add-proj-repo/infrastructure
add-project.sh
スクリプトを実行して、共有された状態と変数を新しいプロジェクト ディレクトリ構造にコピーします。
$WORKDIR/add-proj-repo/scripts/add-project.sh app3 $WORKDIR/asm $WORKDIR/infra-repo
- 変更を commit して push し、新しいプロジェクトを作成する
cd $WORKDIR/infra-repo
git add .
git status
git commit -m "add new project" && git push origin master
- commit により
infrastructure
リポジトリがトリガーされ、新しいリソースを含むインフラストラクチャがデプロイされます。次のリンクの出力をクリックして、最新のビルドに移動すると、Cloud Build の進行状況を確認できます。
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_ADMIN}"
infrastructure
Cloud Build の最後のステップでは、新しい Kubernetes リソースが k8s-repo
に作成されます。これにより、(ops プロジェクトの)k8s-repo
で Cloud Build がトリガーされます。新しい Kubernetes リソースは、前の手順で追加した 3 つの新しいクラスタ用です。ASM/Istio コントロール プレーンと共有コントロール プレーン リソースは、k8s-repo
Cloud Build で新しいクラスタに追加されます。
- インフラストラクチャの Cloud Build が正常に終了したら、次の出力リンクをクリックして、
k8s-repo
の最新の Cloud Build 実行に移動します。
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
- 次のスクリプトを実行して、新しいクラスタを vars ファイルと kubeconfig ファイルに追加します。
$WORKDIR/add-proj-repo/scripts/setup-gke-vars-kubeconfig-add-proj.sh $WORKDIR/asm
- 新しい kubeconfig ファイルを指すように
KUBECONFIG
変数を変更します。
source $WORKDIR/asm/vars/vars.sh
export KUBECONFIG=$WORKDIR/asm/gke/kubemesh
- クラスタ コンテキストを一覧表示します。8 つのクラスタが表示されます。
kubectl config view -ojson | jq -r '.clusters[].name'
`Output (do not copy)`
gke_user001-200204-05-dev1-49tqc4_us-west1-a_gke-1-apps-r1a-prod gke_user001-200204-05-dev1-49tqc4_us-west1-b_gke-2-apps-r1b-prod gke_user001-200204-05-dev2-49tqc4_us-central1-a_gke-3-apps-r2a-prod gke_user001-200204-05-dev2-49tqc4_us-central1-b_gke-4-apps-r2b-prod gke_user001-200204-05-dev3-49tqc4_us-east1-b_gke-5-apps-r3b-prod gke_user001-200204-05-dev3-49tqc4_us-east1-c_gke-6-apps-r3c-prod gke_user001-200204-05-ops-49tqc4_us-central1_gke-asm-2-r2-prod gke_user001-200204-05-ops-49tqc4_us-east1_gke-asm-3-r3-prod gke_user001-200204-05-ops-49tqc4_us-west1_gke-asm-1-r1-prod
Istio のインストールを確認する
- すべての Pod が実行されており、ジョブが完了したことを確認して、Istio が新しい運用クラスタにインストールされていることを確認します。
kubectl --context $OPS_GKE_3 get pods -n istio-system
`Output (do not copy)`
NAME READY STATUS RESTARTS AGE grafana-5f798469fd-72g6w 1/1 Running 0 5h12m istio-citadel-7d8595845-hmmvj 1/1 Running 0 5h12m istio-egressgateway-779b87c464-rw8bg 1/1 Running 0 5h12m istio-galley-844ddfc788-zzpkl 2/2 Running 0 5h12m istio-ingressgateway-59ccd6574b-xfj98 1/1 Running 0 5h12m istio-pilot-7c8989f5cf-5plsg 2/2 Running 0 5h12m istio-policy-6674bc7678-2shrk 2/2 Running 3 5h12m istio-sidecar-injector-7795bb5888-kbl5p 1/1 Running 0 5h12m istio-telemetry-5fd7cbbb47-c4q7b 2/2 Running 2 5h12m istio-tracing-cd67ddf8-2qwkd 1/1 Running 0 5h12m istiocoredns-5f7546c6f4-qhj9k 2/2 Running 0 5h12m kiali-7964898d8c-l74ww 1/1 Running 0 5h12m prometheus-586d4445c7-x9ln6 1/1 Running 0 5h12m
- 両方の
dev3
クラスタに Istio がインストールされていることを確認します。dev3
クラスタでは、Citadel、サイドカー インジェクタ、coredns のみが実行されます。これらは、ops-3
クラスタで実行されている Istio コントロール プレーンを共有します。
kubectl --context $DEV3_GKE_1 get pods -n istio-system
kubectl --context $DEV3_GKE_2 get pods -n istio-system
`Output (do not copy)`
NAME READY STATUS RESTARTS AGE istio-citadel-568747d88-4lj9b 1/1 Running 0 66s istio-sidecar-injector-759bf6b4bc-ks5br 1/1 Running 0 66s istiocoredns-5f7546c6f4-qbsqm 2/2 Running 0 78s
共有コントロール プレーンのサービス ディスカバリを確認する
- 6 つのアプリケーション クラスタのすべてのオペレーション クラスタに Secret がデプロイされていることを確認します。
kubectl --context $OPS_GKE_1 get secrets -l istio/multiCluster=true -n istio-system
kubectl --context $OPS_GKE_2 get secrets -l istio/multiCluster=true -n istio-system
kubectl --context $OPS_GKE_3 get secrets -l istio/multiCluster=true -n istio-system
`Output (do not copy)`
NAME TYPE DATA AGE gke-1-apps-r1a-prod Opaque 1 14h gke-2-apps-r1b-prod Opaque 1 14h gke-3-apps-r2a-prod Opaque 1 14h gke-4-apps-r2b-prod Opaque 1 14h gke-5-apps-r3b-prod Opaque 1 5h12m gke-6-apps-r3c-prod Opaque 1 5h12m
13. 回路遮断
目標: 配送サービス用の回路ブレーカーを実装する。
shipping
Service のDestinationRule
を作成して回路ブレーカーを実装するfortio
(負荷生成ユーティリティ)を使用して、回路を強制的に「トリミング」してshipping
Service の回路ブレーカーを検証します。
ファスト トラック スクリプト ラボの手順
Fast Track スクリプトのラボは近日提供予定です。
コピーして貼り付ける方法のラボの説明
ここまで、Istio 対応サービスの基本的なモニタリングとトラブルシューティングの戦略について学習しました。次は、Istio を使用してサービスの復元力を改善し、そもそも必要なトラブルシューティングの量を削減する方法を見ていきましょう。
マイクロサービス アーキテクチャでは、カスケード障害のリスクが生じます。カスケード障害では、あるサービスの障害がその依存関係や依存関係に伝播し、「波及効果」を引き起こします。エンドユーザーに影響する可能性がある サービスの停止を防ぐことができますIstio が提供するサーキット ブレーカー トラフィック ポリシーを使用すると、サービスを分離して、ダウンストリーム(クライアントサイド)のサービスを障害が発生したサービスを待機しないように保護したり、アップストリーム(サーバーサイド)のサービスをオンラインに戻ったときに急激なダウンストリーム トラフィックの急増から保護したりできます。概して、サーキット ブレーカーを使用すると、1 つのバックエンド サービスがハングアップしたことですべてのサービスが SLO を満たさずに済みます。
回路ブレーカーのパターンは、「トリップ」できる電気スイッチにちなんで名付けられました。過剰な電力が流れたときに、デバイスを過負荷から保護します。これは、Istio の設定では、Envoy が回路ブレーカーで、サービスの保留中のリクエスト数を追跡していることを意味します。このデフォルトのクローズ状態では、リクエストは Envoy を通じて中断なく流れます。
ただし、保留中のリクエストの数が定義されたしきい値を超えると、回路ブレーカーがトリップ(オープン)され、Envoy はすぐにエラーを返します。これにより、クライアントに代わってサーバーがフェイル ファストすることが可能になり、過負荷状態のときにサーバー アプリケーションのコードがクライアントのリクエストを受け取れなくなります。
その後、定義したタイムアウトの後、Envoy はハーフオープン状態に移行します。この状態では、サーバーは試験的な方法でリクエストの受信を再開できます。リクエストに正常に応答できると、回路ブレーカーが再び閉じて、サーバーへのリクエストが再び流れ始めます。
この図は、Istio 回路ブレーカー パターンをまとめたものです。青い四角は Envoy、青で塗りつぶされた円はクライアント、白で塗りつぶされた円はサーバー コンテナを表しています。
Istio DestinationRules を使用してサーキット ブレーカー ポリシーを定義できます。このセクションでは、次のポリシーを適用して配送サービスに回路ブレーカーを適用します。
Output (do not copy) apiVersion: "networking.istio.io/v1alpha3" kind: "DestinationRule" metadata: name: "shippingservice-shipping-destrule" namespace: "shipping" spec: host: "shippingservice.shipping.svc.cluster.local" trafficPolicy: tls: mode: ISTIO_MUTUAL connectionPool: tcp: maxConnections: 1 http: http1MaxPendingRequests: 1 maxRequestsPerConnection: 1 outlierDetection: consecutiveErrors: 1 interval: 1s baseEjectionTime: 10s maxEjectionPercent: 100
ここで注目すべき DestinationRule フィールドが 2 つあります。connectionPool
は、このサービスで許可される接続の数を定義します。outlierDetection フィールドは、Envoy が回路ブレーカーを開くしきい値を決定する方法を構成する場所です。ここでは 1 秒ごと(間隔)に、Envoy がサーバー コンテナから受信したエラーの数をカウントします。この値が consecutiveErrors
のしきい値を超えると、Envoy 回路ブレーカーが開き、10 秒間、productcatalog Pod の 100% が新しいクライアント リクエストからシールドされます。Envoy サーキット ブレーカーがオープン(つまりアクティブ)になると、クライアントは 503(サービス利用不可)エラーを受け取ります。実際に見てみましょう。
- コマンドを簡素化するために、k8s-repo と asm dir の環境変数を設定します。
export K8S_REPO="${WORKDIR}/k8s-repo"
export ASM="${WORKDIR}/asm"
- k8s-repo を更新する
cd $WORKDIR/k8s-repo
git pull
cd $WORKDIR
- 両方の Ops クラスタで配送サービスの DestinationRule を更新します。
cp $ASM/k8s_manifests/prod/istio-networking/app-shipping-circuit-breaker.yaml ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cp $ASM/k8s_manifests/prod/istio-networking/app-shipping-circuit-breaker.yaml ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit add resource app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit add resource app-shipping-circuit-breaker.yaml
- Fortio 負荷生成ツールの Pod を Dev1 リージョンの GKE_1 クラスタにコピーします。これは「trip」に使用するクライアント Pod です。配送サービス用の回路ブレーカー
cp $ASM/k8s_manifests/prod/app/deployments/app-fortio.yaml ${K8S_REPO}/${DEV1_GKE_1_CLUSTER}/app/deployments/
cd ${K8S_REPO}/${DEV1_GKE_1_CLUSTER}/app/deployments; kustomize edit add resource app-fortio.yaml
- 変更を commit します。
cd $K8S_REPO
git add . && git commit -am "Circuit Breaker: shippingservice"
git push
cd $ASM
- Cloud Build が完了するまで待ちます。
- Cloud Shell に戻り、fortio Pod を使用して、同時接続 1 つ、合計 1,000 件のリクエストを使用して、shippingservice に gRPC トラフィックを送信します。まだ
connectionPool
設定を超えていないため、回路ブレーカーはトリップしません。
FORTIO_POD=$(kubectl --context ${DEV1_GKE_1} get pod -n shipping | grep fortio | awk '{ print $1 }')
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 1 -n 1000 -qps 0 shippingservice.shipping.svc.cluster.local:50051
出力(コピーしないでください)
Health SERVING : 1000 All done 1000 calls (plus 0 warmup) 4.968 ms avg, 201.2 qps
- 今度は、同時接続数を 2 に増やして、リクエストの合計数を一定に保ちながら、fortio を再度実行します。リクエストの最大 3 分の 2 で「オーバーフロー」が返されます。回路ブレーカーが作動したためです。定義したポリシーでは、1 秒間に 1 つの同時接続しか許可されません。
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 2 -n 1000 -qps 0 shippingservice.shipping.svc.cluster.local:50051
出力(コピーしないでください)
18:46:16 W grpcrunner.go:107> Error making grpc call: rpc error: code = Unavailable desc = upstream connect error or disconnect/reset before headers. reset reason: overflow ... Health ERROR : 625 Health SERVING : 375 All done 1000 calls (plus 0 warmup) 12.118 ms avg, 96.1 qps
- Envoy は、回路ブレーカーがアクティブになったときに切断された接続数を upstream_rq_pending_overflow 指標を使用して追跡します。これを fortio Pod で見つけましょう。
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c istio-proxy -- sh -c 'curl localhost:15000/stats' | grep shipping | grep pending
出力(コピーしないでください)
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0 cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0 cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_active: 0 cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_failure_eject: 9 cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_overflow: 565 cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_total: 1433
- 両方のリージョンから回路ブレーカー ポリシーを削除してクリーンアップします。
kubectl --context ${OPS_GKE_1} delete destinationrule shippingservice-circuit-breaker -n shipping
rm ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit remove resource app-shipping-circuit-breaker.yaml
kubectl --context ${OPS_GKE_2} delete destinationrule shippingservice-circuit-breaker -n shipping
rm ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit remove resource app-shipping-circuit-breaker.yaml
cd $K8S_REPO; git add .; git commit -m "Circuit Breaker: cleanup"; git push origin master
このセクションでは、サービスに 1 つの回路ブレーカー ポリシーを設定する方法を説明しました。ハングする可能性のあるアップストリーム(バックエンド)サービスには、回路ブレーカーをセットアップすることをおすすめします。Istio 回路ブレーカー ポリシーを適用することで、マイクロサービスを分離し、アーキテクチャにフォールト トレラントを組み込み、高負荷でのカスケード障害のリスクを軽減できます。
14. フォールト インジェクション
目標: 遅延を発生させて(本番環境に push する前に)レコメンデーション Service の復元力をテストします。
recommendation
Service のVirtualService
を作成して 5 秒の遅延を発生させるfortio
負荷生成ツールを使用して遅延をテストするVirtualService
の遅延を削除し、検証する
ファスト トラック スクリプト ラボの手順
Fast Track スクリプトのラボは近日提供予定です。
コピーして貼り付ける方法のラボの説明
サービスに回路ブレーカー ポリシーを追加することは、本番環境のサービスに対する復元力を構築する方法の一つです。しかし、回路遮断を行うと障害が発生し、ユーザー側でエラーが発生する可能性があります。これは理想的ではありません。このようなエラーケースに先手を打ち、バックエンドがエラーを返したときにダウンストリーム サービスがどのように反応するかをより正確に予測するために、ステージング環境でカオステストを導入できます。カオステストとは、システム内の弱点を分析してフォールト トレランスを高めるために、サービスを意図的に中断する手法です。また、カオステストを使用して、バックエンドで障害が発生したときにユーザーに表示されるエラーを軽減する方法を特定することもできます。たとえば、キャッシュされた結果をフロントエンドに表示するなどです。
フォールト インジェクションに Istio を使用すると、ソースコードを変更する代わりに、本番環境リリース イメージを使用してネットワーク レイヤでフォールトを追加できるため、便利です。本番環境では、本格的なカオス テストツールを使用して、ネットワーク レイヤだけでなく Kubernetes やコンピューティング レイヤでも復元力をテストできます。
「fault」を含む VirtualService を適用することで、Istio をカオステストに使用できます。表示されます。Istio では、遅延障害(タイムアウトの挿入)と 中止障害(HTTP エラーの挿入)の 2 種類の障害がサポートされています。この例では、5 秒の遅延のフォールトを recommendations サービスに挿入します。しかし 今回は、回路ブレーカーを使用して「早期にフェイル」する代わりに下流のサービスに対して完全なタイムアウトが耐えられるようになります。
- フォールト インジェクション ディレクトリに移動します。
export K8S_REPO="${WORKDIR}/k8s-repo"
export ASM="${WORKDIR}/asm/"
cd $ASM
k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml
を開いて内容を調べます。Istio には、リクエストの一部に障害を挿入するオプションがあることに注意してください。ここでは、すべての recommendationservice リクエストにタイムアウトを導入します。
出力(コピーしないでください)
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: recommendation-delay-fault spec: hosts: - recommendationservice.recommendation.svc.cluster.local http: - route: - destination: host: recommendationservice.recommendation.svc.cluster.local fault: delay: percentage: value: 100 fixedDelay: 5s
- VirtualService を k8s_repo にコピーします。このフォールトは、両方のリージョンでグローバルにインジェクションされます。
cp $ASM/k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit add resource app-recommendation-vs-fault.yaml
cp $ASM/k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit add resource app-recommendation-vs-fault.yaml
- 変更を push
cd $K8S_REPO
git add . && git commit -am "Fault Injection: recommendationservice"
git push
cd $ASM
- Cloud Build が完了するまで待ちます。
- 回路ブレーカー セクションにデプロイされた fortio Pod を実行し、一部のトラフィックを recommendationservice に送信します。
FORTIO_POD=$(kubectl --context ${DEV1_GKE_1} get pod -n shipping | grep fortio | awk '{ print $1 }')
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 100 -n 100 -qps 0 recommendationservice.recommendation.svc.cluster.local:8080
Once the fortio command is complete, you should see responses averaging 5s:
出力(コピーしないでください)
Ended after 5.181367359s : 100 calls. qps=19.3 Aggregated Function Time : count 100 avg 5.0996506 +/- 0.03831 min 5.040237641 max 5.177559818 sum 509.965055
- 挿入した障害の動作を確認するには、ウェブブラウザでフロントエンドを開いて、いずれかのプロダクトをクリックします。商品ページは、ページの下部に表示されるおすすめ商品を取得するため、読み込みにさらに 5 秒かかります。
- 両方の Ops クラスタからフォールト インジェクション サービスを削除してクリーンアップします。
kubectl --context ${OPS_GKE_1} delete virtualservice recommendation-delay-fault -n recommendation
rm ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit remove resource app-recommendation-vs-fault.yaml
kubectl --context ${OPS_GKE_2} delete virtualservice recommendation-delay-fault -n recommendation
rm ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit remove resource app-recommendation-vs-fault.yaml
- 変更を push する:
cd $K8S_REPO
git add . && git commit -am "Fault Injection cleanup / restore"
git push
cd $ASM
15. Istio コントロール プレーンのモニタリング
ASM によって、Pilot、Mixer、Galley、Citadel という 4 つの重要なコントロール・プレーン・コンポーネントがインストールされます。それぞれが関連するモニタリング指標を Prometheus に送信します。ASM には Grafana ダッシュボードが付属しています。このダッシュボードを使用すると、オペレーターはこのモニタリング データを可視化し、コントロール プレーンの健全性とパフォーマンスを評価できます。
ダッシュボードの表示
- Istio とともにインストールした Grafana サービスをポート転送する
kubectl --context ${OPS_GKE_1} -n istio-system port-forward svc/grafana 3000:3000 >> /dev/null
- ブラウザで Grafana を開きます
- [ウェブでプレビュー] をクリックアイコンをクリックします。
- ポート 3000 で [プレビュー] をクリックします(注: ポートが 3000 でない場合は、[ポートを変更] をクリックしてポート 3000 を選択します)。
- これにより、ブラウザに「BASE_URL/?orgId=1&authuser=0&environment_id=default」
- 利用可能なダッシュボードを表示する
- URL を「BASE_URL/dashboard"
- [istio] をクリックします。利用可能なダッシュボードを表示するフォルダ
- いずれかのダッシュボードをクリックすると、そのコンポーネントのパフォーマンスが表示されます。以降のセクションでは、各コンポーネントの重要な指標について説明します。
モニタリング パイロット
Pilot は、ネットワーキングとポリシー構成をデータプレーン(Envoy プロキシ)に分散するコントロール プレーン コンポーネントです。パイロットはワークロードとデプロイの数に応じてスケールする傾向があるが、ワークロードへのトラフィック量に必ずしも比例しない。パイロットが異常である場合:
- 必要以上のリソース(CPU や RAM)を消費している
- 更新された構成情報の Envoy への push に遅延が生じる
注: パイロットが停止している場合や遅延が発生しても、ワークロードは引き続きトラフィックを処理します。
- [BASE_URL/dashboard/db/istio-pilot-dashboard"パイロット指標を表示してください。
重要なモニタリング指標
リソース使用量
許容可能な使用量の数値については、Istio のパフォーマンスとスケーラビリティのページをガイドとして使用してください。これよりも著しく持続的なリソース使用量が見られる場合は、GCP サポートにお問い合わせください。
パイロットへのプッシュに関する情報
このセクションでは、Envoy プロキシへの構成の Pilot による push をモニタリングします。
- [Pilot Pushes] には任意の時点でプッシュされた設定のタイプが表示されます。
- ADS Monitoring には、システム内の仮想サービス、サービス、接続エンドポイントの数が表示されます。
- [既知のエンドポイントがないクラスタ] には、構成されているものの、インスタンスが実行されていないエンドポイントが表示されます(*.googleapis.com などの外部サービスを示している可能性があります)。
- [パイロット エラー] には、時間の経過とともに発生したエラーの数が表示されます。
- 競合は、リスナーに関するあいまいな構成である競合の数を示します。
エラーまたは競合が発生している場合は、1 つ以上のサービスで不適切な構成か、構成に一貫性のない構成があります。詳細については、データプレーンのトラブルシューティングをご覧ください。
Envoy の情報
このセクションでは、コントロール プレーンに接続する Envoy プロキシについて説明します。XDS 接続の失敗が繰り返し表示される場合は、GCP サポートにお問い合わせください。
モニタリング ミキサー
Mixer は、Envoy プロキシからテレメトリー バックエンド(通常は Prometheus、Stackdriver など)にテレメトリーを集約するコンポーネントです。この容量では、データプレーンには存在しません。これは、2 つの異なるサービス名(istio-telemetry と istio-policy)でデプロイされた 2 つの Kubernetes Job(Mixer)としてデプロイされます。
Mixer は、ポリシー システムとの統合にも使用できます。この点では、Mixer はデータプレーンに影響を及ぼします。これは、Mixer に対するポリシーがチェックに失敗するとサービスへのアクセスをブロックしてしまうためです。
Mixer は、トラフィック量に応じてスケールする傾向があります。
- [BASE_URL/dashboard/db/istio-mixer-dashboard"Mixer の指標を表示します。
重要なモニタリング対象指標
リソース使用量
許容可能な使用量の数値については、Istio のパフォーマンスとスケーラビリティのページをガイドとして使用してください。これよりも著しく持続的なリソース使用量が見られる場合は、GCP サポートにお問い合わせください。
Mixer の概要
- [Response Duration] は重要な指標です。Mixer テレメトリーへのレポートはデータパスに含まれていませんが、これらのレイテンシが高いと、確実にサイドカー プロキシのパフォーマンスが低下します。90 パーセンタイルは 1 桁ミリ秒単位、99 パーセンタイルは 100 ミリ秒未満であることが予想されます。
- [Adapter Dispatch Duration] は、Mixer が(それを介してテレメトリーとロギング システムに情報を送信する)呼び出し元のレイテンシを示します。レイテンシが高いと、必ずメッシュのパフォーマンスに影響します。繰り返しになりますが、p90 レイテンシは 10 ミリ秒未満にする必要があります。
モニタリング ギャリー
Galley は、Istio の構成検証、取り込み、処理、配布用のコンポーネントです。Kubernetes API サーバーから Pilot に構成が伝達されます。Pilot の場合と同様、システム内のサービスやエンドポイントの数に応じて拡張する傾向があります。
- [BASE_URL/dashboard/db/istio-galley-dashboard"Galley の指標を表示します。
重要なモニタリング対象指標
リソースの検証
最も重要な指標は、宛先ルール、ゲートウェイ、サービス エントリなど、検証に合格した、または不合格になったリソースの数を示すものです。
接続されたクライアント
Galley に接続されているクライアントの数を示します。通常は 3 個(pilot、istio-telemetry、istio-policy)になり、これらのコンポーネントのスケーリングに合わせてスケーリングされます。
16. Istio のトラブルシューティング
データプレーンのトラブルシューティング
構成に問題があることが Pilot ダッシュボードに示された場合は、PIlot ログを調べるか、istioctl を使用して構成の問題を見つける必要があります。
Pilot のログを調べるには、kubectl -n istio-system logs istio-pilot-69db46c598-45m44 Discovery を実行します。istio-pilot-... は、トラブルシューティングする Pilot インスタンスの Pod 識別子に置き換えます。
結果のログで、Push Status メッセージを検索します。例:
2019-11-07T01:16:20.451967Z info ads Push Status: {
"ProxyStatus": {
"pilot_conflict_outbound_listener_tcp_over_current_tcp": {
"0.0.0.0:443": {
"proxy": "cartservice-7555f749f-k44dg.hipster",
"message": "Listener=0.0.0.0:443 AcceptedTCP=accounts.google.com,*.googleapis.com RejectedTCP=edition.cnn.com TCPServices=2"
}
},
"pilot_duplicate_envoy_clusters": {
"outbound|15443|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
"proxy": "sleep-6c66c7765d-9r85f.default",
"message": "Duplicate cluster outbound|15443|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
},
"outbound|443|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
"proxy": "sleep-6c66c7765d-9r85f.default",
"message": "Duplicate cluster outbound|443|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
},
"outbound|80|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
"proxy": "sleep-6c66c7765d-9r85f.default",
"message": "Duplicate cluster outbound|80|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
}
},
"pilot_eds_no_instances": {
"outbound_.80_._.frontend-external.hipster.svc.cluster.local": {},
"outbound|443||*.googleapis.com": {},
"outbound|443||accounts.google.com": {},
"outbound|443||metadata.google.internal": {},
"outbound|80||*.googleapis.com": {},
"outbound|80||accounts.google.com": {},
"outbound|80||frontend-external.hipster.svc.cluster.local": {},
"outbound|80||metadata.google.internal": {}
},
"pilot_no_ip": {
"loadgenerator-778c8489d6-bc65d.hipster": {
"proxy": "loadgenerator-778c8489d6-bc65d.hipster"
}
}
},
"Version": "o1HFhx32U4s="
}
push ステータスには、Envoy プロキシに構成を push しようとしたときに発生した問題が表示されます。この場合は、「Duplicate cluster」が複数表示されます。これは、アップストリームの宛先が重複していることを示します。
問題の診断でサポートが必要な場合は、Google Cloud サポートにお問い合わせください。
構成エラーの検出結果
istioctl を使用して構成を分析するには、istioctl experimental analyze -k --context $OPS_GKE_1
を実行します。これにより、システムの構成が分析され、問題があれば、推奨される変更が示されます。このコマンドで検出できる構成エラーの一覧については、ドキュメントをご覧ください。
17. クリーンアップ
管理者が cleanup_workshop.sh スクリプトを実行して、bootstrap_workshop.sh スクリプトによって作成されたリソースを削除します。クリーンアップ スクリプトを実行するには、次の情報が必要です。
- 組織名 -
yourcompany.com
など - ワークショップ ID -
YYMMDD-NN
の形式(例:200131-01
) - 管理 GCS バケット - ブートストラップ スクリプトで定義
- Cloud Shell を開き、以下のすべての操作を Cloud Shell で実行します。以下のリンクをクリックしてください。
- 目的の管理者ユーザーで gcloud にログインしていることを確認します。
gcloud config list
- asm フォルダに移動します。
cd ${WORKDIR}/asm
- 削除する組織名とワークショップ ID を定義します。
export ORGANIZATION_NAME=<ORGANIZATION NAME>
export ASM_WORKSHOP_ID=<WORKSHOP ID>
export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
- 次のようにクリーンアップ スクリプトを実行します。
./scripts/cleanup_workshop.sh --workshop-id ${ASM_WORKSHOP_ID} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET} --org-name ${ORGANIZATION_NAME}