istiodのServiceDiscoveryとEnvoy-Proxyのざっくりとした連携について

# 概要

Istioのコントロールプレーンとしてデプロイされる`istiod`のServiceDiscoveryが`Envoy-Proxy`と
どのように連携しているのかについて、`istiod`側と`Envoy-Proxy`側から私の解釈を記述します。

## 前提

Istioのバージョンは1.6.0です。

# 3つの機能

こちらの[Istio / Archtecture](https://istio.io/latest/docs/ops/deployment/architecture/)でも解説されていますが

- Service Discovery
- Configuration
- Certificate Management

の3つから構成されています。

![スクリーンショット 2020-07-09 7.23.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447425/8fe0d76c-c6f3-9743-339a-faa39362c10c.png)

istiodのDeploymentごと`kubectl delete`して上記3つに関連することを試すといった検証はしたことが無いですが
istiodがお亡くなりになっているとIstioリソースを新しく適用しようとしても`Envoy-Proxy`へ伝達されません。
そもそも`kubectl apply`しようにもIstioのAPIが応答しないのでconfig伝達の前にValidationの時点で怒られます。

まだ初学者レベルの私が感じたところとしては、`Istio`が認識するyamlファイルが事故ってないかを確認し、
事故ってなければEnvoyで認識できる形式に変換し、EnvoyのAPIを利用して各Envoy-Proxyに送り込んでいるいった動きに見えます。

## 図（ズ

![スクリーンショット 2020-07-09 7.18.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447425/a7367edf-ff6f-6a79-8135-b0dc2fac5c0a.png)

istiodがDiscoveryとConfigurationとCertificatesをそれぞれの`Envoy-Proxy`にやっていますよ〜といった
ざっくりとした図ですね。

Istio1.6.0でコントロールプレーンがモノリスになったおかげで、以前のバージョンでPodとして存在してたPilot,Citadel,Galleyが削除され、`istiod`の中に包括されるようになっています。

- PilotはServiceDiscovery相当の動きを担当
- CitadelはCertificate Management相当の動きを担当
- GalleyはConfiguration相当の動きを担当

していたそうです。

管理が楽になったので喜ぶべきなのでしょうか。

# Service DiscoveryはEnvoy APIを添えるだけ

調べてみたのですが、`istiod`というより`Envoy-Proxy`の機能をメインに使っているようです。
`istiod`を`kubectl logs`して見えるログから`RDS`,`CDS`,`LDS`,`EDS`といったワードが見えると思いますが
この部分が`istiod`から各Podに同居している`Envoy-Proxy`のAPIを叩きまくっている部分です。

# Service Discoveryをもう少し掘っていくと

![スクリーンショット 2020-07-09 7.18.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447425/5256f8d3-6f64-970f-1a88-8e85b64a4812.png)

代表的な物として４つが挙げられるかなと思いました。他にもいくつかあるようですが、ここでは割愛します。ごめんね。

## `Route Discovery Service`(RDS)
 
ざっくりいうとServiceへのルーティング情報を`Envoy-Proxy`に叩き込むAPI。
`VirtualService`の設定情報が反映されているかを確認する場合は、
`istioctl proxy-config routes [podname].[namespace] -o json`で詳細まで確認できます。

## `Listener Discovery Service`(LDS)

通信を待ち受けるリスナー情報を`Envoy-Proxy`に叩き込むAPI。
あまり仲良くした記憶が無いので解説できないのですが、この情報を確認する場合は、
`istioctl proxy-config listener [podname].[namespace] -o json`で詳細まで確認できます。

## `Cluster Discovery Service`(CDS)

Serviceの名前解決に必要な情報(
- [podname]
- [podname].[namespace]
- [podname].[namespace].svc
- [podname].[namespace].svc.cluster.local
)
や、そのServiceへトラフィックを流す時に適用されるルール(DestinationRule)を`Envoy-Proxy`に叩き込むAPI。
`istioctl proxy-config cluster [podname].[namespace] -o json`で詳細まで確認できます。

「`DestinationRule`が意図したように効いてないぞ！！？」という事態に陥った時に上記のコマンドで中を覗いてみてください。
どのNamespaceのDestinationRuleがどのホスト名(FQDN)に対して有効になっているか確認できます。

## `Endpoint Discovery Service`(EDS)

CDSではFQDNやホスト名に紐づく設定が確認できましたが、
`EDS`ではIPアドレスとポート番号といったエンドポイントとしての情報を`Envoy-Proxy`に叩き込むAPI。
`istioctl proxy-config endpoint [podname].[namespace] -o json`で詳細まで確認できます。が、
endpointの場合は`-o json`を付けない方が見やすかったりします。適宜変更してみてください。

他にも、エンドポイントのSTATUS(Healthy/UnHealthy)やOutelier Checkの結果を`Envoy-Proxy`間で共有します。
よく説明に出てくるサーキットブレーカーの発動に必要な情報と推測しています。

# おわりに

ここまで`istiod`と`Envoy-Proxy`間の`Service Discovery`について解説しましたが、
まだまだカバーしきれていないと思っています。
Envoy自体が高機能なプロキシであり、Istio自体がまだEnvoyの全ての機能を操りきれていないため
IstioからEnvoy-Proxyのポテンシャルを全て引き出せていないと思います。

これからのIstioのアップデートに期待ということで、終わります。
読んでくれた方々の参考になれば嬉しいです。