サービスメッシュ Istioとは?

## はじめに

Kubernetesを利用する時にサービスメッシュを検討することがあるかと思います。

本記事ではサービスメッシュとは何か?
また、サービスメッシュの機能を持つIstioについて説明していきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628777/cd385dbb-fb8d-b428-4989-e36f8bcea941.png)


## サービスメッシュとは

サービスメッシュとはマイクロサービスの各サービス間通信を専用のソフトウェアに仲介させることで、マイクロサービス特有の課題を解決する仕組みです。

サービス間通信の運用の課題として以下の項目が挙げられます。

- 通信の回復性
- 負荷分散
- 分散トレース
- サービスバージョン管理
- サービス間トラフィック暗号化

サービスメッシュはこれらの課題に対する有効な対処方法の一つです。

また、上記の項目は各アプリケーションの個別に実装することもできますが、大きなコストがかかってしまいます。

マイクロサービスアーキテクチャではマイクロサービスごとに使用するプログラミング言語やデータベースが異なるケースも多くあり、各ネットワーク機能は別のソフトウェアレイヤーで行いたいという要望もサービスメッシュは解決します。
### 図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628777/a4379550-36f4-979b-5f08-b4f18d9d2da7.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628777/8eb2e01c-2958-1c89-c4da-d7fe6b2a8aa2.png)

## サービスメッシュが提供するネットワークサービス

サービスメッシュはサービス間通信するソフトウェアにおいて、アプリケーションに代わってネットワーク要求を送信するサービスですが、代表的な機能として以下となっています。

- トラフィック制御
- 回復性、耐障害性処理
- セキュリティ、アクセス制御
- 状態の可視化(可観測性)、分散トレース

### トラフィック制御

- 各サービスに流れるトラフィックを細かく制御できます。
  - 例えば、あるサービスの応答の遅延が他の多数のサービスにまで影響を及ぼすことがあります。
  - サービスメッシュによって応答しないサービスへのアクセスを遮断すること(サーキットブレイカー)で、応答遅延の波及を阻止できます。
  - また、リクエストの10%を新しいバージョンに割り振るといったこと(カナリアリリース)も可能になり、柔軟なデプロイを取ることができます。

### 回復性、耐障害性管理

- サービスメッシュを使うとコードに変更を加えることなくアプリケーションに耐障害性機能を追加することができます。
  - 回復機能、耐障害性機能にはタイムアウト、タイムアウトを伴うリトライ、サーキットブレーカー、ヘルスチェック、フォールトインジェクションなどがあります。



### セキュリティ

- 各サービス間で行われる通信の暗号化やアクセスの認証・認可機能を提供します。
  - 例えば、Kubernetesの内部では基本的に自由に通信できるため、脆弱性の悪用等であるPodが乗っ取られてしまうと、その影響がクラスター全体に波及してしまう可能性があります。
  - サービスメッシュの機能である相互TLS(mTLS)を利用するすることで盗聴や中間者攻撃(MITM)を抑止できます。
  - また認証・認可機能により予め通信できるサービスを制限しておくことで、開発環境から本番環境へのアクセスを防止したり、脆弱性の影響を局所化したりできます。
  - また、サービスメッシュを使うとアプリケーションへの変更を最小に抑えながら複数のプロトコルとランタイムに対してポリシーを一貫して使用することができます。

  



### オブザーバビリティ（可観測性)

- 各サービス間で行われる通信のメトリクスを容易に取得できます。
  - マイクロサービスでは1リクエストを処理するのにも複数のサービスが連携して対応するため、問題発生時にチェックすべき箇所がコンテナ基盤や各サービスのログ等多岐に渡り、リクエストがどのように処理されているかの全体像を把握するのが難しくなります。
  - サービスメッシュの分散トレーシング機能を活用すると、マイクロサービスで応答遅延や障害などが発生した際もボトルネックの特定が容易となり、迅速に対応できます。



## Istioについて

Istioは、マイクロサービスで動くアプリケーションに透過的に機能するOSSのサービスメッシュです。　
Istioを使うことでサービスのセキュリティ、トラフィック監視、回復性などを効率的に行うことができます。
上記のサービスメッシュの説明で述べたアプリケーションのコードを変更することなくロードバランシングやサービス間の認証、モニタリングを実現することができます。



Istioは大規模なエコシステムによって様々なシナリオ、用途で活用されています。Istio自体はオープンソースなので直接インストールすることもできますが、多くのクラウドベンダーがIstioを統合して管理する製品を提供しています。



## Istioのアーキテクチャ

Istioは、データプレーンとコントロールプレーンという2つのコンポーネントに分割されます。

- データプレーンはEnvoyプロキシサーバを用いてマイクロサービス間の全てのネットワーク通信を仲介および制御します。また、全てのトラフィックのテレメトリを収集して報告します。
- コントロールプレーンはトラフィックをルーティングするプロキシの設定を行います。

![Istioベースのアプリケーションの全体的なアーキテクチャ。](https://istio.io/latest/docs/ops/deployment/architecture/arch.svg)



## Envoyプロキシ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628777/dade1355-1552-888d-9f13-9880887bdfdf.png)

IstioはEnvoyプロキシの拡張バージョンを使用します。Envoyとは、C++で開発された高性能プロキシであり、サービスメッシュの全てのサービスのインバウンドトラフィックとアウトバウンドトラフィックを仲介します。Envoyプロキシはデータプレーントラフィックと通信を行う唯一のIstioコンポーネントです。



Envoyプロキシはサービスのサイドカーとして展開され、Envoyの多くの組み込み機能によりサービスの支えの強化を行います。
以下、例です。

- 動的なサービス検出
- 負荷分散
- TLS Termination
- HTTP/2 gRPCプロキシのサポート
- サーキットブレイカー
- ヘルスチェック
- フォールトインジェクション
- 高機能なメトリクス

サイドカーデザインを展開することで,Istioはメッシュ全体の動作に関する情報を抽出することができたり、アプリケーションのコードを再設計することなく既存のサービスにIstioを追加することができます。

### Envoyのアーキテクチャ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628777/446e984b-4ff3-ffc9-b0ce-36d24134f8a8.png)


EnvoyとNginx、HAproxyの違いは以下の記事に論述されています。
[Envoy vs NGINX vs HAProxy](https://blog.getambassador.io)

## Istiod

Istiodは、サービスディスカバリ、構成、証明書管理機能を提供します。

Istiodはトラフィックの動作を制御する高レベルのルーティングルールをEnvoy固有の構成に変換し、実行時にサイドカーに伝搬します。Pilotは、プラットフォーム固有のサービス検出メカニズムを抽象化し、EnvoyAPIに準拠するサイドカーが使用できる標準形式にそれらを合成し ます。

Istioは、KubernetesやVMなどの複数の環境の検出をサポートできます。

IstioのTrafficManagement APIを使用して、IstiodにEnvoy構成を改良し、サービスメッシュ内のトラフィックをよりきめ細かく制御するように指示できます。

Istiodセキュリティは、組み込みのIDおよび資格情報管理により、強力なサービス間およびエンドユーザー認証を可能にします。Istioを使用して、サービスメッシュ内の暗号化されていないトラフィックをアップグレードできます。Istioを使用すると、オペレーターは、比較的不安定なレイヤー3またはレイヤー4のネットワーク識別子ではなく、サービスIDに基づいてポリシーを適用できます。さらに、Istioの認証機能 を使用して、サービスにアクセスできるユーザーを制御できます。

Istiodは認証局（CA）として機能し、データプレーンでの安全なmTLS通信を可能にする証明書を生成します。

## Kialiによる要求トラフィックの可視化
IstioにはKialiというユーザーインターフェースの可視化サービスがあります。
IstioのIngress gatewayからPodに入ってくるトラフィックを視覚化することができるので、Ingreesだけで運用するよりもサービスの情報がより詳細に理解することができます。

##### 実際のKialiのGUI
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628777/b631a463-a9fb-1721-e65b-cc1ce5eaa6e6.png)

IstioではSREが用いるアプリ運用品質で重要なGolden Signalのうち、上記のKialiで３つを視覚化することができます。

https://sre.google/sre-book/monitoring-distributed-systems/


#### Golden Signal
 1. レイテンシ
 2. トラフィック
 3. エラー
 4. サチュレーション(こちらはGrafanaで見ることが多い)


## 外部通信IngressGateway, EgressGatewayについて
外部トラフィックをクラスタ内に取り入れる方法としてClusterIPからNodePort,LoadBalancer,IngressGatewayがありますが、それらの違いについては英語ですが、以下のブログ記事がとても参考になります。

https://medium.com/@zhaohuabing/which-one-is-the-right-choice-for-the-ingress-gateway-of-your-service-mesh-21a280d4a29c
#### 外部通信のわかりやすい図
(もちろんIstioで通信を制御できます)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628777/86fae30f-0c9c-368f-f18c-efc0049e922d.png)


 
 
## さいごに

サービスメッシュ、Istioの説明しましたが、必ずしもサービスメッシュを導入すればいいというわけではありません。
サービスメッシュを誤った形で使うとサービスがより複雑になったり無駄なオーバーヘッドが生じてしまいます。望まない高機能なアーキテクチャができて金額のコストも人材のコストも寄りかかってしまうこともあるかと思います。

それぞれの条件によって適切な方法がありますし、各アプリケーション毎にソースコードを書いた方が良い場合もあります。

例えば、マイクロサービスアーキテクチャを構築しているがほぼ同一言語で構築している場合は各ライブラリの統一が可能になるので利点が少なくなります。
しかし急にRustを導入したい、Python使って機械学習したいというPolyglot(多言語)のような状況となった時にサービスメッシュが生きてきたりもします。

それぞれの状況を鑑みて適切な技術を使っていくのがベストです。

## 参考文献
https://istio.io/

https://cloud.google.com/learn/what-is-istio?hl=ja