GKE(Google Kubernetes Engine)のistioでサンプルアプリを動かす【構築編】
マイクロサービスアーキテクチャを採用することで得られるメリットは多いですが、対応しなければならない問題も増えます。
その中でも、サービスが利用不能になった(障害が発生した)場合の対応については、慎重に検討しておく必要があります。
下流のサービスへの呼び出しが停滞すると、連鎖的にすべてのサービスが呼び出し待ちになり、システム全体がハングする可能性があるからです。
この問題の解決するためには、タイムアウトやサーキットブレーカーの導入することが一般的です。
サービス側のアプリケーションコードにこの機能を実装すればいいのですが、istioを導入することでインフラ側で制御することが可能になります。
具体的には、EnvoyとよばれるプロキシをサイドカーとしてすべてのPodにインジェクションし、トラフィックをEnvoy経由にすることで、アプリケーションコードを変更することなくタイムアウトやサーキットブレーカーを設定することができます。
そのほかにも、きめ細やかなトラフィック制御はリリース時にとても役立ちます。
そんな便利なistioを導入するために、今回は、調査としてGKE上で、istioが提供しているサンプルアプリを動かしてみたいと思います。
参考にするページは以下のとおりです。
GKEでistioをセットアップする
まず最初に、クラスタを作成します。 今回は、n1-standard-1を3つのクラスタにしてみます。
(推奨は4つらしいですが、3つでも特に問題は発生しませんでした。)
クラスタの作成時に、istioを有効にすることを忘れないでください。
セキュリティオプションは、Strict mTLSとPermissive mTLSが選択できます。
今回は、Strict mTLSを選択しました。
クラスタの作成が終わったら、下記のコマンドでクラスタのクレデンシャルを取得します。
$ gcloud container clusters get-credentials istio-test
Fetching cluster endpoint and auth data.
kubeconfig entry generated for istio-test.
namespaceを確認すると、istio-system名前空間にistio関連のPodがデプロイされている事がわかります。
$ kubectl get namespace
NAME STATUS AGE
default Active 36m
istio-system Active 35m
kube-node-lease Active 36m
kube-public Active 36m
kube-system Active 36m
istio-systemの中のPodを確認してみます。
$ kubectl -n istio-system get pods
NAME READY STATUS RESTARTS AGE
istio-citadel-5448cbc9f8-vnmlt 1/1 Running 0 35m
istio-cleanup-secrets-1.1.16-gke.0-jfcfd 0/1 Completed 0 35m
istio-galley-6bb4658798-9z7cg 1/1 Running 0 35m
istio-ingressgateway-6f664d5df6-flld7 1/1 Running 0 35m
istio-pilot-59cb7cfdfd-97lxc 2/2 Running 0 35m
istio-policy-55d7c65fc5-shm6l 2/2 Running 4 35m
istio-security-post-install-1.1.16-gke.0-l4sft 0/1 Completed 0 35m
istio-sidecar-injector-6cf9dc4549-jtgdc 1/1 Running 0 35m
istio-telemetry-745bf67755-pbtmj 2/2 Running 5 35m
promsd-b9966d7d5-pqn2s 2/2 Running 1 35m
citadelやgallery、ingressgateway、pilotなどistioを構成するPodが存在することを確認できます。
次に、defualt名前空間内にデプロイされるすべてのPodに、istioサイドカー(Envoy)を自動的にインジェクションするようにラベルを設定します。
$ kubectl label namespace default istio-injection=enabled
namespace/default labeled
$ kubectl get namespace --show-labels
NAME STATUS AGE LABELS
default Active 51m istio-injection=enabled
istio-system Active 50m addonmanager.kubernetes.io/mode=Reconcile,istio-injection=disabled,k8s-app=istio
kube-node-lease Active 51m <none>
kube-public Active 51m <none>
kube-system Active 51m <none>
これで準備が完了しました。
Bookinfoアプリケーションをクラスタにデプロイする
istioの動作を確認するために、用意されているアプリケーションをデプロイしてみます。
このアプリケーションはマイクロサービスで構成されていて、それぞれのサービスが異なる言語で実装されています。
サンプルアプリケーションは、istioのリポジトリ内にあるので、GitでCloneしてきます。
git clone git@github.com:istio/istio.git
以降は、istioディレクトリ内で作業します。
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
アプリケーションがデプロイされると、自動的にサイドカーがインジェクションされるので、それを確認します。
$ kubectl describe pods productpage-v1-7d6cfb7dfd-jrnql
~~省略~~
Containers:
productpage:
Container ID: docker://0d301e95a63663304869633e2be657996a463eb0033c26bd6c829b04e52eec28
Image: docker.io/istio/examples-bookinfo-productpage-v1:1.15.0
Image ID: docker-pullable://istio/examples-bookinfo-productpage-v1@sha256:0a5eb4795952372251d51f72834bccb7ea01a67cb72fd9b58b757cca103b7524
Port: 9080/TCP
Host Port: 0/TCP
State: Running
Started: Tue, 17 Dec 2019 10:35:39 +0900
Ready: True
Restart Count: 0
Requests:
cpu: 100m
Environment: <none>
Mounts:
/tmp from tmp (rw)
/var/run/secrets/kubernetes.io/serviceaccount from bookinfo-productpage-token-dcxph (ro)
istio-proxy:
Container ID: docker://2f0c622c5bd8761b7c3cc490c7b8c2ac01136696b73f09805e2a896839347fe4
Image: gke.gcr.io/istio/proxyv2:1.1.16-gke.0
Image ID: docker-pullable://gke.gcr.io/istio/proxyv2@sha256:5388dd8c7267a89414b12bd1f64b623caf29351cf2fe5063120d933b2e68e3e8
Port: 15090/TCP
Host Port: 0/TCP
~~省略~~
istio-proxyがインジェクションされているのが確認できます。
外部からアクセスできるようにする
最初にistio-ingessgatewayを設定します。
istio-ingessgatewayはistioサービスメッシュに、出入りするトラフィックを管理してくれます。
なので、外部からアクセスできるようにするためには、istio-ingessgatewayの設定が必要になります。
istio-ingessgatewayを設定するにはGatewayリソースを作成します。(同時にVirtualServiceも作成されます)
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created
次に、istio-ingessgatewayに割り振られている外部IPを確認します。 istio-ingressgatewayはistio-system名前空間にデプロイされています。
$ kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer **.**.**.** **.**.**.** 15020:31001/TCP,80:31422/TCP,443:31051/TCP,31400:30289/TCP,15029:31162/TCP,15030:31436/TCP,15031:31991/TCP,15032:32138/TCP,15443:32188/TCP 99m
EXTERNAL-IPが外部IPとなるので、そのIPへブラウザでアクセスしてみます。
http://**.**.**.**/productpage
外部から疎通できていることが確認できます。
ちなみに、GCLBが自動的にプロビジョニングされています。
最後に、デフォルトのDestinationRuleを作成します。
$ kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml
設定された内容を確認します。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: details
namespace: default
spec:
host: details
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: productpage
namespace: default
spec:
host: productpage
subsets:
- labels:
version: v1
name: v1
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: ratings
namespace: default
spec:
host: ratings
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
- labels:
version: v2-mysql
name: v2-mysql
- labels:
version: v2-mysql-vm
name: v2-mysql-vm
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
namespace: default
spec:
host: reviews
subsets:
- labels:
version: v1
name: v1
- labels:
version: v2
name: v2
- labels:
version: v3
name: v3
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
DestinationRuleについて詳しくふれませんが、それぞれのサービスにいくつかのバージョンが定義されているのが確認できます。
次回は、この環境を使って実際にistioの設定を変更して動作を確認していきます。
この記事を書いた人
-
2008年にアーティスへ入社。
システムエンジニアとして、SI案件のシステム開発に携わる。
その後、事業開発部の立ち上げから自社サービスの開発、保守をメインに従事。
ドメイン駆動設計(DDD)を中心にドメインを重視しながら、保守可能なソフトウェア開発を探求している。
この執筆者の最新記事
関連記事
最新記事
FOLLOW US
最新の情報をお届けします
- facebookでフォロー
- Twitterでフォロー
- Feedlyでフォロー