ひとことで言うと#
各マイクロサービスにサイドカープロキシを配置し、サービス間通信の制御(ルーティング、認証、観測)をアプリケーションコードから切り離してインフラ層で一括管理するアーキテクチャ。
押さえておきたい用語#
- サイドカープロキシ
- 各サービスのPodに併設される軽量なプロキシプロセス。すべてのインバウンド・アウトバウンドトラフィックを仲介し、通信制御を実行する。Envoyが代表的。
- データプレーン
- サイドカープロキシの集合体で、実際のトラフィックを処理する層。ルーティング、リトライ、ロードバランシングなどを実行する。
- コントロールプレーン
- データプレーンの設定を一元管理する管理層。Istio、Linkerdが代表的。ポリシーやルーティングルールを宣言的に定義する。
- mTLS(相互TLS認証)
- サービス間通信でクライアントとサーバーの双方が証明書を提示し合う認証方式。通信の暗号化と相互認証を同時に実現する。
- トラフィックシフティング
- 新バージョンへのトラフィックを段階的に切り替える手法。カナリアリリース(5%→20%→100%)などを宣言的に制御できる。
サービスメッシュの全体像#
こんな悩みに効く#
- マイクロサービスが増えるたびに、通信制御のコードを各サービスに個別実装している
- サービス間のmTLS(相互認証)を全サービスに一括適用したいが、手間がかかりすぎる
- どのサービスがどのサービスを呼んでいるか、通信の全体像が把握できない
基本の使い方#
サービスメッシュはデータプレーンとコントロールプレーンの2層で構成される。
- データプレーン: 各サービスに配置されるサイドカープロキシ(Envoyなど)。実際のトラフィックを仲介する
- コントロールプレーン: プロキシの設定を一元管理する管理層(Istio、Linkerdなど)
- アプリケーションはサイドカーを意識せず、従来通り通信するだけ
ポイント: アプリケーションコードの変更なしに、通信制御を後付けできるのが最大の利点。
一度にすべてのサービスに適用せず、段階的に導入する。
- まずは観測(オブザーバビリティ)目的で一部サービスにサイドカーを注入する
- 通信トポロジーの可視化で全体像を把握する
- 問題がなければ、トラフィック制御やセキュリティ機能を順次有効にする
ポイント: 観測 → トラフィック制御 → セキュリティの順に機能を有効化するのがベストプラクティス。
コントロールプレーンからルーティング・リトライ・タイムアウトなどを宣言的に設定する。
- カナリアリリース: 新バージョンにトラフィックの5%だけ振り分ける
- リトライポリシー: 特定のエラーコードに対して自動リトライ
- タイムアウト: サービスごとにタイムアウト値を統一設定
ポイント: これらの設定をYAMLなどの宣言的定義で管理でき、アプリケーションコードを変更せずにポリシーを変更できる。
サービスメッシュのセキュリティ機能と観測機能をフル活用する。
- mTLS: すべてのサービス間通信を自動的に暗号化・相互認証する
- アクセス制御: 「サービスAからサービスBへの通信のみ許可」といったポリシーを設定する
- 分散トレーシング: リクエストの流れをサービスをまたいで追跡する
ポイント: ゼロトラストセキュリティの実現において、サービスメッシュは最も実践的な手段の一つ。
具体例#
状況: マイクロサービスが50を超え、各サービスがリトライ・タイムアウト・ログ出力を個別実装。品質がバラバラで障害時の原因特定に平均2時間。
段階的導入:
- Phase 1(2週間): 全サービスにEnvoyサイドカーを注入。Kialiで通信トポロジーを可視化。未知の依存関係を3件発見
- Phase 2(1週間): リトライ・タイムアウトポリシーをメッシュレベルで統一設定。各サービスの個別実装を削除
- Phase 3(1週間): mTLSを全通信に適用。サービス間のアクセス制御ポリシーを設定
結果: 障害時の原因特定時間が平均2時間→15分に短縮。各サービスから通信制御コードが約200行ずつ削減。セキュリティ監査で「全サービス間通信が暗号化済み」を証明。
状況: 決済サービスのv2.0リリースで、従来はBlue/Greenデプロイを使用。切り替え時に一瞬エラーが発生していた。
Istio VirtualServiceで段階的リリース:
- Day 1: v2.0にトラフィック5%を振り分け。エラーレートとレイテンシを監視
- Day 2: 問題なし → 20%に増加
- Day 3: 問題なし → 50%に増加
- Day 4: 問題なし → 100%に切り替え。v1.0を廃止
緊急時の対応: Day 2の段階でv2.0のp99レイテンシが閾値を超えた場合、YAMLの1行変更で即座にv1.0に全トラフィックを戻す。
結果: 決済サービスのリリースでダウンタイムゼロを達成。以前のBlue/Greenでは平均4秒のエラー期間があった。リリース失敗時のロールバック時間が3分→10秒に。
状況: 30サービスのKubernetesクラスタにIstioを導入。導入前のリソース使用量を基準にインフラ費用を見積もっていた。
問題:
- 各PodにEnvoyサイドカーが追加され、メモリ使用量がPod当たり128MB増加
- 30サービス x 3レプリカ = 90Podで合計11.5GBのメモリ増
- CPU使用量もPod当たり50m増加し、ノード追加が必要に
- 月額インフラコストが**$2,400増加**(約15%増)
対策:
- Envoyのメモリ制限を最適化(128MB→64MB)
- 低トラフィックサービスはサイドカーのCPU requestを下げる
- コントロールプレーンのレプリカ数を調整
結果: 最適化後のコスト増は**$900/月(約6%増)**に抑制。通信制御の統一化で削減できた開発工数(月約80時間)と比較すれば十分にROIが合うと判断。
やりがちな失敗パターン#
- サービス数が少ない段階で導入する — サービスが5〜10個程度なら、サービスメッシュのオーバーヘッドのほうが大きい。サービス数が増えて手動管理の限界を感じてから導入する
- 全機能を一度に有効にする — 観測・トラフィック制御・セキュリティをすべて同時に設定すると、問題の切り分けが困難になる。段階的に機能を追加する
- サイドカーのリソース消費を見積もらない — 各Podにサイドカーが追加されるため、CPU・メモリの消費が増える。リソースの追加コストを事前に見積もる
- コントロールプレーンの可用性を軽視する — Istioのコントロールプレーンがダウンすると設定変更ができなくなる。コントロールプレーンのHA構成と監視を必ず設定する
まとめ#
サービスメッシュは、マイクロサービスの通信課題をインフラ層で一括解決するアーキテクチャ。通信制御・セキュリティ・観測をアプリケーションコードから分離することで、開発者はビジネスロジックに集中できる。ただし導入・運用コストは小さくないため、規模と課題が見合うタイミングで段階的に導入することが成功の鍵。