概要
マイクロサービス化したシステムを運用する上で出てくる課題を解決するパターンとしてService Meshというものがあります。
このService Meshというものは以下の2つのコンポーネントで構成されます。
- Data plane
- アプリケーションの代わりにネットワーク層の仕事をする
- Control plane
- Data planeの管理
このData plane
のproxyはSidecarパターンという形で構築します。
今回はそれが生まれた背景などをEnvoyを用いて説明していこうと思います。
Sidecarパターンは何が嬉しいの?
そもそもどういった問題背景から生まれたのかを考えます。
モノリス
最初はシンプルな機能であったため、モノリシックなAPIで十分でした。
しかし機能が増え、チーム人数も増えたためドメイン毎に機能を分けてマイクロサービス化する事を考えます。
また通信のレイテンシを下げるため、gRPCの導入も考えます。
とりあえず分割したマイクロサービス化
ここでは簡単のため、Alive
とUser
という2つのサービスだけあるとします。
一見サービス毎に分割できてめでたしめでたし、に見えますが、よく考えてみると分割した分、システム的には複雑性が増しています。
例えばAlive
やUser
の中でどうやって負荷分散をすればいいのか、などです。
gRPCを使ったメリットがある一方でL4では分散できない問題が起きます。
負荷分散どうする
簡単のためGateway
からUser Service
のPodsへの通信のみ考えます。
Front Proxy LB
前回
で試した例ですね。シンプルにLBとして用意するので分かりやすいです。
一方でデメリットとして
- LBを経由するのでレイテンシが増える
- LBにコネクションが集中するので、LB自体のスケール性を考慮する必要がある
- gRPCではL4のLBは使えない
といったことがあります。
Client Side LB
LBを経由しない方法として、サービスの呼び出し側(Client
)がバランシングするという考え方があります。
ただこの場合User Service
のPodが増える度に、Gateway
はそのIPを検知して設定を更新する必要がありますし、サービスの種類が増える度にアプリケーション側でコードに修正を入れる必要があるのは保守・運用的に辛いところがあります。
それ以外の課題
最初に述べたようにマイクロサービスでは分割した分、システム的には複雑性が増しています。
パッと考えるだけでも負荷分散以外に
- トレーシング
- メトリクス
- 通信の暗号化
- ACL
- 一部のサービスが落ちた時のCircuit Breaker
- 自動リトライ
などネットワーク層の問題を考慮する必要があります。
これらをすべてアプリ側で対応するのは非常に大変だという事が分かります。
Sidecarパターン
それらのネットワーク層の課題をアプリケーション側で考えるのでなく、別途Proxyを用意してそちらに責務を持たせようとしたのがSidecarパターンです。
この図のように先程のClient Side LBで問題になっていた部分をEnvoyが吸収します。
負荷分散以外ものネットワーク層の問題も、すべてSidecarに任せることでアプリケーションはドメインロジックにのみ集中することが可能になります。
ちなみにEnvoyはどうやってUser Service
のPodのIPを知るかというと、別途Service Discoveryを用意してそこから定期的にチェック・更新することになります。
KubernetesならHeadless serviceを使いますし、AWSのECSならConsulなどを使います。
まとめ
マイクロサービスでのSidecarパターンが生まれた背景と、その構成を図示しました。
次回は実際にKubernetes上で上記のシステムを構築します。