Istio1.0 on Google Kubernetes Engineの環境セットアップ

Istioとは、最近のマイクロサービス化されたコンテナ群をサービスメッシュ的に連携される仕組みを提供するものらしいが、いまいち、実感が持てないので、実際、Istio環境をセットアップしてみました。

## Google Kubernetes Engine環境をセットアップする
##### (1) gcloud コマンドライン ツールのデフォルトを設定する
```
$ export PROJECT_ID="xxxxx"
$ gcloud config set project $PROJECT_ID
$ gcloud config set compute/zone us-central1-b
Updated property [compute/zone].
```
##### (2) Kubernetes Engine クラスタを作成する
```
$ gcloud container clusters create istio-tutorial \
    --machine-type=n1-standard-2 \
    --num-nodes=4 \
    --no-enable-legacy-authorization
```
こんな感じで、Kubernetesクラスタが作成された

```
... (snip)
kubeconfig entry generated for istio-tutorial.
NAME            LOCATION       MASTER_VERSION  MASTER_IP       MACHINE_TYPE   NODE_VERSION  NUM_NODES  STATUS
istio-tutorial  us-central1-b  1.9.7-gke.6     xxx.xxx.xxx.xxx  n1-standard-2  1.9.7-gke.6   4          RUNNING
```
##### (3) 必要なクラスタができたら、現在のユーザーにクラスタ管理者権限を付与する
```
$ kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole=cluster-admin \
    --user=$(gcloud config get-value core/account)
```
## Istio環境をセットアップする
##### (1) [istioリリースページ](https://github.com/istio/istio/releases)から、Istio クライアントを実行する OS に対応したインストール ファイルをダウンロードする
##### (2) ダウンロードしたインストール ファイルを展開したのち、インストール ディレクトリに移動する
```
$ cd istio-1.0.0
```
##### (3) istioctl クライアントを PATH に追加する
```
$ export PATH=$PWD/bin:$PATH
```
##### (4) Envoy サイドカー間の[相互TLS認証](https://istio.io/docs/concepts/security/)を可能にするように、Istioコンポーネントをインストールする
```
$ kubectl apply -f install/kubernetes/istio-demo-auth.yaml
```
##### (5) Istioコンポーネントが稼働していることを確認する
```
$ kubectl get pods -n istio-system
NAME                                        READY     STATUS    RESTARTS   AGE
grafana-6995b4fbd7-nmwnf                    1/1       Running   0          7m
istio-citadel-54f4678f86-qjcr6              1/1       Running   0          7m
istio-egressgateway-c68bcd889-hxshj         1/1       Running   0          7m
istio-galley-7bd8b5f88f-rv4vn               1/1       Running   0          7m
istio-ingressgateway-665699c874-rqddl       1/1       Running   0          7m
istio-pilot-68cbbcd65d-svnht                2/2       Running   0          7m
istio-policy-7c5b5bb744-hzk4d               2/2       Running   0          7m
istio-sidecar-injector-85ccf84984-m68bk     1/1       Running   0          7m
istio-statsd-prom-bridge-55965ff9c8-zwslm   1/1       Running   0          7m
istio-telemetry-5b6c57fffc-qchtw            2/2       Running   0          7m
istio-tracing-77f9f94b98-v8sm9              1/1       Running   0          7m
prometheus-7456f56c96-nxf5k                 1/1       Running   0          7m
servicegraph-684c85ffb9-j4jqt               1/1       Running   0          7m  
```

## BookInfo サンプルアプリをデプロイする
Istioの動作確認として、BookInfoサンプルアプリが公式サイトにて公開されています
[Bookinfo Application](https://istio.io/docs/examples/bookinfo)を参考にして、BookInfo サンプルアプリケーションをセットアップします

![bookinfo.png](https://qiita-image-store.s3.amazonaws.com/0/103595/5161f8dc-2d8d-32b6-30f5-7313a222e2a4.png)


##### (1) [Manual sidecar injection](https://istio.io/docs/setup/kubernetes/sidecar-injection/#manual-sidecar-injection)を使用して、サンプルアプリをデプロイする
```
$ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml)
service "details" created
deployment "details-v1" created
service "ratings" created
deployment "ratings-v1" created
service "reviews" created
deployment "reviews-v1" created
deployment "reviews-v2" created
deployment "reviews-v3" created
service "productpage" created
deployment "productpage-v1" created
```
##### (2) サンプルアプリが正しくデプロイされていることを確認する
```
$ kubectl get services
NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
details       ClusterIP   10.19.247.134   <none>        9080/TCP   1m
kubernetes    ClusterIP   10.19.240.1     <none>        443/TCP    31m
productpage   ClusterIP   10.19.248.137   <none>        9080/TCP   1m
ratings       ClusterIP   10.19.240.176   <none>        9080/TCP   1m
reviews       ClusterIP   10.19.252.13    <none>        9080/TCP   1m
```
```
$ kubectl get pods
NAME                              READY     STATUS    RESTARTS   AGE
details-v1-74c6674976-mb8rl       2/2       Running   0          3m
productpage-v1-6f5d648f5b-75fdf   2/2       Running   0          3m
ratings-v1-76bff46c48-984tz       2/2       Running   0          3m
reviews-v1-74fbd7fc56-krkh9       2/2       Running   0          3m
reviews-v2-864964989d-sv95w       2/2       Running   0          3m
reviews-v3-5c5c4ff456-7sppm       2/2       Running   0          3m
```
##### (3) 外部からサンプルアプリにアクセスさせる
```
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
gateway "bookinfo-gateway" created
virtualservice "bookinfo" created
```
```
$ kubectl get gateway
NAME               AGE
bookinfo-gateway   35s
```
##### (4) istio-ingressgatewayの動作状態を確認する
```
$ kubectl get svc istio-ingressgateway -n istio-system
NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)                                                                                                     AGE
istio-ingressgateway   LoadBalancer   10.19.249.250   xxx.xxx.xxx.xxx   80:31380/TCP,443:31390/TCP,31400:31400/TCP,15011:31009/TCP,8060:31867/TCP,15030:31127/TCP,15031:31128/TCP   37m
```
##### (5) 環境変数: INGRESS_HOSTを設定する
```
$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
```
```
$ echo $INGRESS_HOST
xxx.xxx.xxx.xxx
```
##### (6) 環境変数: INGRESS_PORTを設定する
```
$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
```
```
$ echo $INGRESS_PORT
80
```
##### (7) 環境変数: GATEWAY_URLを設定する
```
$ export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
```
```
$ echo $GATEWAY_URL
xxx.xxx.xxx.xxx:80
```
##### (8) curlを使用して BookInfoサンプルアプリが正しく動作していることを確認する
```
$ curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/productpage
200
```
##### (9) ブラウザから、BookInfoサンプルアプリを確認する
Webブラウザ上で、リロードを繰り返すと、次の３パターンのいずれかが表示されるようになれば成功です

```
$ open http://$GATEWAY_URL/productpage
```
![BookInfo_ver1.png](https://qiita-image-store.s3.amazonaws.com/0/103595/9b988e9e-29c3-003d-08e9-1bfa3711bd7c.png)
![BookInfo_ver2.png](https://qiita-image-store.s3.amazonaws.com/0/103595/a0a94ca5-de3e-a24d-9e01-64910bec8f19.png)
![BookInfo_ver3.png](https://qiita-image-store.s3.amazonaws.com/0/103595/c6bbd170-03b6-3923-da22-75671524eb3c.png)
期待通りに、動作できているようです。

## 最後に、
Google Kubernetes Engine上に、Istio環境セットアップは無事完了しました。
次のステップとしては、独自マイクロサービス用アプリをIstioサービスメッシュ対応を目指していきます。