1. ようこそ
Google の Istio Multi Cloud Burst Codelab にご参加いただきありがとうございます。この Codelab では、Kubernetes、Node、Go の初級レベルの実践経験が必要です。 必要なもの
|
|
学習内容
- GKE で Kubernetes クラスタを作成する方法
- Helm を使用して Kubernetes クラスタに Istio をインストールする方法
- Helm を使用して Istio Multicluster をインストールする方法
- ソースから Kubernetes にウェブ アプリケーションをデプロイする
- Istio へのトラフィック ルーティング ルールの作成と適用
- Prometheus 指標
- Kubernetes クラスタ内でコンテナ イメージをビルドして push する
2. 設定方法
この Codelab は、次のいずれかで進めることができます。
- Google Cloud Shell (推奨): ブラウザ内シェル。ツールがインストールされている
- ノートパソコン(以下の手順に沿って操作してください)
Google Cloud Platform を使ってみる
- GCP アカウントをお持ちでない場合は、講師から無料のユーザー アカウント カードを受け取ってください。
- Google Cloud Console に移動し、[プロジェクトを選択](
)をクリックします。 - プロジェクトの「ID」をメモしておき、プロジェクトをクリックして選択します。

オプション 1: Google Cloud Shell を使用する(推奨)
Cloud Shell は、必要なツールがインストールされ、Google Cloud Platform アカウントに自動的に認証された、ブラウザ内のコマンドライン シェルを提供します。(Cloud Shell でこの演習を実行しない場合は、次のセクションに進んでください)。
Cloud コンソールに移動し、右上のツールバーにある [Cloud Shell をアクティブにする] をクリックします。

Cloud Shell にツールを追加する
または、次のコマンドを実行して両方を ~/.bin にインストールし、$PATH に追加します。
mkdir -p ~/.bin && \
cd ~/.bin && \
curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubectx && \
chmod +x kubectx && \
curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubens && \
chmod +x kubens && \
curl -LO https://storage.googleapis.com/kubernetes-helm/helm-v2.12.0-linux-amd64.tar.gz && \
tar xzf helm-v2.12.0-linux-amd64.tar.gz && \
rm helm-v2.12.0-linux-amd64.tar.gz && \
mv linux-amd64/helm ./helm && \
rm -r linux-amd64 && \
export PATH=${HOME}/.bin:${PATH}
Cloud Shell を使いやすくするための簡単なヒントをいくつかご紹介します。
1. シェルを新しいウィンドウに分離します。 |
|
2. ファイル エディタを使用する場合: 右上にある鉛筆アイコンをクリックして、ブラウザ内のファイル エディタを起動します。この機能は、コード スニペットをファイルにコピーする際に役立ちます。 |
|
3. 新しいタブを開始する: 複数のターミナル プロンプトが必要な場合。 |
|
4. テキストを大きくする: Cloud Shell のデフォルトのフォントサイズは小さすぎて読めない場合があります。 | Linux/Windows の場合: Ctrl-+、macOS の場合: ⌘-+。 |
オプション 2: ノートパソコンを設定する(非推奨)
Cloud Shell よりも独自のワークステーション環境を使用する方が快適な場合は、次のツールを設定します。
gcloud:をインストールします(Cloud Shell にプリインストールされています)。手順に沿って、プラットフォームにgcloudをインストールします。これを使用して Kubernetes クラスタを作成します。kubectl:をインストールします(Cloud Shell にプリインストールされています)。次のコマンドを実行してインストールします。
gcloud components install kubectl
次のコマンドを実行して gcloud を認証します。Google アカウントでのログインを求められます。次に、事前に作成したプロジェクト(上記参照)をデフォルト プロジェクトとして選択します。(コンピューティング ゾーンの構成はスキップできます)。
gcloud init
3. GCP プロジェクトの設定
プロジェクトで GKE(Google Kubernetes Engine)、GCR(Google Container Registry)、GCB(Google Cloud Build)API を有効にします。
gcloud services enable \ cloudapis.googleapis.com \ container.googleapis.com \ containerregistry.googleapis.com \ cloudbuild.googleapis.com
環境変数を設定する
設定中に Google Cloud プロジェクトを頻繁に使用するため、簡単に参照できるように環境変数を設定しましょう。
export GCLOUD_PROJECT=$(gcloud config get-value project)
このワークショップでは、コードファイルと構成ファイルを作成します。プロジェクト ディレクトリを作成して、そのディレクトリに移動しましょう。
mkdir -p src/istio-burst && \ cd src/istio-burst && \ export proj=$(pwd)
4. 「primary」Kubernetes クラスタを作成します
Google Kubernetes Engine(GKE)を使用すると、マネージド Kubernetes クラスタを簡単に作成できます。
次のコマンドは、Kubernetes クラスタを作成します。
- 「primary」という名前の
- us-west1-a ゾーンに
- 利用可能な Kubernetes の最新バージョン。
- 初期ノード数 4
export cluster=primary
export zone=us-west1-a
gcloud container clusters create $cluster --zone $zone --username "admin" \
--cluster-version latest --machine-type "n1-standard-2" \
--image-type "COS" --disk-size "100" \
--scopes "https://www.googleapis.com/auth/compute",\
"https://www.googleapis.com/auth/devstorage.read_only",\
"https://www.googleapis.com/auth/logging.write",\
"https://www.googleapis.com/auth/monitoring",\
"https://www.googleapis.com/auth/servicecontrol",\
"https://www.googleapis.com/auth/service.management.readonly",\
"https://www.googleapis.com/auth/trace.append" \
--num-nodes "4" --network "default" \
--enable-cloud-logging --enable-cloud-monitoring --enable-ip-alias
(この処理には 5 分ほどかかることがあります。クラスタの作成は Cloud Console で確認できます)。
Kubernetes クラスタが作成されると、gcloud はクラスタを指す認証情報を使用して kubectl を構成します。
gcloud container clusters get-credentials $cluster --zone=$zone
これで、新しいクラスタで kubectl を使用できるようになります。
次のコマンドを実行して、クラスタの Kubernetes ノードを一覧表示します(ステータスが「Ready」と表示されます)。
kubectl get nodes
使いやすいように Kubeconfig 名を変更する
コンテキストを頻繁に切り替えるため、クラスタの短いエイリアスがあると便利です。
このコマンドは、作成した kubeconfig エントリの名前を primary に変更します。
kubectx ${cluster}=gke_${GCLOUD_PROJECT}_${zone}_${cluster}
権限を設定する:
Istio をデプロイするには、クラスタ管理者である必要があります。このコマンドは、Google Cloud アカウントに関連付けられているメールアドレスをクラスタ管理者として設定します。
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole=cluster-admin \
--user=$(gcloud config get-value core/account)
5. 「バースト」クラスタを作成する
次のコマンドは、Kubernetes クラスタを作成します。
- 「burst」という名前の
- us-west1-a ゾーンに
- 利用可能な Kubernetes の最新バージョン。
- 初期ノード数 1
- 最大 5 ノードまでの自動スケーリングが有効
export cluster=burst
export zone=us-west1-a
gcloud container clusters create $cluster --zone $zone --username "admin" \
--cluster-version latest --machine-type "n1-standard-2" \
--image-type "COS" --disk-size "100" \
--scopes "https://www.googleapis.com/auth/compute",\
"https://www.googleapis.com/auth/devstorage.read_only",\
"https://www.googleapis.com/auth/logging.write",\
"https://www.googleapis.com/auth/monitoring",\
"https://www.googleapis.com/auth/servicecontrol",\
"https://www.googleapis.com/auth/service.management.readonly",\
"https://www.googleapis.com/auth/trace.append" \
--num-nodes "1" --enable-autoscaling --min-nodes=1 --max-nodes=5 \
--network "default" \
--enable-cloud-logging --enable-cloud-monitoring --enable-ip-alias
(この処理には 5 分ほどかかることがあります。クラスタの作成は Cloud Console で確認できます)。
Kubernetes クラスタが作成されると、gcloud はクラスタを指す認証情報を使用して kubectl を構成します。
gcloud container clusters get-credentials $cluster --zone=$zone
これで、新しいクラスタで kubectl を使用できるようになります。
次のコマンドを実行して、クラスタの Kubernetes ノードを一覧表示します(ステータスが「Ready」と表示されます)。
kubectl get nodes
使いやすいように Kubeconfig 名を変更する
このコマンドは、作成した kubeconfig エントリを burst に変更します。
kubectx ${cluster}=gke_${GCLOUD_PROJECT}_${zone}_${cluster}
権限を設定する:
Istio Remote をデプロイするには、クラスタ管理者である必要があります。このコマンドは、Google Cloud アカウントに関連付けられているメールアドレスをクラスタ管理者として設定します。
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole=cluster-admin \
--user=$(gcloud config get-value core/account)
6. ファイアウォール ルールを適用する
2 つのクラスタが相互に通信できるようにするには、ファイアウォール ルールを作成する必要があります。
次のコマンドを実行して、クラスタ間の通信を許可するファイアウォール ルールを Google Cloud Platform に作成します。
function join_by { local IFS="$1"; shift; echo "$*"; }
ALL_CLUSTER_CIDRS=$(gcloud container clusters list \
--filter="(name=burst OR name=primary) AND zone=$zone" \
--format='value(clusterIpv4Cidr)' | sort | uniq)
ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}"))
ALL_CLUSTER_NETTAGS=$(gcloud compute instances list \
--filter="(metadata.cluster-name=burst OR metadata.cluster-name=primary) AND metadata.cluster-location=us-west1-a" \
--format='value(tags.items.[0])' | sort | uniq)
ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
gcloud compute firewall-rules create istio-multicluster-test-pods \
--allow=tcp,udp,icmp,esp,ah,sctp \
--direction=INGRESS \
--priority=900 \
--source-ranges="${ALL_CLUSTER_CIDRS}" \
--target-tags="${ALL_CLUSTER_NETTAGS}" --quiet
これで、両方のクラスタが設定され、アプリケーションと Istio をデプロイする準備が整いました。
7. Istio の概要
Istio とは
Istio は、「サービスの接続、保護、制御、監視」を目的としたサービス メッシュ コントロール プレーンです。これはさまざまな方法で行われますが、主にプロキシ コンテナ(Envoy)をデプロイされた各 Kubernetes Pod にサイドカーとして追加することで行われます。プロキシ コンテナは、汎用ポリシーとテレメトリー ハブ(Mixer)と連携して、マイクロサービス間のすべてのネットワーク通信を制御します。

これらのポリシーは Kubernetes の Deployment と Service とは独立して適用できます。つまり、ネットワーク オペレーターは、関連するアプリケーションを再デプロイすることなく、ネットワーク アクティビティを監視し、ネットワーク ポリシーを制限、リダイレクト、書き換えることができます。
Istio がサポートするトラフィック管理機能には、次のようなものがあります。
- サーキット ブレーカー
- 割合に基づくトラフィック分割
- URL の書き換え
- TLS 終端
- ヘルスチェック
- 負荷分散
このワークショップでは、割合ベースのトラフィック分割に焦点を当てます。
Istio で使用する用語
VirtualService
VirtualService は、ホストがアドレス指定されたときに適用される一連のトラフィック ルーティング ルールを定義します。
Gateway
ゲートウェイは、メッシュのエッジで動作し、受信または送信 HTTP/TCP 接続を処理するロードバランサです。ゲートウェイでは、ポートや SNI 構成などを指定できます。
DestinationRule
DestinationRule は、ルーティングの後にサービス宛てのトラフィックに適用されるポリシーを定義します。ロード バランシングの構成、サイドカーからの接続プール サイズ、外れ値検出の設定を指定します。
Istio Multicluster
2 つのクラスタを作成したときに、primary クラスタは自動スケーリングなしの 4 つのノードで、burst クラスタは最大 5 つのノードで自動スケーリングされる 1 つのノードであったことに気づいたかもしれません。
この構成には 2 つの理由があります。
まず、オンプレミスからクラウドへのシナリオをシミュレートします。オンプレミス環境では、インフラストラクチャが固定されているため、自動スケーリング クラスタにアクセスできません。
第 2 に、Istio を実行するための最小要件は、4 ノードの設定(上記で定義)です。ここで疑問が生じます。Istio には少なくとも 4 つのノードが必要ですが、burst クラスタで 1 つのノードで Istio を実行するにはどうすればよいでしょうか?Istio Multicluster は、Istio サービスの小規模なセットをインストールし、プライマリ クラスタの Istio インストールと通信してポリシー ルールを取得し、テレメトリー情報を公開します。
8. アプリケーション アーキテクチャの概要
コンポーネントの概要
このチュートリアルでは、NodeJS と Redis を使用して 3 階層アプリケーションをデプロイします。
ワーカー
ワーカー アプリケーションは NodeJS で記述されており、受信した POST HTTP リクエストをリッスンし、それに対してハッシュ オペレーションを実行します。PREFIX という名前の環境変数が定義されている場合は、ハッシュの先頭にその値を追加します。ハッシュが計算されると、アプリケーションは指定された Redis サーバーのチャンネル「calculation」で結果を送信します。
PREFIX 環境変数は、後でマルチクラスタ機能を説明するために使用します。
参考: アプリケーションが使用するパッケージは次のとおりです。
body-parser:http リクエストの解析を許可しますcors:クロスオリジン リソース シェアリングの使用を許可しますdotenv:環境変数の解析が容易express:簡単なウェブサイト ホスティングioredis:Redis データベースと通信するためのクライアント ライブラリmorgan:構造化されたログを提供
フロントエンド
フロントエンドも express を使用してウェブページをホストする NodeJS アプリケーションです。ユーザーが入力した頻度を受け取り、そのレートで worker アプリケーションにリクエストを送信します。このアプリケーションは、「calculation」という名前の Redis チャネルのメッセージもサブスクライブし、結果をウェブページに表示します。
アプリケーションは次の依存関係を使用します。
body-parser:http リクエストの解析を許可しますdotenv:環境変数の解析が容易express:簡単なウェブサイト ホスティングioredis:Redis データベースと通信するためのクライアント ライブラリmorgan:構造化されたログを提供しますrequest:HTTP リクエストの作成を許可しますsocket.io:ウェブページからサーバーへの双方向通信を可能にします
このウェブページでは、スタイリングに Bootstrap を使用しています。実行すると、次のようになります。

アーキテクチャ図

デプロイメント図
作成した 2 つのクラスタに最終的なアプリケーションをデプロイします。primary クラスタにはすべてのコンポーネント(frontend、worker、Redis)がデプロイされますが、burst クラスタには worker アプリケーションのみがデプロイされます。
次の図は、2 つのクラスタを示しています。赤色の枠で囲まれたボックスは Kubernetes Service、青色の枠で囲まれたボックスは Kubernetes Deployment です。黄色のボックスは、Istio のインストールを示しています。
クラスタに Redis の Deployment がないにもかかわらず、burst クラスタには Redis の Service がデプロイされていることに注目してください。Kubernetes DNS がリクエストを解決できるように、このサービスをクラスタに配置する必要がありますが、リクエストが実際に作成されると、Istio Proxy はリクエストを primary クラスタの Redis デプロイに再ルーティングします。
最終的なアプリケーションには、primary クラスタで実行されている istiowatcher. という名前の Deployment が追加されます。これにより、トラフィックが特定のしきい値を超えたときに、トラフィックを burst に自動的に動的に再ルーティングできます。

9. アプリケーション デプロイ ファイルを作成する
アプリケーションをデプロイするための一連の Kubernetes マニフェストを作成する必要があります。
プロジェクトのルート ディレクトリに移動し、kubernetes という名前の新しいフォルダを作成します。
mkdir ${proj}/kubernetes && cd ${proj}/kubernetes
frontend.yaml を作成する
これにより、フロントエンド イメージにアクセスするための Kubernetes Deployment と Service の両方が作成されます。
次の内容を frontend.yaml に挿入します。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: frontend-deployment
labels:
app: frontend
spec:
replicas: 1
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: gcr.io/istio-burst-workshop/frontend
ports:
- containerPort: 8080
readinessProbe:
initialDelaySeconds: 10
httpGet:
path: "/_healthz"
port: 8080
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-readiness-probe"
livenessProbe:
initialDelaySeconds: 10
httpGet:
path: "/"
port: 8080
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-liveness-probe"
env:
- name: PORT
value: "8080"
- name: PROCESSOR_URL
value: "http://worker-service"
- name: REDIS_URL
value: "redis-cache-service:6379"
---
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
type: ClusterIP
selector:
app: frontend
ports:
- name: http
port: 80
targetPort: 8080
Deployment で注意すべき点
- アプリケーションが実行されるポートを
8080に指定しました。 - ワーカーのアドレスを「
http://worker-service」に設定し、Kubernetes の組み込み DNS 機能を使用して結果のサービスを解決します。 REDIS_URLのアドレスを「redis-cache-service:6379」に設定し、Kubernetes の組み込み DNS 機能を使用して結果の IP アドレスを解決します。- また、コンテナが起動して実行中であることを Kubernetes に通知するために、コンテナに
livenessプローブとreadinessプローブを設定しました。
worker-service.yaml を作成する
この Service は複数のクラスタで再利用しますが、Deployment はクラスタごとに異なるものを記述するため、Kubernetes Service の定義は Deployment の定義とは別のファイルに記述します。
worker-service.yaml に以下を挿入します。
apiVersion: v1
kind: Service
metadata:
name: worker-service
spec:
type: ClusterIP
selector:
app: worker
ports:
- name: http
port: 80
targetPort: 8081
worker-primary.yaml を作成する
これは、プライマリ クラスタに push する worker のデプロイになります。
次の内容を worker-primary.yaml に挿入します。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: worker-deployment
labels:
app: worker
spec:
replicas: 1
selector:
matchLabels:
app: worker
template:
metadata:
labels:
app: worker
cluster-type: primary-cluster
spec:
containers:
- name: worker
image: gcr.io/istio-burst-workshop/worker
imagePullPolicy: Always
ports:
- containerPort: 8081
readinessProbe:
initialDelaySeconds: 10
httpGet:
path: "/_healthz"
port: 8081
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-readiness-probe"
livenessProbe:
initialDelaySeconds: 10
httpGet:
path: "/"
port: 8081
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-liveness-probe"
env:
- name: PORT
value: "8081"
- name: REDIS_URL
value: "redis-cache-service:6379"
この例では、liveness プローブと readiness プローブを提供し、アプリケーションで使用する PORT 環境変数と REDIS_URL 環境変数を指定するという同じパターンに従っています。
このデプロイで注意すべきもう 1 つの点は、PREFIX 環境変数がないことです。つまり、計算結果は生のハッシュになります(接頭辞は付きません)。
このデプロイの最後の重要なポイントは、cluster-type: primary-cluster ラベルです。これは、後で Istio マルチクラスタでトラフィック ルーティングを行う際に使用します。
redis.yaml を作成する
ワーカーからフロントエンドへの通信は Redis チャネルを介して行われるため、Redis アプリケーションをクラスタにデプロイする必要があります。
redis.yaml に以下を挿入します。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: redis-cache
spec:
template:
metadata:
labels:
app: redis-cache
spec:
containers:
- name: redis
image: redis:alpine
ports:
- containerPort: 6379
readinessProbe:
periodSeconds: 5
tcpSocket:
port: 6379
livenessProbe:
periodSeconds: 5
tcpSocket:
port: 6379
volumeMounts:
- mountPath: /data
name: redis-data
resources:
limits:
memory: 256Mi
cpu: 125m
requests:
cpu: 70m
memory: 200Mi
volumes:
- name: redis-data
emptyDir: {}
これは、Redis アプリケーションの半標準的なデプロイです。redis:alpine イメージに基づいてコンテナを起動し、適切なポートを公開して、適切なリソースの上限を設定します。
redis-service.yaml を作成する
Redis アプリケーションと通信するには、Kubernetes Service が必要です。
redis-service.yaml に以下を挿入します。
apiVersion: v1
kind: Service
metadata:
name: redis-cache-service
spec:
type: ClusterIP
selector:
app: redis-cache
ports:
- port: 6379
targetPort: 6379
これにより、Redis Deployment にアクセスするための redis-cache-service という名前のサービスが提供されます。
10. アプリケーションをデプロイする
イメージを GCR に push し、Kubernetes マニフェストを作成したので、アプリケーションをデプロイして動作を確認しましょう。
次のコマンドを実行して、アプリケーションをデプロイします。
- 正しいクラスタにいることを確認する
kubectx primary
- Redis Cache をデプロイする
kubectl apply -f redis.yaml
- Redis Service をデプロイする
kubectl apply -f redis-service.yaml
- フロントエンドをデプロイする
kubectl apply -f frontend.yaml
- ワーカーをデプロイする
kubectl apply -f worker-primary.yaml
- ワーカー サービスをデプロイする
kubectl apply -f worker-service.yaml
アプリケーションを GKE にデプロイしました。おめでとうございます!
テスト
Pod がオンラインになるまで待ちます
kubectl get pods -w
すべての Pod が「実行中」になったら、Ctrl+C キーを押します。
NAME READY STATUS RESTARTS AGE frontend-deployment-695d95fbf7-76sd8 1/1 Running 0 2m redis-cache-7475999bf5-nxj8x 1/1 Running 0 2m worker-deployment-5b9cf9956d-g975p 1/1 Running 0 2m
フロントエンドを LoadBalancer 経由で公開していないことに注意してください。これは、後で Istio 経由でアプリケーションにアクセスするためです。すべてが稼働していることをテストするには、次のコマンドを実行して、ローカルマシン(または Cloud Shell)のポート 8080 を frontend デプロイを実行しているポート 8080 に転送します。kubectl port-forward.
kubectl port-forward \
$(kubectl get pods -l app=frontend -o jsonpath='{.items[0].metadata.name}') \
8080:8080
ローカルで実行している場合: ウェブブラウザを開き、http://localhost:8080 に移動します。
Cloud Shell で実行している場合: [ウェブでプレビュー] ボタンをクリックし、[ポート 8080 でプレビュー] を選択します。

フロントエンドが表示されます。[頻度] ボックスに数値を入力すると、ハッシュが表示されます。

おめでとうございます。すべてが稼働中です。
Ctrl+C を押して、ポートの転送を停止します。
11. デプロイされたアプリケーションをクリーンアップする
Istio をクラスタに適用してからアプリケーションを再デプロイするので、まず現在のアプリケーションをクリーンアップしましょう。
次のコマンドを実行して、作成した Deployment と Service をすべて削除します。
redis-cache-serviceを削除
kubectl delete -f redis-service.yaml
redisを削除
kubectl delete -f redis.yaml
frontendを削除
kubectl delete -f frontend.yaml
workerを削除
kubectl delete -f worker-primary.yaml
worker-serviceを削除
kubectl delete -f worker-service.yaml
12. プライマリ クラスタに Istio をインストールする
Istio を入手する
Istio のリリースは GitHub でホストされています。次のコマンドを実行すると、istio のバージョン 1.0.0 がダウンロードされ、解凍されます。
- プロジェクトのルートに移動する
cd ${proj}
- アーカイブをダウンロードする
curl -LO https://github.com/istio/istio/releases/download/1.0.0/istio-1.0.0-linux.tar.gz
- アーカイブを解凍して削除する
tar xzf istio-1.0.0-linux.tar.gz && rm istio-1.0.0-linux.tar.gz
Istio テンプレートを作成する
次の Helm コマンドを実行すると、クラスタに Istio をインストールするためのテンプレートが作成されます。
helm template istio-1.0.0/install/kubernetes/helm/istio \ --name istio --namespace istio-system \ --set prometheus.enabled=true \ --set servicegraph.enabled=true > istio-primary.yaml
これにより、Istio のデプロイと実行に必要なすべての定義と仕様を含む istio-primary.yaml という名前のファイルが現在のディレクトリに作成されます。
2 つの --set パラメータを確認してください。これらのアドオンは、Istio システムに Prometheus と ServiceGraph のサポートを追加します。このラボでは、後ほど Prometheus サービスを使用します。
Istio をデプロイする
Istio をデプロイするには、まず Istio の Deployment と Service が実行される istio-system という Namespace を作成する必要があります。
kubectl create namespace istio-system
最後に、Helm で作成した istio-primary.yaml ファイルを適用します。
kubectl apply -f istio-primary.yaml
デフォルトの Namespace にラベルを付ける
Istio は、サイドカー プロキシ サービスを各 Deployment に挿入することで機能します。これはオプトイン ベースで行われるため、Istio がサイドカーを自動的に挿入できるように、default Namespace に istio-injection=enabled というラベルを付ける必要があります。
kubectl label namespace default istio-injection=enabled
おめでとうございます。クラスタが稼働し、Istio がアプリケーションのデプロイの準備を整えました。
13. Istio トラフィック管理を使用してアプリケーションをデプロイする
Istio トラフィック管理構成ファイルを作成する
Istio は、構成に YAML ファイルを使用するため、Kubernetes と同様に動作します。そのため、Istio にトラフィックの公開とルーティングの方法を指示する一連のファイルを作成する必要があります。
istio-manifests という名前のディレクトリを作成し、そのディレクトリに移動します。
mkdir ${proj}/istio-manifests && cd ${proj}/istio-manifests
frontend-gateway.yaml を作成する
このファイルは、GKE LoadBalancer と同様の方法で Kubernetes クラスタを公開し、すべての受信トラフィックをフロントエンド サービスに転送します。
frontend-gateway.yaml という名前のファイルを作成し、次の内容を挿入します。
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: frontend-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: frontend-ingress-virtual-service
spec:
hosts:
- "*"
gateways:
- frontend-gateway
http:
- route:
- destination:
host: frontend-service
port:
number: 80
redis-virtualservice.yaml を作成する
redis-virtualservice.yaml という名前のファイルを作成し、次の内容を挿入します。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: redis-virtual-service
spec:
hosts:
- redis-cache-service
gateways:
- mesh
tcp:
- route:
- destination:
host: redis-cache-service.default.svc.cluster.local
worker-virtualservice.yaml を作成する
worker-virtualservice.yaml という名前のファイルを作成し、次の内容を挿入します。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
port:
number: 80
Istio トラフィック管理ポリシーをデプロイする
Istio ポリシーのデプロイは、他の Kubernetes リソースと同様に kubectl apply を使用して行います。
- Gateway を適用する
kubectl apply -f frontend-gateway.yaml
- Redis VirtualService を適用する
kubectl apply -f redis-virtualservice.yaml
- Worker VirtualService を適用する
kubectl apply -f worker-virtualservice.yaml
アプリケーションをデプロイする
kubernetesディレクトリに戻ります。
cd ${proj}/kubernetes
- Redis Cache をデプロイする
kubectl apply -f redis.yaml
- Redis Service をデプロイする
kubectl apply -f redis-service.yaml
- フロントエンドをデプロイする
kubectl apply -f frontend.yaml
- ワーカーをデプロイする
kubectl apply -f worker-primary.yaml
- ワーカー サービスをデプロイする
kubectl apply -f worker-service.yaml
確認
この時点で、Istio とトラフィック管理ポリシーを使用してクラスタにアプリケーションを再デプロイしました。
すべてのワークロードがオンラインになるまで待ちます。
すべてがオンラインになったら、frontend-ingressgateway.yaml で構成した IngressGateway を取得します。
$ kubectl -n istio-system get svc istio-ingressgateway NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 10.36.3.112 35.199.158.10 80:31380/TCP,
<EXTERNAL-IP> アドレスに移動するか、curl を実行すると、フロントエンドが表示されます。
$ curl 35.199.158.10
<!doctype html>
<html>
<head>
<title>String Hashr</title>
<!-- Bootstrap -->
...
14. 「バースト」クラスタに Istio をインストールする
primary クラスタの設定とデプロイに多くの時間を費やしましたが、デプロイするクラスタはもう 1 つあります。
このセクションでは、両方のクラスタの構成変数を取得する必要があります。各コマンドでどのクラスタが参照されているかに注意してください。
Istio リモート マニフェストを作成する
primary クラスタに Istio をデプロイしたときと同様に、Helm を使用して burst クラスタへの Istio リモートのデプロイをテンプレート化します。ただし、その前に primary クラスタに関する情報を取得する必要があります。
プライマリ クラスタ情報を収集する
primary クラスタに変更
kubectx primary
次のコマンドは、プライマリ クラスタ内のさまざまな Pod の IP アドレスを取得します。これらは、Istio Remote がプライマリ クラスタと通信するために使用されます。
export PILOT_POD_IP=$(kubectl -n istio-system get pod -l istio=pilot -o jsonpath='{.items[0].status.podIP}')
export POLICY_POD_IP=$(kubectl -n istio-system get pod -l istio-mixer-type=policy -o jsonpath='{.items[0].status.podIP}')
export STATSD_POD_IP=$(kubectl -n istio-system get pod -l istio=statsd-prom-bridge -o jsonpath='{.items[0].status.podIP}')
export TELEMETRY_POD_IP=$(kubectl -n istio-system get pod -l istio-mixer-type=telemetry -o jsonpath='{.items[0].status.podIP}')
export ZIPKIN_POD_IP=$(kubectl -n istio-system get pod -l app=jaeger -o jsonpath='{range .items[*]}{.status.podIP}{end}')
リモート テンプレートを作成する
次に、helm を使用して istio-remote-burst.yaml という名前のファイルを作成し、burst クラスタにデプロイします。
プロジェクトのルートに移動する
cd $proj
helm template istio-1.0.0/install/kubernetes/helm/istio-remote --namespace istio-system \
--name istio-remote \
--set global.remotePilotAddress=${PILOT_POD_IP} \
--set global.remotePolicyAddress=${POLICY_POD_IP} \
--set global.remoteTelemetryAddress=${TELEMETRY_POD_IP} \
--set global.proxy.envoyStatsd.enabled=true \
--set global.proxy.envoyStatsd.host=${STATSD_POD_IP} \
--set global.remoteZipkinAddress=${ZIPKIN_POD_IP} > istio-remote-burst.yaml
バースト クラスタに Istio Remote をインストールする
burst クラスタに Istio をインストールするには、primary クラスタにインストールする場合と同じ手順を実行する必要がありますが、代わりに istio-remote-burst.yaml ファイルを使用する必要があります。
kubecontext をバーストに変更する
kubectx burst
istio-system Namespace を作成する
kubectl create ns istio-system
istio-burst.yaml を適用する
kubectl apply -f istio-remote-burst.yaml
ラベルのデフォルトの Namespace
ここでも、プロキシを自動的に挿入できるように、default Namespace にラベルを付ける必要があります。
kubectl label namespace default istio-injection=enabled
おめでとうございます。これで、burst クラスタに Istio Remote が設定されました。ただし、この時点では、クラスタはまだ通信できません。burst クラスタの kubeconfig ファイルを生成し、primary クラスタにデプロイして、両者をリンクする必要があります。
「バースト」クラスタの kubeconfig を作成する
バースト クラスタに変更する
kubectx burst
環境を設定する
クラスタの kubeconfig ファイルを作成するには、クラスタに関する情報を収集する必要があります。
- クラスタの名前を取得する
CLUSTER_NAME=$(kubectl config view --minify=true -o "jsonpath={.clusters[].name}")
- クラスタ サーバー名を取得する
SERVER=$(kubectl config view --minify=true -o "jsonpath={.clusters[].cluster.server}")
istio-multiサービス アカウントの認証局の Secret の名前を取得する
SECRET_NAME=$(kubectl get sa istio-multi -n istio-system -o jsonpath='{.secrets[].name}')
- 前のシークレットに保存されている認証局データを取得する
CA_DATA=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['ca\.crt']}")
- 前のシークレットに保存されているトークンを取得する
TOKEN=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['token']}" | base64 --decode)
kubeconfig ファイルを作成する
これらの環境変数をすべて設定したら、kubeconfig ファイルを作成する必要があります。
cat <<EOF > burst-kubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ${CA_DATA}
server: ${SERVER}
name: ${CLUSTER_NAME}
contexts:
- context:
cluster: ${CLUSTER_NAME}
user: ${CLUSTER_NAME}
name: ${CLUSTER_NAME}
current-context: ${CLUSTER_NAME}
kind: Config
preferences: {}
users:
- name: ${CLUSTER_NAME}
user:
token: ${TOKEN}
EOF
これにより、現在のディレクトリに burst-kubeconfig という新しいファイルが作成されます。このファイルは、primary クラスタが burst クラスタの認証と管理に使用できます。
プライマリ クラスタに戻す
kubectx primary
シークレットを作成してラベル付けし、「バースト」の kubeconfig を適用する
kubectl create secret generic burst-kubeconfig --from-file burst-kubeconfig -n istio-system
Istio がマルチクラスタ認証に使用するように、Secret にラベルを付けます。
kubectl label secret burst-kubeconfig istio/multiCluster=true -n istio-system
おめでとうございます。両方のクラスタが認証され、Istio Multicluster を介して相互に通信しています。アプリケーションをクラスタ間でデプロイする
15. クロス クラスタ アプリケーションをデプロイする
Deployment を作成する
kubernetes ディレクトリに移動します。
cd ${proj}/kubernetes
「バースト」クラスタのワーカー デプロイを作成する: worker-burst.yaml
worker-burst.yaml という名前のファイルを作成し、次の内容を挿入します。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: worker-deployment
labels:
app: worker
spec:
replicas: 1
selector:
matchLabels:
app: worker
template:
metadata:
labels:
app: worker
cluster-type: burst-cluster
spec:
containers:
- name: worker
image: gcr.io/istio-burst-workshop/worker
imagePullPolicy: Always
ports:
- containerPort: 8081
readinessProbe:
initialDelaySeconds: 10
httpGet:
path: "/_healthz"
port: 8081
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-readiness-probe"
livenessProbe:
initialDelaySeconds: 10
httpGet:
path: "/"
port: 8081
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-liveness-probe"
env:
- name: PORT
value: "8081"
- name: REDIS_URL
value: "redis-cache-service:6379"
- name: PREFIX
value: "bursty-"
これは、先ほど作成した worker-primary.yaml とほぼ同じです。主な違いは次の 2 つです。
最初の大きな違いは、値「bursty-」の PREFIX 環境変数が追加されたことです。
env:
- name: PORT
value: "8081"
- name: REDIS_URL
value: "redis-cache-service:6379"
- name: PREFIX
value: "bursty-"
つまり、burst クラスタのワーカーは、送信するすべてのハッシュに「bursty-」という接頭辞を付けます。これを使用して、アプリケーションが真にクロス クラスタであることを確認できます。
2 つ目の大きな違いは、このデプロイの cluster-type ラベルを primary-cluster から burst-cluster に変更したことです。
labels:
app: worker
cluster-type: burst-cluster
このラベルは、後で VirtualService を更新するときに使用します。
Istio サービスの変更
現在、Istio サービスは両方のデプロイを活用していません。トラフィックの 100% が「プライマリ」クラスタにルーティングされています。これをわかりやすく変更しましょう。
istio-manifests ディレクトリに移動します。
cd ${proj}/istio-manifests
DestinationRule を含めるように worker-virtualservice.yaml を編集する
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
subset: primary
port:
number: 80
weight: 50
- destination:
host: worker-service.default.svc.cluster.local
subset: burst
port:
number: 80
weight: 50
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: worker-destination-rule
spec:
host: worker-service
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: primary
labels:
cluster-type: primary-cluster
- name: burst
labels:
cluster-type: burst-cluster
VirtualService に 2 つ目の宛先が追加されています。同じホスト(worker-service.default.svc.cluster.local))を参照しますが、トラフィックの 50% は primary サブセットにルーティングされ、残りの 50% は burst サブセットにルーティングされます。
primary サブセットはラベル cluster-type: primary-cluster を持つデプロイ、burst サブセットはラベル cluster-type: burst-cluster を持つデプロイとして定義されています。
これにより、トラフィックが 2 つのクラスタ間で 50/50 に分割されます。
クラスタにデプロイ
redis-service.yaml をバースト クラスタにデプロイする
burst kubeconfig に変更
kubectx burst
プロジェクトのルートに移動する
cd ${proj}
次に、デプロイします。
バースト クラスタに redis-service.yaml をデプロイする
kubectl apply -f kubernetes/redis-service.yaml
worker-burst.yaml をバースト クラスタにデプロイする
kubectl apply -f kubernetes/worker-burst.yaml
burst クラスタに worker-service.yaml をデプロイする
kubectl apply -f kubernetes/worker-service.yaml
Istio VirtualService を適用する
primary kubeconfig に変更
kubectx primary
デプロイ
kubectl apply -f istio-manifests/worker-virtualservice.yaml
動作を確認する
機能していることを確認するには、Istio Ingress ポイントに移動します。ハッシュの約 50% に「burst-」という接頭辞が付いていることを確認します。

これは、クラスタ間の通信が正常に行われていることを意味します。さまざまなサービスで重みを変更し、worker-virtualservice.yaml ファイルを適用してみてください。これはクラスタ間のトラフィックのバランスを取る優れた方法ですが、自動的に行うことはできないでしょうか?
16. Prometheus 指標の活用
Prometheus の概要
Prometheus は、SoundCloud で最初に構築されたオープンソースのシステム モニタリングとアラート ツールキットです。指標名と Key-Value ペアで識別される時系列データを含む多次元データモデルを維持します。
参考までに、Prometheus のアーキテクチャ図を以下に示します。

Istio は、Prometheus とともにデプロイされると、さまざまな指標を Prometheus サーバーに自動的にレポートします。これらの指標を使用して、クラスタをオンザフライで管理できます。
Prometheus 指標の探索
まず、Prometheus Deployment を公開する必要があります。
GKE の [ワークロード] タブに移動し、[prometheus] ワークロードをドリルダウンします。

デプロイの詳細が表示されたら、[アクション] -> [公開] に移動します。

ポート 9090 に転送するよう選択し、「ロードバランサ」と入力します

[公開] を選択します。
これにより、Prometheus 指標の探索に使用できる一般公開の IP アドレスに Service が作成されます。
エンドポイントが動作可能になるまで待ち、動作可能になったら、[外部エンドポイント] の横にある IP アドレス
をクリックします。
Prometheus UI が表示されます。

Prometheus は、独自のワークショップに十分な指標を提供します。ここでは、まず istio_requests_total 指標について説明します。
このクエリを実行すると、大量のデータが返されます。これは、Istio サービス メッシュを通過するすべてのリクエストに関する指標であり、その数は膨大です。式を変更して、本当に興味のあるものに絞り込みます。
宛先サービスが worker-service.default.svc.cluster.local で、送信元が frontend-deployment のリクエスト(過去 15 秒間に限定)
クエリは次のようになります。
istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s]
これにより、はるかに管理しやすいデータセットで作業できるようになります。

しかし、まだ少し密度が高いです。すべてのリクエストではなく、1 秒あたりのリクエスト数を知りたい。
これには、組み込みの rate 関数を使用します。
rate(istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s])

これでかなり近づきましたが、これらの指標を論理グループにさらに絞り込む必要があります。
これを行うには、sum キーワードと by キーワードを使用して結果をグループ化し、合計します。
sum(rate(istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s])) by (source_workload,
source_app, destination_service)

これで終了です。Prometheus から必要な指標を正確に取得できます。
最終的な Prometheus クエリ
これまでの学習を踏まえて、Prometheus に問い合わせる必要がある最終的なクエリは次のようになります。
sum(rate(istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s])) by (source_workload,
source_app, destination_service)
これで、HTTP API を使用して指標を取得できます。
次のように HTTP GET リクエストを行うことで、クエリを使用して API をクエリできます。<prometheus-ip-here> は置き換えてください。
curl http://<prometheus-ip-here>/api/v1/query?query=sum\(rate\(istio_requests_total%7Breporter%3D%22destination%22%2C%0Adestination_service%3D%22worker-service.default.svc.cluster.local%22%2C%0Asource_workload%3D%22frontend-deployment%22%7D%5B15s%5D\)\)%20by%20\(source_workload%2C%0Asource_app%2C%20destination_service\)
以下に示すのはレスポンスの例です。
{
"status": "success",
"data": {
"resultType": "vector",
"result": [
{
"metric": {
"destination_service": "worker-service.default.svc.cluster.local",
"source_app": "frontend",
"source_workload": "frontend-deployment"
},
"value": [
1544404907.503,
"18.892886390062788"
]
}
]
}
}
これで、JSON から指標値を抽出できます。
クリーンアップ
Prometheus の公開に使用した Service を削除する必要があります。Google Cloud コンソールで、作成したサービスの上部に移動し、[削除] をクリックします。

次のステップ:
クラスタ内のトラフィックの移動方法とレートを検出する方法を考えたので、次のステップでは、Prometheus を定期的にクエリする小さなバイナリを作成します。worker への 1 秒あたりのリクエスト数が特定のしきい値を超えた場合は、ワーカー仮想サービスに異なる宛先重みを適用して、すべてのトラフィックを burst クラスタに送信します。1 秒あたりのリクエスト数が下限しきい値を下回ったら、すべてのトラフィックを primary に戻します。
17. クロス クラスタ バーストを作成する
設定
worker-service のすべてのトラフィックをプライマリ クラスタに設定する
worker-service 宛てのすべてのトラフィックが primary クラスタに転送される状態を、アプリケーションの「デフォルト」状態と見なします。
$proj/istio-manifests/worker-virtualservice.yaml を次のように編集します。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
subset: primary
port:
number: 80
weight: 100
- destination:
host: worker-service.default.svc.cluster.local
subset: burst
port:
number: 80
weight: 0
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: worker-destination-rule
spec:
host: worker-service
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: primary
labels:
cluster-type: primary-cluster
- name: burst
labels:
cluster-type: burst-cluster
primary クラスタに接続していることを確認する
kubectx primary
istio-manifests/worker-virtualservice.yaml を適用する
kubectl apply -f istio-manifests/worker-virtualservice.yaml
istiowatcher デーモンを記述する
このサービスは、速度と移植性の面から Go を使用して記述します。アプリケーションの全体的なフローは、起動して 1 秒ごとに Prometheus にクエリを実行することです。
src に istiowatcher という新しいディレクトリを作成します。
mkdir -p ${proj}/src/istiowatcher && cd ${proj}/src/istiowatcher
クラスタ内から Istio コントロール プレーンを操作するために、コンテナ内から istioctl を呼び出します。
istiowatcher.go を作成する
そのディレクトリに istiowatcher.go という名前のファイルを作成し、次の内容を挿入します。
package main
import (
"github.com/tidwall/gjson"
"io/ioutil"
"log"
"net/http"
"os/exec"
"time"
)
func main() {
//These are in requests per second
var targetLow float64 = 10
var targetHigh float64 = 15
// This is for the ticker in milliseconds
ticker := time.NewTicker(1000 * time.Millisecond)
isBurst := false
// Our prometheus query
reqQuery := `/api/v1/query?query=sum(rate(istio_requests_total{reporter="destination",destination_service="worker-service.default.svc.cluster.local",source_workload="frontend-deployment"}[15s]))by(source_workload,source_app,destination_service)`
for t := range ticker.C {
log.Printf("Checking Prometheus at %v", t)
// Check prometheus
// Note that b/c we are querying over the past 5 minutes, we are getting a very SLOW ramp of our reqs/second
// If we wanted this to be a little "snappier" we can scale it down to say 30s
resp, err := http.Get("http://prometheus.istio-system.svc.cluster.local:9090" + reqQuery)
if err != nil {
log.Printf("Error: %v", err)
continue
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
val := gjson.Get(string(body), "data.result.0.value.1")
log.Printf("Value: %v", val)
currentReqPerSecond := val.Float()
log.Printf("Reqs per second %f", currentReqPerSecond)
if currentReqPerSecond > targetHigh && !isBurst {
applyIstio("burst.yaml")
log.Println("Entering burst mode")
isBurst = true
} else if currentReqPerSecond < targetLow && isBurst {
applyIstio("natural.yaml")
log.Println("Returning to natural state.")
isBurst = false
}
}
}
func applyIstio(filename string) {
cmd := exec.Command("istioctl", "replace", "-f", filename)
if err := cmd.Run(); err != nil {
log.Printf("Error hit applying istio manifests: %v", err)
}
}
Dockerfile を作成する
Dockerfile という名前の新しいファイルを作成し、次の内容を挿入します。
FROM golang:1.11.2-stretch as base
FROM base as builder
WORKDIR /workdir
RUN curl -LO https://github.com/istio/istio/releases/download/1.0.0/istio-1.0.0-linux.tar.gz
RUN tar xzf istio-1.0.0-linux.tar.gz
RUN cp istio-1.0.0/bin/istioctl ./istioctl
FROM base
WORKDIR /go/src/istiowatcher
COPY . .
COPY --from=builder /workdir/istioctl /usr/local/bin/istioctl
RUN go get -d -v ./...
RUN go install -v ./...
CMD ["istiowatcher"]
このマルチステージ Dockerfile は、最初のステージで Istio の 1.0.0 リリースをダウンロードして展開します。第 2 段階では、ディレクトリ内のすべてをイメージにコピーし、ビルドステージから istioctl を /usr/local/bin にコピー(アプリケーションから呼び出せるようにするため)、依存関係を取得し、コードをコンパイルして、CMD を「istiowatcher」に設定します。
burst.yaml を作成する
これは、frontend から worker へのリクエスト/秒が 15 を超えたときに istiowatcher が適用するファイルです。
burst.yaml という名前の新しいファイルを作成し、次の内容を挿入します。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
subset: primary
port:
number: 80
weight: 0
- destination:
host: worker-service.default.svc.cluster.local
subset: burst
port:
number: 80
weight: 100
natural.yaml を作成する
frontend から worker への 1 秒あたりのリクエスト数が 10 を下回ったときに戻る「自然な」状態と見なします。この状態では、トラフィックの 100% が primary クラスタにルーティングされます。
natural.yaml という名前の新しいファイルを作成し、次の内容を挿入します。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
subset: primary
port:
number: 80
weight: 100
- destination:
host: worker-service.default.svc.cluster.local
subset: burst
port:
number: 80
weight: 0
istiowatcher をビルドして push する
次のコマンドを実行して、現在のディレクトリを Google Cloud Build(GCB)に送信します。これにより、GCR でイメージがビルドされ、タグ付けされます。
gcloud builds submit -t gcr.io/${GCLOUD_PROJECT}/istiowatcher
istiowatcher をデプロイする
kubernetes ディレクトリに移動します。
cd ${proj}/kubernetes/
デプロイ ファイル istiowatcher.yaml を作成する
istiowatcher.yaml というファイルを作成し、次の内容を挿入します(<your-project-id> は置き換えてください)。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: istiowatcher-deployment
labels:
app: istiowatcher
spec:
replicas: 1
selector:
matchLabels:
app: istiowatcher
template:
metadata:
labels:
app: istiowatcher
spec:
serviceAccountName: istio-pilot-service-account
automountServiceAccountToken: true
containers:
- name: istiowatcher
image: gcr.io/<your-project-id>/istiowatcher
imagePullPolicy: Always
導入
プライマリ クラスタで実行されていることを確認する
kubectx primary
istio-system Namespace に istiowatcher.yaml をデプロイする
kubectl apply -n istio-system -f istiowatcher.yaml
yaml の serviceAccountName ディレクティブと automountServiceAccountToken ディレクティブに注意してください。これにより、クラスタ内から istioctl を実行するために必要な認証情報が取得されます。
また、istio-pilot-service-account の認証情報を取得するために、これを istio-system 名前空間内にデプロイする必要があります。(default 名前空間に存在しない)。
トラフィックが自動的に切り替わるのを確認します。
いよいよマジック モーメントです。フロントエンドに移動して、リクエスト/秒を 20 に増やしましょう。
数秒かかりますが、すべてのハッシュに「bursty-」という接頭辞が付いています。
これは、15s の範囲で Prometheus をサンプリングしているため、レスポンス時間に少し遅延が生じるためです。バンドをさらに狭くしたい場合は、prometheus のクエリを 5s. に変更します。
18. 次のステップ
クリーンアップ
このワークショップ用に提供された一時アカウントを使用している場合は、クリーンアップする必要はありません。
Kubernetes クラスタ、ファイアウォール ルール、GCR のイメージを削除できます。
gcloud container clusters delete primary --zone=us-west1-a
gcloud container clusters delete burst --zone=us-west1-a
gcloud compute firewall-rules delete istio-multicluster-test-pods
gcloud container images delete gcr.io/$GCLOUD_PROJECT/istiowatcher
今後の展望
- Istio Talks に参加する
- 認定資格を取得する: Kubernetes + Istio で次世代のアプリを構築する
- 基調講演: Kubernetes、Istio、Knative: 新しいオープン クラウド スタック - Aparna Sinha(Google Kubernetes グループ プロダクト マネージャー)
- チュートリアル: Istio の使用 - Lee Calcote 氏、Girish Ranganathan 氏(SolarWinds)
- Istio - The Packet's-Eye View - Matt Turner, Tetrate
- Istio はこれまでで最も次世代の次世代ファイアウォールですか?- John Morello 氏、Twistlock
- Istio のドキュメントを読む
- Istio ワーキング グループに参加する
- Twitter で @IstioMesh をフォローする




