TL

サービスメッシュとサイドカーの内部(mTLS/L7制御)

アプリのコードを一行も変えずに、暗号化・再試行・タイムアウトを全通信へ一括適用したい——それを支えるのがサイドカープロキシです。傍受・mTLS自動化・L7制御の仕組みをデータパスから押さえれば、メッシュの挙動を設計で読み解けます。

応用サービスメッシュEnvoymTLSサイドカーL7制御マイクロサービス最終更新: 2026-06-21
TL;DR要点だけ先に
  • 1.サービスメッシュはデータプレーン(各ポッドに刺さる Envoy サイドカー)とコントロールプレーン(設定を配る istiod 等)に分離する。アプリの通信を iptables/eBPF で透過的に傍受し、プロキシ間でルーティングする。
  • 2.mTLS は両側のサイドカーが互いの証明書を検証する相互認証。SPIFFE ID を埋め込んだ短命証明書をコントロールプレーンが自動発行・ローテーションし、アプリ無改変で平文通信を暗号化・認証する。
  • 3.リトライ・タイムアウト・サーキットブレーカは L7(HTTP/gRPC のステータスやメソッド)を見て初めて判断できる。データプレーンが応答コードやヘッダを解釈し、コントロールプレーンの宣言的ポリシーどおりに制御する。

なぜプロキシをアプリの隣に置くのか

マイクロサービス(/devops/microservices/)が増えると、暗号化・再試行・タイムアウト・トレース伝播・流量制御といった「通信の横断的関心事」を、各サービスの言語・フレームワークごとに実装し続けることになります。Go のサービスと Java のサービスでリトライの実装も挙動も微妙に違う——この不揃いが運用を蝕みます。

サービスメッシュ(/devops/service-mesh/)の発想は単純です。通信の制御をアプリから引き剥がし、各ワークロードの隣に常駐するプロキシ(サイドカー)へ寄せる。アプリは「localhost に普通に喋る」だけでよく、暗号化も再試行もプロキシが肩代わりします。実装言語が何であろうと、ポリシーは一箇所で宣言的に定義され、全通信へ一様に適用される。これが「アプリ非改変で通信を制御する」の正体です。

データプレーンとコントロールプレーンの分離

メッシュは2層に分かれます。この分離が設計の核心です。

実体役割データパス上か
データプレーン各ポッドの Envoy サイドカー実トラフィックの傍受・転送・暗号化・L7制御あり(パケットが必ず通る)
コントロールプレーンistiod 等の中央コンポーネント設定の集約・証明書発行・サイドカーへの配信なし(制御信号のみ)

データプレーン は実際のリクエストが通る経路です。Istio や多くのメッシュが採用する Envoy は、L7 を理解する高機能プロキシで、リスナ・ルート・クラスタ・エンドポイントという構成要素を動的に組み替えられます。コントロールプレーン(Istio なら istiod)は実トラフィックを一切触らず、「どのサービスがどこにいるか」「どんなルーティング・mTLS ポリシーか」を集約し、各 Envoy へ xDS(Discovery Service)API で push します。LDS(リスナ)・RDS(ルート)・CDS(クラスタ)・EDS(エンドポイント)といった一連の gRPC ストリームで、設定がほぼリアルタイムに更新されます。

制御の遅延と障害は別物

コントロールプレーンが落ちても、すでに配られた設定でデータプレーンは通信し続けられます(設定が古いまま固定されるだけ)。制御は「設定を変える」操作であり、パケット転送そのものではない——この独立性が、メッシュを運用上壊れにくくしています。

トラフィック傍受:アプリが気づかないうちに通す

サイドカーが効くには、アプリの送受信パケットを 強制的にプロキシへ迂回させる 必要があります。アプリは自分が localhost へ送ったつもりでも、実際にはサイドカーが横取りしている——この透過傍受が仕組みの土台です。

古典的な実装は iptables です。ポッド起動時に init コンテナが NAT ルールを仕込み、アウトバウンドのパケットを Envoy のポート(例 15001)へ、インバウンドを別ポート(例 15006)へ REDIRECT します。

アプリ → (送信) → iptables NAT → Envoy:15001 → mTLS暗号化 → 相手ポッド
相手ポッド → Envoy:15006 → mTLS復号 → iptables → (受信) → アプリ

アプリのソケット先は変わらないのにカーネルが宛先を書き換えるため、コード改変は不要です。ただし iptables 方式は全パケットがユーザ空間の Envoy を往復するオーバーヘッドを持ちます。近年は eBPF(/devops/ebpf-observability/)でソケット層に傍受を仕込み、同一ノード内ではカーネル内で直結して Envoy 往復を省く方式(Cilium のメッシュや Istio の ambient mode 等)が登場しています。いずれも狙いは同じで、アプリに見えない場所で経路を曲げる ことです。

mTLS:相互認証を自動化する

通常の TLS はクライアントがサーバを検証する片方向認証です。mTLS(相互 TLS) は両側が互いの証明書を提示・検証し、接続の両端が「誰であるか」を暗号的に保証 します。ゼロトラストの基礎であり、平文の内部通信を暗号化しつつ「呼び出し元が本当にそのサービスか」を確かめられます。

問題は証明書の運用です。サービスインスタンスは絶えず増減し、IP も入れ替わる。これを人手で配るのは不可能で、ここをコントロールプレーンが自動化します。

  • ID 体系(SPIFFE): 各ワークロードに spiffe://<trust-domain>/ns/<namespace>/sa/<service-account> 形式の SPIFFE ID を与え、これを証明書の SAN(Subject Alternative Name)に埋め込みます。識別子が IP ではなく サービスの論理アイデンティティ に紐づくのが要点です。
  • 短命証明書の自動発行: サイドカー(Istio の istio-agent)が CSR をコントロールプレーンの CA へ送り、署名済みのワークロード証明書を受け取ります。有効期間は数時間〜24時間程度と 意図的に短く、漏洩時の被害窓を絞ります。
  • 無停止ローテーション: 期限が近づくと自動で再発行・差し替え。鍵はメモリ上に保持しディスクに書かないのが一般的で、アプリは証明書の存在すら意識しません。
「mTLS有効」は権限を意味しない

mTLS が保証するのは 相手の身元(authentication) までです。「サービス A が B を呼んでよいか」という 認可(authorization) は別レイヤで、SPIFFE ID を主体とした認可ポリシー(Istio の AuthorizationPolicy 等)で明示的に定義する必要があります。暗号化されていても、ポリシー未設定なら誰でも呼べてしまいます。

L7 制御:ステータスを読むから判断できる

リトライ・タイムアウト・サーキットブレーカは、本質的に L7(アプリケーション層)の情報を解釈して初めて成立 します。TCP/IP の L3/L4 では「接続が張れたか」しか分かりませんが、Envoy は HTTP/gRPC を終端し、ステータスコード・ヘッダ・メソッドまで読めるため、内容に応じた制御が可能になります。

リトライを例にとると、データプレーンは応答コードを見て再送可否を判断します。503 は再送する価値があるが、400(呼び出し側起因)は再送しても無駄、という区別は L7 でしか付きません。具体的な制御点は次のとおりです。

制御判断材料(L7)典型パラメータ注意点
リトライ応答コード・gRPC ステータス再試行回数・条件(5xx, reset 等)・per-try timeout増幅を避けるためバックオフとジッタを併用([/devops/retry-backoff-jitter/](/devops/retry-backoff-jitter/))
タイムアウトリクエスト全体の所要時間route timeout・per-try timeout再試行回数 × per-try が全体 timeout を超えない設計に
サーキットブレーカ連続失敗・未処理リクエスト数最大接続数・保留リクエスト数・outlier detection区画隔離と組む([/devops/circuit-breaker-bulkhead/](/devops/circuit-breaker-bulkhead/))
ルーティングヘッダ・パス・重み重み付き分割・ヘッダ一致カナリアやトラフィック分割([/devops/deployment-strategies/](/devops/deployment-strategies/))に直結

ここで肝心なのは 責務の分離 です。メッシュのリトライはアプリ側のリトライと 二重になりうる——両方が3回ずつ再送すれば最悪9倍の負荷増幅です。どちらか一方に寄せ、もう一方は無効化するのが定石です。タイムアウトも同様で、全体timeout ≧ (per-try timeout × 試行回数) の関係を崩すと、再試行が完了する前に全体が打ち切られて意図と食い違います。

全体 timeout = 1s, per-try = 300ms, retries = 3 の場合
試行1(300ms) → 失敗 → 試行2(300ms) → 失敗 → 試行3(300ms) → ここで約900ms
→ 1s 以内に収まる(設計が整合)
設計レビューの定番論点

「サービスメッシュを入れたから安心」は誤りです。問われるのは——(1) リトライがアプリとメッシュで二重化していないか、(2) タイムアウトの階層(per-try と全体)が整合しているか、(3) mTLS の認証と認可を別物として両方定義したか、(4) 傍受方式(iptables か eBPF か)のオーバーヘッドを把握しているか。そして効果は推測でなく観測で確かめます。サイドカーはトレースのスパン伝播やメトリクス収集の自然な注入点でもあります(/devops/distributed-tracing/)。

サイドカーのコストと「どこで暗号化が解けるか」

サイドカーは万能ではありません。全パケットがプロキシを1〜2ホップ余分に通る ため、レイテンシ(特にテール、/devops/percentile-latency-statistics/)が増え、ポッドごとに Envoy のメモリ・CPU を消費します。ポッド数 N に対してサイドカーも N 個動くため、規模が大きいほど総コストが効いてきます。これが ambient mode のような「ノード共有プロキシ + 必要時のみ L7 プロキシ」へ向かう動機です。

もう一つの落とし穴は 暗号化の境界 です。mTLS が張られるのは Envoy 同士の区間であり、アプリ ↔ サイドカー間(同一ポッド内の localhost)は平文です。同一ポッドのコンテナは信頼境界内なので通常は問題になりませんが、「end-to-end 暗号化」と「サイドカー間暗号化」は別物だと理解しておく必要があります。

まとめ

  • サービスメッシュは データプレーン(Envoy サイドカー)とコントロールプレーン(istiod) を分離し、後者が xDS で設定を配る。制御の障害と転送の障害が独立する。
  • アプリの通信は iptables や eBPF で透過的に傍受 され、コード無改変でプロキシへ迂回する。
  • mTLS は SPIFFE ID 付きの短命証明書をコントロールプレーンが自動発行・ローテーションし、相互認証を実現する。認証と認可は別レイヤ。
  • リトライ・タイムアウト・サーキットブレーカは L7 のステータスを解釈 して初めて成立する。アプリとの二重化やタイムアウト階層の不整合が典型的な事故源。

DevOps/インフラ Article

サービスメッシュとサイドカーの内部(mTLS/L7制御)を実務で読む

TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。

解決すること

サービスメッシュ

比較で見る軸

難易度: advanced / カテゴリ: DevOps/インフラ / タグ数: 6

導入後に効く点

mTLS は両側のサイドカーが互いの証明書を検証する相互認証。SPIFFE ID を埋め込んだ短命証明書をコントロールプレーンが自動発行・ローテーションし、アプリ無改変で平文通信を暗号化・認証する。

先に潰すリスク

用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。

数字・仕様の読み方
難易度
advanced
カテゴリ
DevOps/インフラ
タグ数
6

判断チェックリスト

  • 自社の用途が「サービスメッシュ / Envoy」に近いか確認する。
  • 強みである「サービスメッシュはデータプレーン(各ポッドに刺さる Envoy サイドカー)とコントロールプレーン(設定を配る istiod 等)に分離する。アプリの通信を iptables/eBPF で透過的に傍受し、プロキシ間でルーティングする。」が本当に評価軸になるか確認する。
  • 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
  • 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
  • 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
  • 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。

次に確認する観点

サービスメッシュEnvoymTLSサイドカーL7制御サービスメッシュEnvoymTLS