サービスメッシュが解決しようとしている課題
庄司です。
この記事では、サービスメッシュがどのような課題を解決しようとしているかについて概説します。
アプリケーションは、時間の経過とともに大きく複雑になっていきます。モノリスで始めたアプリケーションもやがて単一のチームでは手に負えなくなります。
やがて分割する時期を迎えます。アプリケーションを分割したそれぞれの部分 (パート) を SOA 時代以降では「サービス」と呼びます。
アプリケーションコードは、ドメインであるアプリケーションの関心事を実装したコードと認証認可や可観測性などの横断的関心事を含むインフラストラクチャーの関心事を実装したコードから構成されています。
ここで、あるサービスを6のサービスに分割した場合を考えてみます。
ドメインの実装コードは、それぞれが分割されて6個に分割されていることがわかります。しかし、インフラストラクチャーの関心事のコードはそれぞれのサービスに同程度の量のまま分散されます。この部分は、通信プロトコルのハンドリングや認証、認可、可観測性などが主要なコードであるためです。さらにサービス間の依存関係があれば、依存するサービスにアクセスするためのコードも追加されることになります。
分割は、モノリスなアプリケーションでは困難だった、それぞれのドメインに適した言語やフレームワークを利用することや、GPU のような特別なリソースを必要とするサービスとそれ以外とを分離するということもできます。しかし、多言語化する場合には、それぞれの言語別にインフラストラクチャーの関心事のコードがさらに必要になります。
ここで、サービスの実装に利用する言語やフレームワークを標準化していると仮定しましょう。
今、アプリケーションは数百のサービスで構成されています。ある日、利用しているフレームワークに重大なセキュリティ上の問題のため、速やかに対応バージョンに引き上げることが求められました。
各サービスは通常変更がない限りデプロイされることはありません。そのため、全てのサービスが同一バージョンのフレームワークを利用しているわけではありません。
問題のあるバージョンのフレームワークを利用しているサービスは、80 見つかりました。そのうちメジャーバージョンも含めて対応する必要のあるサービスは 30 あります。これらのサービスではフレームワーク自体に大きな変更があったことも予想されます。そのため、構成ファイルの確認、非推奨になった機能の利用の有無の確認と必要に応じて修正も行い、再ビルドし、十分なテストを実施することが必要になります。
この決して速やかにというわけにはいかない対応をする間、問題のあるサービスの停止を許容できるでしょうか。
ESB
#サービスメッシュと似たものに、SOA の時代に主としてサービス間の通信の課題を解決するため、そして前述のような課題を解決するためにエンタープライズサービスバス (ESB) と呼ばれるソリューションが利用されてきました。
これによってサービス間の複雑な通信に関連した課題を解決することにつながってきました。前述のインフラストラクチャーの関心事のコードをサービスから切り離して、ESB の機能で実現できました。
ESB はハブ型で提供されることが一般的です。この記事では ESB の詳細には踏み込みません。興味のある方は ESB 製品等のドキュメントを参照してください。
サイドカーパターン
#Docker や Kubernetes の登場によりサービスをコンテナとして提供することが可能になりました。docker-compose や Amazon ECS、Kubernetes の Pod ではその中で複数のコンテナイメージの実行が可能で、この中ではセキュアな専用のネットワークを持っています。
これを利用するサイドカーパターンが登場し、ドメインを実装したコンテナとインフラストラクチャーの関心事を実装したコンテナを分割することが可能になりました。
このように分割することで、これまで各サービスに実装していたインフラストラクチャーの関心事のコードを単一の Proxy (Envoy 等) とすることが可能になります。そして、よりドメインの実装に集中できます。
このサイドカーパターンを利用することで、ドメインの実装を言語非依存にできるため、それぞれに適した言語を促進することが可能になります。また、インフラストラクチャーに関連したフレームワークの必要性がほとんどないぐらいに減らすことも可能になります。
サイドカーパターンを単に適用しただけの場合、それぞれのサイドカーの構成はサービスそれぞれで行うのでしょうか。あるサービスが別のサービスに依存している場合に依存関係の変更があるたびにサイドカーの構成を変更してデプロイ作業が必要になるのでしょうか。もしそうだとすると冒頭のフレームワークのアップグレードの場合と同様に迅速な対応ができないという問題を抱えることになります。
サービスメッシュ
#クラウドや Kubernetes、そしてサービスメッシュでは、データプレーンとそれを制御するコントロールプレーンに分離して管理します。サイドカーはデータプレーンになりますが、データプレーンはコントロールプレーンで制御することで、構成の動的な変更を集中的に実行できます。
まとめ
#最近の進化したサービスメッシュについての「The InfoQ eMag - Service Mesh Ultimate Guide 2021」では、サービスメッシュパターンが解決しようとする課題が次のように書かれています。
- サービスディスカバリー、ルーティング、およびアプリケーションレベル (レイヤー7) の非機能通信要件を処理するために、言語固有の通信ライブラリの個々のサービスへのコンパイルを不要にする。
- 外部サービスのネットワークロケーション、セキュリティクレデンシャル、サービス品質ターゲットなど、サービス通信構成の外部化。
- 他のサービスのパッシブおよびアクティブな監視の提供。
- 分散システム全体へのポリシー適用の分散化。
- 可観測性にデフォルトを提供し関連データの収集の標準化。
これらはいずれも、この記事で概説したインフラストラクチャーの関心事の分離を意味しています。この記事で ESB にも触れましたが、サービスメッシュとは違ったアプローチであり、また現代のクラウドネイティブな時代には、データプレーンとコントロールプレーンとに分かれたサービスメッシュのアプローチの方がより柔軟に見えます。