Amazon EKSを使ってIstio、Kiali、Grafana、Jaegerを触ってみよう！

マイクロサービスに欠かせない？サービスメッシュ。
概念だけ聞いてても何のことかよく分からんので、代表的なOSSであるIstioを実際に触ってみる。

ついでにサンプルアプリに同梱されているクラウドネイティブ系の監視OSSも一緒に触る。


# 準備するもの
- ハンズオン用PC（本記事ではM1 Mac）
- CLIツール（本記事ではMac標準ターミナル）
- AWSアカウント


# Istio＆Kialiハンズオン

### 必要ツールをインストールする

AWS CLIをインストールする。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

AWS CLIの初期設定を実施。自分のAWSアカウントへ紐づける。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-quickstart.html

Macのターミナルにて以下を実行。

```bash
$ aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

※アクセスキーIDとシークレットはAWSマネコンにて発行＆確認可能。
![スクリーンショット 2022-06-11 22.10.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/f5b5cb86-341d-3276-cbf5-ea9d4b3ac4e8.png)

eksctlとkubectlをPCにインストールする。いずれもHomebrewを使うと便利。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/eksctl.html

https://kubernetes.io/ja/docs/tasks/tools/install-kubectl/


### EKSクラスターの作成

MacのターミナルからEKSクラスター作成コマンドを実行する。

```bash
$ eksctl create cluster --name お好きなクラスター名
```

20分ほど待つとクラスター作成完了。試しにノード一覧を取得してみる。

```bash
$ kubectl get node
NAME                                                STATUS   ROLES    AGE   VERSION
ip-192-168-26-107.ap-northeast-1.compute.internal   Ready    <none>   13m   v1.22.6-eks-7d68063
ip-192-168-73-174.ap-northeast-1.compute.internal   Ready    <none>   13m   v1.22.6-eks-7d68063
```


### Istioのインストール

ここからは公式ページのGetting Startedを活用。

https://istio.io/latest/docs/setup/getting-started/

Istio最新版をダウンロードする（今回はバージョン1.14.1）。

```bash
$ curl -L https://istio.io/downloadIstio | sh -
```

ダウンロードしたIstioディレクトリーへ移動。

```bash
$ cd istio-1.14.1
```

MacにIstio用の環境変数を追加。

```bash
$ export PATH=$PWD/bin:$PATH
```

istioctlをインストールする。

```bash
$ istioctl install --set profile=demo -y
```

Istioのバージョンを確認しておく。

```bash
$ istioctl version
client version: 1.14.1
control plane version: 1.14.1
data plane version: 1.14.1 (2 proxies)
```

EKSクラスターへIstio用のネームスペース設定を有効化する。

```bash
$ kubectl label namespace default istio-injection=enabled
namespace/default labeled
```


### サンプルアプリをEKS上にデプロイする

自分のEKSクラスター上へIstioテスト用のサンプルアプリ「boolinfo」をデプロイ。

```bash
$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
```

デプロイされたサービスを確認。

```bash
$ kubectl get services

NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
details       ClusterIP   10.100.124.27    <none>        9080/TCP   4m14s
kubernetes    ClusterIP   10.100.0.1       <none>        443/TCP    49m
productpage   ClusterIP   10.100.251.75    <none>        9080/TCP   4m13s
ratings       ClusterIP   10.100.54.25     <none>        9080/TCP   4m14s
reviews       ClusterIP   10.100.249.201   <none>        9080/TCP   4m13s
```

少し待ってから、Podが起動しているか確認。

```bash
$ kubectl get pods

NAME                              READY   STATUS    RESTARTS   AGE
details-v1-7d88846999-j97r2       2/2     Running   0          98s
productpage-v1-7795568889-vzg9j   2/2     Running   0          98s
ratings-v1-754f9c4975-btfk9       2/2     Running   0          98s
reviews-v1-55b668fc65-rg2ft       2/2     Running   0          98s
reviews-v2-858f99c99-dkmmk        2/2     Running   0          98s
reviews-v3-7886dd86b9-m9xqh       2/2     Running   0          98s
```

デプロイした「ratings」アプリのPodで動作確認コマンドを実行。
HTMLページのタイトルセクションが返却されればOK。

```bash
$ kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
```


### サンプルアプリを外部からアクセス可能にする

EKSクラスターにIngress Gatewayをデプロイする。

```bash
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
```

サービスメッシュ上の問題がないか確認。

```bash
$ istioctl analyze
✔ No validation issues found when analyzing namespace: default.
```

Ingress GatewayサービスのExternal IPを確認。
eksctlのデフォルト指定で作成したEKSクラスターの場合は、ELBのパブリックDNS名がそのままIngress Gatewayとして利用可能であることが分かる。

```bash
$ kubectl get svc istio-ingressgateway -n istio-system
NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP                                                                    PORT(S)                                                                      AGE
istio-ingressgateway   LoadBalancer   10.100.8.158   ********.ap-northeast-1.elb.amazonaws.com   15021:32244/TCP,80:31172/TCP,443:32028/TCP,31400:32681/TCP,15443:30730/TCP   29m
```

Ingressの環境変数を設定。

```bash
$ export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
$ export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].port}')
$ export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
```

外部公開用ホスト＆ポートの組み合わせが正しく設定されたか確認。

```bash
$ echo "$GATEWAY_URL"
********.ap-northeast-1.elb.amazonaws.com:80
```

実際に外部アクセスを試してみる。

```bash
$ open http://$GATEWAY_URL/productpage
```

Webブラウザーでbookinfoアプリへ無事にアクセス完了！
![スクリーンショット 2022-06-12 0.04.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/70778b1c-4d95-b381-d798-78a842dff0a2.png)


### ダッシュボードでサービスメッシュを可視化してみる

KialiやGrafanaなどの監視系アドオンツールをデプロイする。

```bash
$ kubectl apply -f samples/addons
```

以下のコマンドを実施し、Kialiが無事にデプロイされるまで待機。

```bash
$ kubectl rollout status deployment/kiali -n istio-systemWaiting for deployment "kiali" rollout to finish: 0 of 1 updated replicas are available...
deployment "kiali" successfully rolled out
```

そしてKialiを起動してみる。

```bash
$ istioctl dashboard kiali
```

WebブラウザーでKialiへ無事にアクセス成功！
![スクリーンショット 2022-06-12 0.05.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/8ea3d51c-eac6-839c-99f0-cff168f4e72b.png)

左カラムのメニューよりGraphを開き、Namespaceの指定を「Select all」にするとサービスメッシュが可視化される。
![スクリーンショット 2022-06-12 0.12.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/20ff3eee-9ad4-bcc0-304b-cbea373c4deb.png)

※グラフがパッとしないときは、bookinfoアプリを適当に操作したりリロードしてみよう。右上のサインインボタンより、ID/パスワードとも「admin」でログイン操作も可能。


# Grafana＆Jaegerハンズオン

実はKialiのインストール時にまとめてデプロイした `samples/addons` 内にはクラウドネイティブ界の有名な監視ツールが同梱されている。

- Prometheus
- Grafana
- Jaeger
- Zipkin

すでにKialiと一緒にデプロイまで済んでいるので、試しに起動してみる。


### Grafanaを触ってみる

まずは監視ダッシュボードOSSであるGrafanaを起動。

```zsh
$ istioctl dashboard grafana
```

左ペインの Dashboard > Browse より、istio用の標準ダッシュボードにアクセス可能。
試しに「Istio Control Plane Dashboard」を開いてみる。
![スクリーンショット 2022-06-12 14.27.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/306ce6f9-8214-5669-fb33-7b52aefa665f.png)


### Jaegerも触ってみる

お次は分散トレーシング用OSSであるJaegerを起動してみる。
まずはトレーシングを有効化する。

```zsh
istioctl install --set meshConfig.enableTracing=true
This will install the Istio 1.14.1 default profile with ["Istio core" "Istiod" "Ingress gateways"] components into the cluster. Proceed? (y/N) y
```

Jaegarを起動。

```zsh
$ istioctl dashboard jaeger
```

左ペインにて適当なサービスを指定し、トレースの検索を実行。
![スクリーンショット 2022-06-12 14.37.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/792477ac-bd35-2347-d74a-6f86353a0972.png)

右ペインのグラフ内より、適当なトレース（●印）をクリックすると、トレース内容が確認できる。
![スクリーンショット 2022-06-12 14.38.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/bffd2553-e920-1fbe-b2a8-0092b98ff5e3.png)


# おわりに

この次はIstio公式のGetting Startedにある「Next steps」に挑戦してみたい。
監視系OSSも他にPrometheus、Zipkinなどが含まれているので気になる人は触ってみよう。

これで一旦ハンズオン終了する場合、お掃除は以下。

- EKSクラスターの削除

```zsh
$ eksctl delete cluster --name 自分のクラスター名
```

- 環境変数のクリア

```zsh
$ unset INGRESS_HOST
$ unset INGRESS_PORT
$ unset SECURE_INGRESS_PORT
$ unset GATEWAY_URL
```