グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



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の設定を変更して動作を確認していきます。

この記事を書いた人

tkr2f
tkr2f事業開発部 web application engineer
2008年にアーティスへ入社。
システムエンジニアとして、SI案件のシステム開発に携わる。
その後、事業開発部の立ち上げから自社サービスの開発、保守をメインに従事。
ドメイン駆動設計(DDD)を中心にドメインを重視しながら、保守可能なソフトウェア開発を探求している。
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします