Istio, Envoy, Kiali, Prometheus,  Jaeger on Mercari microservice example


[前回](https://qiita.com/kozayupapa/items/daf37d937fd914f36655)　MercariのMicroservice exampleのMakefileを読み進めて構成を把握しました。
そのなかでIstio, Kiali という監視に役立つものがテンプレートのなかに埋め込まれているという点に注目しました。
今回は Istio, Kialiを中心に動作確認していきたいと思います。

ローカルで動かして自由にいじくりまわすということが、新しい技術を理解する早道だと思います。
そのために　mercariさんのexampleでサンプルMicroservice, 運用監視のためのIstio両方とも手軽にInstallできてしまうというのはなんともありがたいです！

## 事前準備
* Localにgo, DockerをInstallしておく
* Docker の使用するメモリー8GB以上に設定する(たりないとpodがpendingのままになります)
* 下記のRepositoryをClone
  - https://github.com/mercari/mercari-microservices-example
* CloneしたRepository内で、`make install` 実行
  - マシン、Networkスペックによるが 15分くらいで構築完了

## Istio-injection
そもそもIstioとはなんでしょうか？

https://istio.io/latest/

 **Simplify observability, traffic management, security, and policy with the leading service mesh.**
上記のように定義されています。サービスメッシュの、可視化、通信制御、セキュリティを簡単に実現するためのものということですね。

アーキテクチャは下記のようになっています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/76af2198-68ca-bf5e-2460-02b5de8d6b7e.png)


Control planeが　各サービスを制御する。各サービスのアプリケーション実装内にIstioに依存した部分を埋め込まないでよいように、Serviceの横にEnvoy Proxyを組み込む（SideCar）。ServiceとServiceは直接通信するのではなくEnvoyProxyが仲介するようにする。EnvoyProxyが可視化、通信制御、セキュリティを考慮して制御する。IstioControlPlaneが各EnvoyProxyに制御内容の指示を出す、結果のmetrixを収集するという役割をもっているということです。

mercary microservice exampleのなかで、かきのように各サービスのdeployment.ymlのなかで定義があります。驚くべきことにこの`istio-injection: enabled`一行をいれるだけでServiceの横にSideCar（App Containerのよこにもう一個SubのContainerをたてること）としてenvoy proxyを構築するということが実現できてしまいます。まさにSimplify!!　こういうことが実現しやすいということがk8s の本当の強みですね。

```yaml:services/authority/deployment.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: authority
  labels:
    istio-injection: enabled
```

* Istio自体のInstallはMakefileの下記の部分で行われています

```Makefile:Makefile
istioctl: $(ISTIOCTL)
$(ISTIOCTL):
ifeq ($(OS)-$(ARCH), darwin-amd64)
	curl -sSL "https://storage.googleapis.com/istio-release/releases/$(ISTIO_VERSION)/istioctl-$(ISTIO_VERSION)-osx.tar.gz" | tar -C $(BIN_DIR) -xzv istioctl
else ifeq ($(OS)-$(ARCH), darwin-arm64)
	curl -sSL "https://storage.googleapis.com/istio-release/releases/$(ISTIO_VERSION)/istioctl-$(ISTIO_VERSION)-osx-arm64.tar.gz" | tar -C $(BIN_DIR) -xzv istioctl
else
	curl -sSL "https://storage.googleapis.com/istio-release/releases/$(ISTIO_VERSION)/istioctl-$(ISTIO_VERSION)-$(OS)-$(ARCH).tar.gz" | tar -C $(BIN_DIR) -xzv istioctl
endif

...

.PHONY: cluster
cluster: $(KIND) $(KUBECTL) $(ISTIOCTL)
	$(KIND_CMD) delete cluster
	$(KIND_CMD) create cluster --image kindest/node:v${KUBERNETES_VERSION} --config ./kind.yaml
	./script/istioctl install --set meshConfig.defaultConfig.tracing.zipkin.address=jaeger.jaeger.svc.cluster.local:9411 -y
```



## Open Kiali

上記でInstallできていると頭ではわかっているのですが、目に見えないと納得できません。
幸いKiali というIstio可視化のための仕組みもセットでMakefileにしたがってすでにInstallされています（いたれりつくせりなexample）。

とりあえず下記のコマンドをうつことでLocalでkiali web serverにアクセスできます。

```shell
 % ./script/istioctl dashboard kiali     
```

![スクリーンショット 2021-11-22 10.27.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/d21fe8ed-815a-f7ca-ce7c-9d12c30adfc3.png)


一応k8s のサービス一覧とかは出てくるのですが　ちょっと物足りません。
サービスメッシュ間の呼び出しグラフとかみえることを期待したのですがなにもでてきません。
prometheus がみつからないという　worningがたくさんでます。
ためしに `% ./script/kubectl get po --all-namespaces` を実行してみるとたしかにpromethuesのpodはありません。どうやらprometheusのインストールがたりていないようです。

```shell
%./script/kubectl get po --all-namespaces 
NAMESPACE            NAME                                                                  READY   STATUS      RESTARTS   AGE
authority            app-56c5c858ff-6hqvv                                                  2/2     Running     0          8d
authority            app-56c5c858ff-zwtk8                                                  2/2     Running     0          8d
catalog              app-6699d57d45-ctf5h                                                  2/2     Running     0          8d
catalog              app-6699d57d45-sgvls                                                  2/2     Running     0          8d
customer             app-7d569ff46-j8zsp                                                   2/2     Running     0          8d
customer             app-7d569ff46-z4nf8                                                   2/2     Running     0          8d
db                   app-796c69d656-sxnkh                                                  1/1     Running     0          7d
gateway              app-689b8fbfbb-7wnbm                                                  2/2     Running     0          8d
gateway              app-689b8fbfbb-kjwkm                                                  2/2     Running     0          8d
ingress-nginx        ingress-nginx-admission-create-hs6ff                                  0/1     Completed   0          8d
ingress-nginx        ingress-nginx-admission-patch-m7zsv                                   0/1     Completed   2          8d
ingress-nginx        ingress-nginx-controller-5cf8cb98c5-vzrp2                             1/1     Running     4          8d
istio-system         istio-ingressgateway-85fbdd86f7-vfgfw                                 1/1     Running     1          8d
istio-system         istiod-75d5bf4676-b5qtq                                               1/1     Running     1          8d
istio-system         kiali-84db5dd45-hdhns                                                 1/1     Running     8          8d
item                 app-67f95964df-2bdqb                                                  2/2     Running     0          8d
item                 app-67f95964df-2xnkl                                                  2/2     Running     0          8d
jaeger               jaeger-78f8cd7f6-2zz6p                                                1/1     Running     1          8d
kube-system          coredns-558bd4d5db-926b9                                              1/1     Running     1          8d
kube-system          coredns-558bd4d5db-hzf5s                                              1/1     Running     1          8d
kube-system          etcd-mercari-microservices-example-control-plane                      1/1     Running     1          8d
kube-system          kindnet-qgjb7                                                         1/1     Running     1          8d
kube-system          kube-apiserver-mercari-microservices-example-control-plane            1/1     Running     1          8d
kube-system          kube-controller-manager-mercari-microservices-example-control-plane   1/1     Running     31         8d
kube-system          kube-proxy-wf8z4                                                      1/1     Running     1          8d
kube-system          kube-scheduler-mercari-microservices-example-control-plane            1/1     Running     35         8d
local-path-storage   local-path-provisioner-85494db59d-mmftw                               1/1     Running     29         8d
```


いや、でもそもそもpromethesと、kialiの関係はどういう関係なんでしょうか？
以下にわかりやすい説明があります。
* https://kiali.io/docs/architecture/architecture/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/046d2804-74e5-54d8-411f-f8d7ae737cba.png)


このなかでPrometheusとの関連について下記のように説明があります

**Prometheus is an Istio dependency. When Istio telemetry is enabled, metrics data is stored in Prometheus. Kiali uses the data stored in Prometheus to figure out the mesh topology, show metrics, calculate health, show possible problems, etc.
Kiali communicates directly with Prometheus and assumes the metrics used by Istio Telemetery. It’s a hard dependency for Kiali, and many Kiali features will not work without it.**

サービス感の呼び出し関係や、サービスの状態の解釈等についてPrometheusに強く依存しているんですね。
そりゃ入れないとだめそうですね。



## Install Prometheus

ではprometheus をinstallしていきましょう
まず現在のpodの状態です。　prometheusないですね。



以下 istioのドキュメントにそって prometheus をインストールします。

https://istio.io/latest/docs/ops/integrations/prometheus/#configuration

* install prometheus

```shell
./script/kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.12/samples/addons/prometheus.yaml
```

上記yamlで必要なservice, pod, servicAccountが作成されます。ただしIstioが定義したとりあえず手早く動かすという設定なので商用に適用する時はパフォーマンス、コスト、セキュリティ観点で見直しましょう。

実行後service, podの状態を確認すると下記のように istio-system name space に prometheusがインストールされています。


``` shell
%./script/kubectl get svc --all-namespaces
NAMESPACE       NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
...
istio-system    istio-ingressgateway                 LoadBalancer   10.96.155.129   <pending>     15021:31817/TCP,80:30665/TCP,443:31943/TCP   8d
istio-system    istiod                               ClusterIP      10.96.167.195   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP        8d
istio-system    kiali                                ClusterIP      10.96.107.175   <none>        20001/TCP,9090/TCP                           8d
istio-system    prometheus                           ClusterIP      10.96.40.238    <none>        9090/TCP                                     29s
item            item                                 ClusterIP      10.96.40.178    <none>        5000/TCP                                     8d
jaeger          jaeger                               ClusterIP      10.96.187.119   <none>        9411/TCP,14268/TCP,16686/TCP                 8d

%./script/kubectl get po --all-namespaces
NAMESPACE            NAME                                                                  READY   STATUS              RESTARTS   AGE
...
istio-system         istio-ingressgateway-85fbdd86f7-vfgfw                                 1/1     Running             1          8d
istio-system         istiod-75d5bf4676-b5qtq                                               1/1     Running             1          8d
istio-system         kiali-84db5dd45-hdhns                                                 1/1     Running             8          8d
istio-system         prometheus-64fd8ccd65-b7jhs                                           0/2     ContainerCreating   0          23s
item                 app-67f95964df-2bdqb                                                  2/2     Running             0          8d
item                 app-67f95964df-2xnkl                                                  2/2     Running             0          8d
jaeger               jaeger-78f8cd7f6-2zz6p                                                1/1     Running             1          8d

```

### TLS error 発生
さあ、これで見られるようになるはずと　mercari exampleのAPIを呼び出そうとすると、

```shell
%curl -s -XGET -H "authorization: bearer $TOKEN" localhost:30000/catalog/items | jq .   
{
  "code": 16,
  "message": "unauthenticated"
}
```

時間が経過しているので4xx のエラーがかえってきます。
kiali でみると下記のように通信箇所が赤く表示されています。
おー、ここまでは期待通り。

![スクリーンショット 2021-11-22 10.35.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/486d1180-6863-c2b6-d7e8-ba64f6d33e67.png)


ならば再度SignInしようとしたところ下記のようTLSのエラーがかえってきてしまいました。。
` TLS error: 268435581:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED`

```shell
(base) mercari-microservices-example % curl -s -XPOST -d '{"name":"gopher"}' localhost:30000/auth/signup                               
{"code":14, "message":"upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: TLS error: 268435581:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED"}                                                                                                                                                   
(base) mercari-microservices-example % curl -s -XPOST -d '{"name":"gopher"}' localhost:30000/auth/signin 
{"code":14, "message":"upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: TLS error: 268435581:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED"}
```

理由がわからなく、ググってみたところどうも以下のように
ServiceAccountを追加したばあいにenvoyに正しく伝搬しないという問題がistio 1.14 以下ではあるようです。

https://github.com/istio/istio/issues/26324

このサンプルではistio 1.11 をつかっているので まさにこの問題にはまっているようです。
回避策としてserviceを作成しなおすとよいとかかれているので試してみます。
ingress-nginx, gateway, authority  をいったんdelete, pod, svcともいなくなったのをかくにんしてから再度applyします。

```shell
(base) mercari-microservices-example%./script/kubectl delete --filename ./platform/ingress-nginx/ingress-nginx.yaml 
(base) mercari-microservices-example % ./script/kubectl delete --filename services/gateway/deployment.yaml 
(base) mercari-microservices-example % ./script/kubectl delete --filename services/authority/deployment.yaml 

# ここまでで削除されたいることを確認
(base) mercari-microservices-example % ./script/kubectl get svc --all-namespaces                            
NAMESPACE      NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
catalog        catalog                ClusterIP      10.96.78.87     <none>        5000/TCP                                     8d
customer       customer               ClusterIP      10.96.74.128    <none>        5000/TCP                                     8d
db             db                     ClusterIP      10.96.62.197    <none>        5000/TCP                                     8d
default        kubernetes             ClusterIP      10.96.0.1       <none>        443/TCP                                      8d
istio-system   istio-ingressgateway   LoadBalancer   10.96.155.129   <pending>     15021:31817/TCP,80:30665/TCP,443:31943/TCP   8d
istio-system   istiod                 ClusterIP      10.96.167.195   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP        8d
istio-system   kiali                  ClusterIP      10.96.107.175   <none>        20001/TCP,9090/TCP                           8d
istio-system   prometheus             ClusterIP      10.96.40.238    <none>        9090/TCP                                     63m
item           item                   ClusterIP      10.96.40.178    <none>        5000/TCP                                     8d
jaeger         jaeger                 ClusterIP      10.96.187.119   <none>        9411/TCP,14268/TCP,16686/TCP                 8d
kube-system    kube-dns               ClusterIP      10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP                       8d
```

applyを実行して再度起動させます。

```shell
(base) mercari-microservices-example % ./script/kubectl apply --filename ./services/gateway/deployment.yaml 
(base) mercari-microservices-example % ./script/kubectl apply --filename ./services/authority/deployment.yaml 
(base) mercari-microservices-example%./script/kubectl apply --filename ./platform/ingress-nginx/ingress-nginx.yaml 
(base) mercari-microservices-example % ./script/kubectl get po --all-namespaces                              
NAMESPACE            NAME                                                                  READY   STATUS      RESTARTS   AGE
authority            app-56c5c858ff-9zjpg                                                  2/2     Running     0          18s
authority            app-56c5c858ff-dc94j                                                  2/2     Running     0          18s
catalog              app-6699d57d45-ctf5h                                                  2/2     Running     0          8d
catalog              app-6699d57d45-sgvls                                                  2/2     Running     0          8d
customer             app-7d569ff46-j8zsp                                                   2/2     Running     0          8d
customer             app-7d569ff46-z4nf8                                                   2/2     Running     0          8d
db                   app-796c69d656-sxnkh                                                  1/1     Running     0          7d2h
gateway              app-689b8fbfbb-2s6xz                                                  2/2     Running     0          26s
gateway              app-689b8fbfbb-h6s22                                                  2/2     Running     0          26s
ingress-nginx        ingress-nginx-admission-create-wqj5v                                  0/1     Completed   0          2m13s
ingress-nginx        ingress-nginx-admission-patch-6wrz7                                   0/1     Completed   1          2m13s
ingress-nginx        ingress-nginx-controller-5cf8cb98c5-xkfv4                             1/1     Running     0          2m14s
istio-system         istio-ingressgateway-85fbdd86f7-vfgfw                                 1/1     Running     1          8d
istio-system         istiod-75d5bf4676-b5qtq                                               1/1     Running     1          8d
istio-system         kiali-84db5dd45-hdhns                                                 1/1     Running     8          8d
istio-system         prometheus-64fd8ccd65-b7jhs                                           2/2     Running     0          77m
item                 app-67f95964df-2bdqb                                                  2/2     Running     0          8d
item                 app-67f95964df-2xnkl                                                  2/2     Running     0          8d
jaeger               jaeger-78f8cd7f6-2zz6p                                                1/1     Running     1          8d
kube-system          coredns-558bd4d5db-926b9                                              1/1     Running     1          8d
kube-system          coredns-558bd4d5db-hzf5s                                              1/1     Running     1          8d
kube-system          etcd-mercari-microservices-example-control-plane                      1/1     Running     1          8d
kube-system          kindnet-qgjb7                                                         1/1     Running     1          8d
kube-system          kube-apiserver-mercari-microservices-example-control-plane            1/1     Running     1          8d
kube-system          kube-controller-manager-mercari-microservices-example-control-plane   1/1     Running     32         8d
kube-system          kube-proxy-wf8z4                                                      1/1     Running     1          8d
kube-system          kube-scheduler-mercari-microservices-example-control-plane            1/1     Running     36         8d
local-path-storage   local-path-provisioner-85494db59d-mmftw                               1/1     Running     30         8d

(base) mercari-microservices-example % ./script/kubectl get svc --all-namespaces
NAMESPACE       NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
authority       authority                            ClusterIP      10.96.26.178    <none>        5000/TCP                                     40s
catalog         catalog                              ClusterIP      10.96.78.87     <none>        5000/TCP                                     8d
customer        customer                             ClusterIP      10.96.74.128    <none>        5000/TCP                                     8d
db              db                                   ClusterIP      10.96.62.197    <none>        5000/TCP                                     8d
default         kubernetes                           ClusterIP      10.96.0.1       <none>        443/TCP                                      8d
gateway         gateway                              ClusterIP      10.96.90.110    <none>        4000/TCP,5000/TCP                            48s
ingress-nginx   ingress-nginx-controller             NodePort       10.96.2.1       <none>        80:32075/TCP,443:30155/TCP                   2m36s
ingress-nginx   ingress-nginx-controller-admission   ClusterIP      10.96.147.194   <none>        443/TCP                                      2m36s
istio-system    istio-ingressgateway                 LoadBalancer   10.96.155.129   <pending>     15021:31817/TCP,80:30665/TCP,443:31943/TCP   8d
istio-system    istiod                               ClusterIP      10.96.167.195   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP        8d
istio-system    kiali                                ClusterIP      10.96.107.175   <none>        20001/TCP,9090/TCP                           8d
istio-system    prometheus                           ClusterIP      10.96.40.238    <none>        9090/TCP                                     77m
item            item                                 ClusterIP      10.96.40.178    <none>        5000/TCP                                     8d
jaeger          jaeger                               ClusterIP      10.96.187.119   <none>        9411/TCP,14268/TCP,16686/TCP                 8d
kube-system     kube-dns                             ClusterIP      10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP                       8d
```


さて、これで再度signupから実行しようとすると、、、
またまた、別の種類のエラーがでてしまいました。。

```shell
(base) mercari-microservices-example % curl -s -XPOST -d '{"name":"gopher"}' localhost:30000/auth/signup | jq .
{
  "code": 13,
  "message": "internal error"
}
```

こんなときこそ kialiで、デバッグしたい、、
と考えてkiali　dashboardをopenしてみます。
![スクリーンショット 2021-11-23 9.05.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/ddd6cfc3-6a1c-b808-8b7b-305e313ef16a.png)
authority, customerが赤くなっていてエラーがでているのが分かります。

![スクリーンショット 2021-11-23 9.19.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/1fe2a84a-8289-a0e6-3dfc-f0f6bbd14108.png)

authority-> application を開きます

![スクリーンショット 2021-11-23 9.20.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/3254055f-8f5a-9f13-6430-aa48c2cf4e65.png)
worlkloads-> app を選択

![スクリーンショット 2021-11-23 9.20.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/460ad006-6aa9-822d-5618-bfc6bb5a42bc.png)
log tab を選択
![スクリーンショット 2021-11-23 9.21.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/4788f555-fa00-a031-2406-2b46c15e9917.png)

おー、デバッグしやすい。　ログが　app, istio 両方みえるんですね。
ログをみるとやっぱり以下がでています

```
: connection failure, transport failure reason: TLS error: 268435581:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED"}
```

ちなみに、podが２つあるので切り替えないとlogがでていないと勘違いしてしまうかもしれないのでご注意ください。
![スクリーンショット 2021-11-23 9.28.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/d4929889-005e-7b6b-238d-7152eee31b29.png)


そして　customer のほうもエラーがでているので参照してみると、、
![スクリーンショット 2021-11-23 9.25.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/947c9f4a-7d3d-0b60-7c19-6b35e001f0ac.png)

こちらのほうはappのログはでずに、　istioのほうでエラーが出ています。
つまり TLSerror はistioのレイヤーで制御されているということがわかりました。

```text
2021-11-23T00:12:31.558107Z	warning	envoy config	StreamAggregatedResources gRPC config stream closed: 14, closing transport due to: connection error: desc = "error reading from server: EOF",eceived prior goaway: code: NO_ERROR, debug data
```


これは　わかってきました。さきほど認証系なのでgateway, authbridgeだけ再起動させたのですが、他のマイクロサービスcustomerや、他のmicroserviceもリスタートがひつようなんですね。よくよく考えてみると　各pod に envoyがsidecarとして配信済みなので、TLS設定が上書きされてしまったら全istio 管理化のpodを再生成が必要というのは納得です。また、pod内のはなしなのでserviceは削除の必要ないですね。
pod だけということで　app をdeleteしてから再度applyします。

```shell
(base) mercari-microservices-example % ./script/kubectl delete deploy -n catalog --ignore-not-found app
deployment.apps "app" deleted
(base) mercari-microservices-example % ./script/kubectl delete deploy -n customer --ignore-not-found app
deployment.apps "app" deleted
(base) mercari-microservices-example % ./script/kubectl delete deploy -n db --ignore-not-found app
deployment.apps "app" deleted
(base) mercari-microservices-example % ./script/kubectl delete deploy -n item --ignore-not-found app
deployment.apps "app" deleted

# 一度podが削除されたことを確認
(base) mercari-microservices-example % ./script/kubectl get po --all-namespaces                         
NAMESPACE            NAME                                                                  READY   STATUS        RESTARTS   AGE
authority            app-56c5c858ff-9zjpg                                                  2/2     Running       0          23h
authority            app-56c5c858ff-dc94j                                                  2/2     Running       0          23h
gateway              app-689b8fbfbb-2s6xz                                                  2/2     Running       0          23h
gateway              app-689b8fbfbb-h6s22                                                  2/2     Running       0          23h
ingress-nginx        ingress-nginx-admission-create-wqj5v                                  0/1     Completed     0          23h
ingress-nginx        ingress-nginx-admission-patch-6wrz7                                   0/1     Completed     1          23h
ingress-nginx        ingress-nginx-controller-5cf8cb98c5-xkfv4                             1/1     Running       1          23h
...
# 再度apply
(base) mercari-microservices-example % ./script/kubectl apply --filename ./services/customer/deployment.yaml                                         
namespace/customer unchanged
deployment.apps/app created
service/customer unchanged
(base) mercari-microservices-example % ./script/kubectl apply --filename ./services/catalog/deployment.yaml 
namespace/catalog unchanged
deployment.apps/app created
service/catalog unchanged
(base) mercari-microservices-example % ./script/kubectl apply --filename ./services/item/deployment.yaml   
namespace/item unchanged
deployment.apps/app created
service/item unchanged
(base) mercari-microservices-example % ./script/kubectl apply --filename ./platform/db/deployment.yaml  
namespace/db unchanged
deployment.apps/app created
service/db unchanged
```

無事Signup, Signinも通るようになりました！


```shell
(base) mercari-microservices-example % curl -s -XPOST -d '{"name":"gopher"}' localhost:30000/auth/signup | jq .
{
  "customer": {
    "id": "1c27eebd-f260-46f6-bb6c-031e7c6a56f9",
    "name": "gopher"
  }
}
(base) mercari-microservices-example % curl -s -XPOST -d '{"name":"gopher"}' localhost:30000/auth/signin | jq .access_token -r

eyJhbGciOiJSUzI1NiIsImtpZCI6ImFhN2M2Mjg3LWM0NWQtNDk2Ni04NGI0LWExNjMzZTRlM2E2NCIsInR5cCI6IkpXVCJ9...
```

そのときの呼び出しGraphです
![スクリーンショット 2021-11-23 11.39.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/ce5db6e1-c859-79ff-6c14-7c5bd1cfeb3d.png)


System All Green!! 気持ちいい。
![スクリーンショット 2021-11-23 11.38.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/85a3a2f4-83f1-48fc-cca6-3fa4aece7cc6.png)

service だけのGraphにするとスッキリ依存関係がみやすい。
![スクリーンショット 2021-11-23 11.42.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/195a9ee4-e5d4-f23a-ea9d-aae28ed7aa5d.png)

その他Metrixもとれているようです。
![スクリーンショット 2021-11-23 11.46.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/10fcbf86-fd5f-c9c6-7bde-132f3c75f82d.png)



## Jaeger , Envoy
これで istio, kiali, prometheus については原理と、動作がわかってきました。
あとはJaegerの理解です。ぱっと下記のサイトのJaegerの説明を読むと分散トレーシング、
パフォーマンス最適化となっていて　istio, envoyとの差分がよくわかりません。
アーキテクチャをみても、Istio, Envoyと似ているなと思いが募ります。

https://www.jaegertracing.io/docs/1.28/architecture/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/aca29808-97e7-a076-a2fd-d0e2eb880c2c.png)


下記の処理概要をみるとjaegerがTraceIDというのを追加して計測しているのは分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/9acb846b-6279-f69e-0fb1-1839eec17ea8.png)

### open tracing
Jaeger理解のために必要となる知識は　OpenTracingという概念です。
* https://www.slideshare.net/td-nttcom/open-tracingjaeger

<iframe src="//www.slideshare.net/slideshow/embed_code/key/g5OEQjI18X0BNw" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/td-nttcom/open-tracingjaeger" title="分散トレーシング技術について（Open tracingやjaeger）" target="_blank">分散トレーシング技術について（Open tracingやjaeger）</a> </strong> from <strong><a href="https://www.slideshare.net/td-nttcom" target="_blank">NTT Communications Technology Development</a></strong> </div>

### JaegerとEnvoyの関係

マイクロサービス間のTraceを共通化するためにOpenTracing仕様が生まれました。
そして　その仕様に準拠した　Zipkin（made by Google）というtraceのためのLibraryがありました。
IstioのSidecarであるEnvoyはZipkinをサポートしています。
Zipkinをさらに使いやすくしたJaeger(made by Uber)を開発しました。
Envoyの出力をJaegerがうけとって詳細な分散Tracingがおこなえます！


だから　Makefileにて、IstioCtl　installするときにjaegerのendpointを指定していたんですね！

```Makefile
.PHONY: cluster
cluster: $(KIND) $(KUBECTL) $(ISTIOCTL)
	$(KIND_CMD) delete cluster
	$(KIND_CMD) create cluster --image kindest/node:v${KUBERNETES_VERSION} --config ./kind.yaml
	./script/istioctl install --set meshConfig.defaultConfig.tracing.zipkin.address=jaeger.jaeger.svc.cluster.local:9411 -y

```

Istioの中にとりこまれているので、意識しなくても使えてしまうEnvoyですが、
Envoy自体も独立したOSSです。一言でいうならLayer7 proxyです。

* https://www.envoyproxy.io/docs/envoy/latest/intro/what_is_envoy
    - ***Envoy is L7 proxy and communication bus***

Envoyの仕組みでTraceできるデータにはいかのようなものがあります

* Originating service cluster set via --service-cluster.
* Start time and duration of the request.
* Originating host set via --service-node.
* Downstream cluster set via the x-envoy-downstream-service-cluster header.
* HTTP request URL, method, protocol and user-agent.
* Additional custom tags set via custom_tags.
* Upstream cluster name, observability name, and address.
* HTTP response status code.
* GRPC response status and message (if available).
* An error tag when HTTP status is 5xx or GRPC status is not “OK”.
* Tracing system-specific metadata.

envoyを以下のようにSideCarでつかうのはIstioの流儀であり、Envoy自体はもっと多様な使い方をサポートしているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/693bbcfc-a7ae-d930-347b-5484f55c6eeb.png)



スッキリしたところでJaegerのUIを開いてみます。

```shell
 # name space が違うので起動できない
`% ./script/istioctl dashboard jaeger  
 Error: no Jaeger pods found
 # -n で指定すると起動できる
 % ./script/istioctl dashboard jaeger -n jaeger
 http://localhost:16686
```

しかし、JaegerのDashboardを開いても関連するサービスのDashboardはでてきてくれません
![スクリーンショット 2021-11-23 13.17.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/6a9d40d9-62e4-6c69-f44f-9088306c9cb2.png)


kialiでひらいてもtracesは存在しないとなってしまいます。
![スクリーンショット 2021-11-23 13.17.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/b14bac00-3388-e26b-9fda-a957432236aa.png)


### Jaeger sampling rate
ちなみにJaegerはすべてのリクエスをTraceしているわけではなく、Samplingしています。
デフォルトでは1/100のリクエストをTraceしています。
なので、Trace結果を見たい場合は、いかのように最低100回以上はリクエストを送ってから確認する必要があります。

```shell
% for i in $(seq 1 200); do curl -s -XGET -H "authorization: bearer $TOKEN" localhost:30000/catalog/items ; done
```

sampling rateを変更するには下記で説明されているconfigを変更することもできます。

* https://istio.io/latest/docs/tasks/observability/distributed-tracing/jaeger/#before-you-begin

***When you enable tracing, you can set the sampling rate that Istio uses for tracing. Use the meshConfig.defaultConfig.tracing.sampling option during installation to set the sampling rate. The default sampling rate is***



### Jaeger istio-system namespaceへ再インストール
mercari microservice example では jaeger は pod, svc のみのシンプルな構成になっています。
いっぽうでIstioのサンプルを参照するとsvc がたくさんInstallされています。

https://istio.io/latest/docs/ops/integrations/jaeger/

* https://raw.githubusercontent.com/istio/istio/release-1.12/samples/addons/jaeger.yaml

確証はないですが　serviceがたりていないのでJaegerのTracingがうまく動いていない可能性があります。
下記のように上記Istio推奨のJaegerをフルセットでistio-system name spaceにインストールしてみます。


```shell
(base) mercari-microservices-example % kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.12/samples/addons/jaeger.yaml
deployment.apps/jaeger created
service/tracing created
service/zipkin created
service/jaeger-collector created
(base) mercari-microservices-example % ./script/kubectl get svc --all-namespaces                      
NAMESPACE       NAME                                 TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
authority       authority                            ClusterIP      10.96.26.178    <none>        5000/TCP                                     31h
catalog         catalog                              ClusterIP      10.96.78.87     <none>        5000/TCP                                     9d
customer        customer                             ClusterIP      10.96.74.128    <none>        5000/TCP                                     9d
db              db                                   ClusterIP      10.96.62.197    <none>        5000/TCP                                     9d
default         kubernetes                           ClusterIP      10.96.0.1       <none>        443/TCP                                      9d
gateway         gateway                              ClusterIP      10.96.90.110    <none>        4000/TCP,5000/TCP                            31h
ingress-nginx   ingress-nginx-controller             NodePort       10.96.2.1       <none>        80:32075/TCP,443:30155/TCP                   31h
ingress-nginx   ingress-nginx-controller-admission   ClusterIP      10.96.147.194   <none>        443/TCP                                      31h
istio-system    istio-ingressgateway                 LoadBalancer   10.96.155.129   <pending>     15021:31817/TCP,80:30665/TCP,443:31943/TCP   9d
istio-system    istiod                               ClusterIP      10.96.167.195   <none>        15010/TCP,15012/TCP,443/TCP,15014/TCP        9d
istio-system    jaeger-collector                     ClusterIP      10.96.252.28    <none>        14268/TCP,14250/TCP,9411/TCP                 9s
istio-system    kiali                                ClusterIP      10.96.107.175   <none>        20001/TCP,9090/TCP                           9d
istio-system    prometheus                           ClusterIP      10.96.40.238    <none>        9090/TCP                                     32h
istio-system    tracing                              ClusterIP      10.96.114.137   <none>        80/TCP,16685/TCP                             9s
istio-system    zipkin                               ClusterIP      10.96.130.165   <none>        9411/TCP                                     9s
```

そして、istioctl install を再実行して　jaeger のendpoint(（上記jager.yamlではzipkin)を設定しなおしてみます。
`zipkin.istio-system.svc.cluster.local:9411 ` service名.namespace.cluster名:port番号　

```shell
(base) mercari-microservices-example % ./script/istioctl install --set meshConfig.defaultConfig.tracing.zipkin.address=zipkin.istio-system.svc.cluster.local:9411 -y 
✔ Istio core installed                                                                                                                                                       
✔ Istiod installed                                                                                                                                                           
✔ Ingress gateways installed                                                                                                                                                 
✔ Installation complete                                                                                                                                                      
Thank you for installing Istio 1.11.  Please take a few minutes to tell us about your install/upgrade experience!  https://forms.gle/kWULBRjUv7hHci7T6
```

このあと全Podをdelete, applyしなおしました。(手間がかかるりますし、総入れ替えになるのでistio, envoyの設定は商用期間中はなるべく変えたくないと思いました。)
そして、、　ついに　Jaegerの詳細な呼び出し履歴がUIで確認できるようになりました！

```shell
% ./script/istioctl dashboard jaeger  
```
jaeger ui をつかったものでも
![スクリーンショット 2021-11-23 19.46.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/fdacc8b8-710e-fd13-38c8-9cd8ecb93c18.png)


```shell
 % ./script/istioctl dashboard kiali  
 ```
Kiali ui を経由したものどちらでもデータとれることを確認しました！
![スクリーンショット 2021-11-23 19.44.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/a0661269-5a19-2e55-8b3d-9708c7ae357d.png)



### Istion (Envoy) config check
Istioの、ProxyConfigの内容を出力するコマンド実行例です。

下記をみると、どのEndpoint設定が有効になっているか大体わかります。ただ、ものによって同じポートが２重に設定されているようにもみえます。設定があるかないかは調べられるが、どの設定が実際に有効に動作しているのかは、正確に把握するにはもう少し深く調査する必要がありますが、参考までに記載しておきます。

```shell
(base) mercari-microservices-example % ./script/istioctl proxy-config route app-7d569ff46-nns4h.customer | grep jaeger
9411                                                          jaeger-collector.istio-system, 10.96.252.28           /*                     
9411                                                          jaeger.jaeger, 10.96.187.119                          /*                     
jaeger.jaeger.svc.cluster.local:14268                         jaeger.jaeger, 10.96.187.119                          /*                     
jaeger.jaeger.svc.cluster.local:9411                          jaeger.jaeger, 10.96.187.119                          /*                     
jaeger-collector.istio-system.svc.cluster.local:14250         jaeger-collector.istio-system, 10.96.252.28           /*                     
jaeger-collector.istio-system.svc.cluster.local:14268         jaeger-collector.istio-system, 10.96.252.28           /*                     
jaeger.jaeger.svc.cluster.local:16686                         jaeger.jaeger, 10.96.187.119                          /*    
(base) mercari-microservices-example % ./script/istioctl proxy-config cluster app-7d569ff46-nns4h.customer | grep zipkin
zipkin                                                                 -         -          -             STRICT_DNS       
zipkin.istio-system.svc.cluster.local                                  9411      -          outbound      EDS              
(base) mercari-microservices-example % ./script/istioctl proxy-config endpoint app-7d569ff46-nns4h.customer | grep zipkin
10.244.0.42:9411                 HEALTHY     OK                outbound|9411||zipkin.istio-system.svc.cluster.local
10.96.130.165:9411               HEALTHY     OK                zipkin

(base) mercari-microservices-example % ./script/istioctl proxy-config route app-7d569ff46-nns4h.customer | grep zipkin
9411                                                          zipkin.istio-system, 10.96.130.165                    /*                     
(base) mercari-microservices-example % ./script/istioctl proxy-config route app-7d569ff46-nns4h.customer | grep jaeger
9411                                                          jaeger-collector.istio-system, 10.96.252.28           /*                     
9411                                                          jaeger.jaeger, 10.96.187.119                          /*                     
jaeger.jaeger.svc.cluster.local:14268                         jaeger.jaeger, 10.96.187.119                          /*                     
jaeger.jaeger.svc.cluster.local:9411                          jaeger.jaeger, 10.96.187.119                          /*                     
jaeger-collector.istio-system.svc.cluster.local:14250         jaeger-collector.istio-system, 10.96.252.28           /*                     
jaeger-collector.istio-system.svc.cluster.local:14268         jaeger-collector.istio-system, 10.96.252.28           /*                     
jaeger.jaeger.svc.cluster.local:16686                         jaeger.jaeger, 10.96.187.119                          /*     

(base) mercari-microservices-example % ./script/istioctl proxy-config bootstrap app-7d569ff46-nns4h.customer | grep zipkin
                                            "zipkin": {
                                                        "address": "zipkin.istio-system.svc.cluster.local:9411"
                    "name": "envoy.tracers.zipkin",
                    "name": "envoy.zipkin",
                    "name": "zipkin",
                        "clusterName": "zipkin",
                                                    "address": "zipkin.istio-system.svc.cluster.local",
                "name": "envoy.tracers.zipkin",
                    "collectorCluster": "zipkin",
```

## まとめ
Istio, Envoy, Kiali, Prometheus, Jaegerの役割分担、くみあわせかたが動かしながら理解することができました。
これらを共通の仕組みとして導入することは、マイクロサービスをまたがる開発、デバッグが高速にまわすための必須となるということが体感できました。
開発、結合時のDebug, 商用サービスのモニタリング　両面でどのように導入していくかを考えていきたいと思います。!

そして　System AllGreen!　といいつづけたいです。　
（あと、NetworkGraphってなんだかみてるだけでワクワクしてきます）
![スクリーンショット 2021-11-23 11.38.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41631/9d9c0585-9661-7ba0-6f0f-c46fd1df0140.png)