サービスメッシュ
Service Mesh ・ さーびすめっしゅ
サービス間通信の制御・保護・観測を、アプリの外のプロキシ層に切り出して一元的に設定する基盤。
✦ 30秒で試す — 航海アプリのコードを1行も変えずに、全通信を暗号化できる司令塔が止まっている間、サービス同士の通信は?予想してみる概要
サービスメッシュは、マイクロサービス同士の通信の制御・保護・観測を、アプリケーションのコードから切り離して専用のインフラ層に任せる仕組みです。「メッシュ(網)」の名のとおり、サービスが増えるほど網の目のように張り巡らされる通信経路すべてを、一枚の層としてまとめて面倒をみます。代表的な実装に Istio、Linkerd、Cilium Service Mesh などがあります。
仕組みの中核はサイドカーパターンです。各サービスの隣に軽量なプロキシを並走させ、サービスの送受信をすべてそこに通します。アプリからは相変わらず「隣のサービスを呼んでいるだけ」に見えますが、実際の通信はリトライ・タイムアウト・暗号化・計測を施されたうえで届きます。そして、その振る舞いのすべてを、中央の1箇所に書いた設定で一斉に変えられる。アプリのコードを一切変えずに、通信の品質と方針を底上げできるのがサービスメッシュの本質です。
なぜ生まれたか
モノリスでは関数呼び出しだった処理の連携が、マイクロサービスではネットワーク越しの呼び出しになります。ネットワークは失敗するものなので、各サービスにはリトライ、タイムアウト、サーキットブレーカー、mTLS による相互の認証、分散トレーシングのためのヘッダの受け渡し……と、本来のビジネスロジックとは無関係な「通信の作法」を大量に実装する必要が生まれました。
これを共通ライブラリで配ろうとすると、Netflix の Hystrix や Ribbon がそうだったように、言語ごとの作り直しと全サービス一斉アップデートという泥沼にはまります。Go のサービスには Java のライブラリは使えず、リトライの方針を1つ変えるだけで数十チームの再デプロイが必要になる。この苦しみへの回答が「通信の作法をアプリの外に出し、プロキシに任せ、方針は中央で配る」というサービスメッシュでした。2016年に Buoyant 社が Linkerd を公開してこの言葉を広め、2017年に Google・IBM・Lyft が Lyft 製のプロキシ Envoy を土台にした Istio を発表して一気に普及しました。
詳細
二層構造 — データプレーンとコントロールプレーン
サービスメッシュは2つの層でできています。データプレーンは各 Pod(Kubernetes でコンテナをまとめる単位)に同居するサイドカーのプロキシの集合で、実際のリクエストはすべてここを流れます。プロキシには Envoy が広く使われていますが、Linkerd は Rust で書いた専用の軽量プロキシ(linkerd2-proxy)を使うなど、すべてが Envoy というわけではありません。コントロールプレーン(Istio では istiod)は、管理者が書いた設定 —「このサービスへのリクエストは3回までリトライ」「v2 へ10%だけ流す」など — を解釈し、各プロキシが理解できる形に変換して配る司令塔です。Istio では xDS という gRPC のストリームで、変更があるたびに全プロキシへ押し出します。
リクエスト自体はコントロールプレーンを通らないため、司令塔が一時的に落ちても通信は流れ続けます。止まるのは「設定の変更が届くこと」と「証明書の更新」です。証明書には有効期限があるので、コントロールプレーンが長く止まったままだと、いずれ新しい通信の相互認証ができなくなります。
下の部品で、この分業を確かめてください。上の設定(リトライ・v2 への比率・mTLS)を書き換えると、設定の版が上がって金の粒が各サイドカーへ届き、届いたサイドカーから順に通信の流れ方が変わります。コントロールプレーンの箱を押して止めると、通信は止まらないのに、設定の変更だけが届かなくなります。
frontend から reviews への通信が流れています。reviews v1 は時々失敗します。上の設定をコントロールプレーンで1回書き換えて、全サイドカーの振る舞いが一斉に変わる様子を見てください。
アプリを変えずに手に入るもの
この構造から得られる機能は4系統に整理できます。第一にトラフィックの制御です。リトライ・タイムアウト・サーキットブレーカーに加え、送り先の重み付けでカナリアリリース(新バージョンへ数 % だけ流して様子を見る)を設定の変更だけで実現できます。リトライを足すときは、再試行が相手をさらに追い詰める「リトライの嵐」に注意し、回数の上限と全体の予算を決めておきます。
第二にセキュリティです。コントロールプレーンが各プロキシに証明書を自動で発行・更新し、サービス間の全通信を mTLS で相互認証・暗号化します。平文も受け付ける移行期間の設定から始めて、全サービスがメッシュに入ったら強制に切り替えるのが定石で、これが「内側のネットワークも信用しない」ゼロトラストの足場になります。第三に可観測性です。全通信がプロキシを通るため、リクエスト数・エラー率・レイテンシといったメトリクスや分散トレーシングのデータが、全サービス分、同じ形で手に入ります(トレースをつなぐヘッダの受け渡しだけは、アプリ側の協力が要ります)。第四に、ヘルスチェックの結果と連動した宛先の選択を、ロードバランサの代わりにプロキシがきめ細かく行います。
代償と、サイドカーレスという流れ
万能に見えますが、代償は小さくありません。全リクエストがプロキシを2回(送信側と受信側)通るためレイテンシが上乗せされ、Pod ごとのプロキシがメモリと CPU を消費します。サイドカーならではの起動・終了の順番の問題も抱えます。そして最大のコストは運用の複雑さです。障害調査では「アプリの問題かメッシュの問題か」という切り分けの層が1つ増え、メッシュ自体のバージョンアップも無停止で行う必要があります。
この重さへの回答として、Pod ごとにプロキシを置かない「サイドカーレス」の方式が広がっています。Istio の ambient mode(2024年の 1.24 で正式版)は、暗号化や L4 の認可をノードごとの軽量なプロキシ(ztunnel)に任せ、L7 の制御(リトライや重み付け)が必要なサービスにだけ、共有のプロキシ(waypoint)を置きます。Cilium Service Mesh は、Linux カーネルの eBPF とノード単位の Envoy で同様の機能を提供します。どちらも「アプリの外で、中央の設定どおりに通信を扱う」という本質は変わらず、プロキシの置き場所が変わっただけです。なお、AWS のマネージドなメッシュだった App Mesh は 2026年9月30日で提供を終え、ECS Service Connect などへの移行が案内されています。
採用の判断は規模に依存します。サービスが数個〜十数個で単一言語なら、APIゲートウェイで入口を整え、内部はリトライのライブラリで済ませるほうが総コストは低いことが多いでしょう。サービスメッシュが真価を発揮するのは、多言語のサービスが数十個以上あり、mTLS の全面適用や揃った可観測性が組織の要件になったときです。
試問
frontend から reviews への通信が流れ、各サービスの隣にいるサイドカー(通信を代わりに運ぶプロキシ)が運んでいます。reviews v1 は時々失敗し、安定した新版 v2 もあります。ボタンで設定(リトライ・v2 への比率・mTLS)を書き換えるとコントロールプレーン(設定を配る司令塔)から各サイドカーへ配られ、コントロールプレーンの箱を押すと止められます。
frontend から reviews への通信が流れています。reviews v1 は時々失敗します。上の設定をコントロールプレーンで1回書き換えて、全サイドカーの振る舞いが一斉に変わる様子を見てください。
