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 コンソールに移動し、[プロジェクトを選択] アイコン
をクリックします。 - プロジェクトの「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. 「プライマリ」Kubernetes クラスタを作成します。
Google Kubernetes Engine(GKE)を使用すると、マネージド Kubernetes クラスタを簡単に作成できます。
次のコマンドを実行すると、Kubernetes クラスタが作成されます。
- という名前のプライマリ ネットワーク インターフェースを作成します。
- 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 コンソールで確認できます)。
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 クラスタが作成されます。
- という名前の
- 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 コンソールで確認できます)。
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 は、「サービスの接続、保護、制御、監視」を目的としたサービス メッシュ コントロール プレーンです。これはさまざまな方法で行われますが、主に、デプロイされた Kubernetes Pod ごとにプロキシ コンテナ(Envoy)をサイドカーとして配置します。プロキシ コンテナは、汎用ポリシーとテレメトリー ハブ(Mixer)とともに、マイクロサービス間のすべてのネットワーク通信を制御します。

これらのポリシーは Kubernetes Deployment と Service から独立して適用できます。つまり、ネットワーク事業者は、関連するアプリケーションを再デプロイすることなく、ネットワーク アクティビティをモニタリングし、ネットワーク ポリシーを制限、リダイレクト、書き換えることができます。
Istio がサポートするトラフィック管理機能には次のものがあります。
- サーキット ブレーカー
- 割合ベースのトラフィック分割
- URL の書き換え
- TLS 終端
- ヘルスチェック
- 負荷分散
このワークショップでは、割合ベースのトラフィック分割に焦点を当てます。
使用する Istio の用語
VirtualService
VirtualService は、ホストがアドレス指定されたときに適用される一連のトラフィック ルーティング ルールを定義します。
Gateway
ゲートウェイは、メッシュのエッジで動作し、受信または送信 HTTP/TCP 接続を処理するロードバランサです。ゲートウェイでは、ポートや SNI 構成などを指定できます。
DestinationRule
DestinationRule は、ルーティングの発生後に Service を対象とするトラフィックに適用するポリシーを定義します。ロード バランシング、サイドカーからの接続プールのサイズ、外れ値検出の設定を指定します。
Istio マルチクラスタ
2 つのクラスタを作成したときに、primary クラスタは自動スケーリングなしで 4 ノード、burst クラスタは最大 5 ノードまで自動スケーリングで 1 ノードであることに気づいたかもしれません。
この構成には 2 つの理由があります。
まず、オンプレミスから Cloud へのシナリオをシミュレートします。オンプレミス環境では、インフラストラクチャが固定されているため、自動スケーリング クラスタにアクセスできません。
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 のサービスがデプロイされていることに注目してください。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
- Worker Service をデプロイする
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 経由でアプリケーションにアクセスするためです。すべてが稼働していることを確認するには、kubectl port-forward. を使用します。次のコマンドを実行して、ローカルマシン(または Cloud Shell)のポート 8080 を、frontend デプロイメントを実行しているポート 8080 に転送します。
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 とサービスをすべて削除します。
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-primary.yaml という名前のファイルが作成されます。このファイルには、Istio のデプロイと実行に必要なすべての定義と仕様が含まれています。
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
- Worker Service をデプロイする
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 リモート マニフェストを作成する
Istio を primary クラスタにデプロイしたときと同様に、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 を burst に変更する
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 がマルチクラスタ認証にシークレットを使用するようにラベルを付ける
kubectl label secret burst-kubeconfig istio/multiCluster=true -n istio-system
おめでとうございます。両方のクラスタが認証され、Istio マルチクラスタを介して相互に通信しています。アプリケーションをクラスタ間でデプロイする
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 つ目の主な違いは、この Deployment の cluster-type ラベルを primary-cluster から burst-cluster に変更したことです。
labels:
app: worker
cluster-type: burst-cluster
このラベルは、後で VirtualService を更新するときに使用します。
Istio サービスを変更する
現在、Istio サービスは両方のデプロイメントを活用していません。トラフィックの 100% が「プライマリ」クラスタにルーティングされています。これをわかりやすく変更しましょう。
istio-manifests ディレクトリに移動します。
cd ${proj}/istio-manifests
worker-virtualservice.yaml を編集して DestinationRules を含める
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 を持つ Deployment に、burst サブセットはラベル cluster-type: burst-cluster を持つ Deployment に定義されています。
これにより、トラフィックが 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
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 に転送することを選択し、「ロードバランサ」と入力します。

[公開] を選択します。
これにより、一般公開されている IP アドレスに Service が作成され、Prometheus 指標の探索に使用できるようになります。
エンドポイントが動作可能になるまで待ち、[外部エンドポイント]
の横にある 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 宛てのすべてのトラフィックが 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 で記述します。アプリケーションの全体的なフローでは、起動時に Prometheus にクエリを実行し、1 秒ごとにクエリを実行します。
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 名前空間には存在しません)。
トラフィックが自動的に切り替わる様子を確認する
次に、マジック モーメントです。フロントエンドに移動して、1 秒あたりのリクエスト数を 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 - パケットの視点 - Matt Turner、Tetrate
- Istio は、これまでに作成された中で最も次世代の次世代ファイアウォールですか?- John Morello、Twistlock
- Istio のドキュメントを読む
- Istio ワーキング グループに参加する
- Twitter で @IstioMesh をフォローする




