Skip to content
Published on

Istio Ambient Mesh内部構造:サイドカーのないサービスメッシュ

Authors

はじめに

Istio Ambient Meshは、サイドカープロキシなしでサービスメッシュ機能を提供する新しいデータプレーンモードです。従来のサイドカー方式の根本的な限界を解決するために設計されました。

この記事では、Ambient Meshの内部アーキテクチャ、コアコンポーネント、サイドカー方式との違いを深く分析します。

サイドカー方式の限界

リソースオーバーヘッド

従来のサイドカーモード:
┌─────────────────────────────────┐
Pod│  ┌───────────┐ ┌─────────────┐ │
│  │    App    │ │ istio-proxy │ │  ← Pod当たり約100MB RAM0.1 CPU
│  │           │   (Envoy)    │ │
│  └───────────┘ └─────────────┘ │
└─────────────────────────────────┘

100個のPod = 約10GB追加メモリ

起動遅延

サイドカー注入はPod起動時間に影響を与えます:

  • istio-initコンテナがiptablesルールを設定(1-2秒)
  • istio-proxyがistiodから構成受信を待機(2-5秒)
  • 全体の起動時間に3-7秒追加

アップグレードの複雑さ

サイドカーアップグレード時はすべてのPodを再起動する必要があります:

  • ローリングアップデートでPodを1つずつ再作成
  • 大規模クラスターでは数時間かかる
  • アプリケーションの可用性に影響

Ambient Meshアーキテクチャ

┌─────────────────────────────────────────────────────────┐
Control Plane│                      istiod                              │
└─────────────────────┬───────────────────────────────────┘
                      │ xDS
          ┌───────────┼───────────┐
          ▼           ▼           ▼
┌─────────────┐ ┌──────────┐ ┌──────────┐
│   ztunnel   │ │ ztunnel  │ │ waypoint │
  (Node 1) (Node 2) │ │  proxy   │
DaemonSet  │ │ DaemonSet│ (per-ns)└──────┬──────┘ └────┬─────┘ └────┬─────┘
       │              │            │
  ┌────┴────┐   ┌────┴────┐      │
Pod A   │   │ Pod B   │      │
  (no scar)(no scar)│      │
  └─────────┘   └─────────┘      │
       │              │            │
       └──── HBONE tunnel ────────┘

ztunnel:ノードレベルL4プロキシ

概要

ztunnel(Zero Trust Tunnel)は各ノードにDaemonSetとしてデプロイされる軽量L4プロキシです:

  • Rustで記述:高パフォーマンスと低メモリ使用量
  • L4専用:TCPレベルの処理のみ担当
  • ノード当たり1つ:該当ノードのすべてのPodトラフィックを処理

ztunnelのコア機能

ztunnel機能:
├── 1. mTLS暗号化/復号
│   ├── ワークロード証明書管理(SDS│   └── すべてのPod間通信を暗号化
├── 2. L4認可
│   ├── AuthorizationPolicy(L4ルールのみ)
│   └── ソース/宛先IDベースのアクセス制御
├── 3. HBONEトンネリング
│   ├── HTTP/2 CONNECTベースのトンネル
│   └── ポート15008で受信
└── 4. L4テレメトリ
    ├── TCP接続メトリクス
    └── バイト転送量追跡

ztunnel内部動作

[アウトバウンドトラフィック処理]

App (Pod A, Node 1) → reviews:9080
[1] トラフィックインターセプション(eBPFまたはiptables)
    → トラフィックをローカルztunnelにリダイレクト
[2] ztunnelが宛先を確認
    ├── Kubernetes Service解決
    └── 宛先Podのノード位置を確認
[3] HBONEトンネル確立
    ├── 宛先ノードのztunnelとmTLS接続
    ├── HTTP/2 CONNECTでトンネル作成
    └── ポート15008を使用
[4] 暗号化されたトラフィックを送信

[インバウンドトラフィック処理]

[5] 宛先ノードのztunnelがHBONEトンネルを受信
[6] mTLS復号および認可確認
    ├── ソースSPIFFE IDを検証
    └── AuthorizationPolicyを評価
[7] 平文で宛先Podに転送

ztunnelの証明書管理

ztunnelは該当ノードのすべてのPodの証明書を管理します:

ztunnel (Node 1)
├── Pod Aの証明書:spiffe://cluster.local/ns/prod/sa/frontend
├── Pod Bの証明書:spiffe://cluster.local/ns/prod/sa/reviews
└── Pod Cの証明書:spiffe://cluster.local/ns/prod/sa/ratings

証明書取得方式:
1. ztunnelがistiodに各ワークロードの証明書をリクエスト
2. Kubernetes ServiceAccountトークンで認証
3. SDSを通じて証明書を受信・更新

Waypoint Proxy:ネームスペースレベルL7プロキシ

概要

waypoint proxyはL7機能が必要な場合にのみデプロイされるEnvoyベースのプロキシです:

L4のみ必要な場合:
Pod → ztunnel → ztunnel → Pod
(mTLS + L4認可のみ)

L7が必要な場合:
Pod → ztunnel → waypoint proxy → ztunnel → Pod
HTTPルーティング、L7認可、フォールトインジェクションなど)

Waypoint Proxyのデプロイ

Kubernetes Gateway APIを使用してwaypoint proxyを作成します:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: waypoint
  namespace: production
  labels:
    istio.io/waypoint-for: service
spec:
  gatewayClassName: istio-waypoint
  listeners:
    - name: mesh
      port: 15008
      protocol: HBONE

またはistioctlを使用:

istioctl waypoint apply --namespace production

Waypoint Proxyが処理する機能

Waypoint Proxy (Envoy)├── L7トラフィック管理
│   ├── VirtualService(HTTPルーティング)
│   ├── 重み付きトラフィック分割
│   ├── リトライ、タイムアウト
│   ├── フォールトインジェクション
│   └── トラフィックミラーリング
├── L7セキュリティ
│   ├── AuthorizationPolicy(L7ルール)
│   ├── RequestAuthentication(JWT│   └── HTTPヘッダー/パスベースの認可
└── L7オブザーバビリティ
    ├── HTTPメトリクス(istio_requests_totalなど)
    ├── 分散トレーシングスパン
    └── アクセスロギング

HBONEトンネリングプロトコル

HBONE概要

HBONE(HTTP-Based Overlay Network Environment)はAmbient Meshのコア通信プロトコルです:

HBONEトンネル構造:
┌──────────────────────────────────────┐
TCP Connection (port 15008)│  ┌────────────────────────────────┐  │
│  │ TLS (mTLS)                     │  │
│  │  ┌──────────────────────────┐  │  │
│  │  │ HTTP/2 CONNECT           │  │  │
│  │  │  ┌────────────────────┐  │  │  │
│  │  │  │ Tunneled TCP Data  │  │  │  │
│  │  │  └────────────────────┘  │  │  │
│  │  └──────────────────────────┘  │  │
│  └────────────────────────────────┘  │
└──────────────────────────────────────┘

HBONE vs サイドカー方式の比較

特性サイドカー(iptables)HBONE(Ambient)
トラフィックインターセプションiptables REDIRECTeBPFまたはiptables
プロキシ位置Pod内部ノードレベル(ztunnel)
トンネリングなし(直接接続)HTTP/2 CONNECT
mTLS終端点サイドカープロキシztunnel
ポート元のサービスポート15008(HBONE)

HBONE接続フロー

Source Pod (Node 1)          Destination Pod (Node 2)
     │                              ▲
     ▼                              │
ztunnel (Node 1)              ztunnel (Node 2)
     │                              ▲
TCP: Node1Node2:15008TLS: mTLS handshake       │
HTTP/2: CONNECT method    │
     └──────────────────────────────┘

トラフィックインターセプション

eBPFベースのインターセプション(推奨)

eBPFプログラムがカーネルレベルでトラフィックをリダイレクト:

App(ソケット接続)→ eBPF hook → ztunnel
              TC(Traffic Control)または
              Socket-level redirection

利点:
- iptablesより高いパフォーマンス
- カーネルレベルで動作しオーバーヘッド最小化
- Pod別iptablesルール不要

iptablesベースのインターセプション(フォールバック)

eBPFをサポートしない環境ではiptablesを使用します:

istio-cniがノードレベルでiptablesルールを設定:

iptables -t nat -A PREROUTING \
  -p tcp \
  -m mark ! --mark 0x539/0xfff \
  -j REDIRECT --to-ports 15008

iptables -t nat -A OUTPUT \
  -p tcp \
  -m mark ! --mark 0x539/0xfff \
  -j REDIRECT --to-ports 15001

ワークロード登録

Ambient Meshの有効化

ネームスペースにラベルを追加してAmbient Meshに登録します:

kubectl label namespace production istio.io/dataplane-mode=ambient

このラベルが追加されると:

  1. 該当ネームスペースのPodトラフィックがztunnelにリダイレクト
  2. ztunnelが該当Podの証明書を管理
  3. すべてのPod間通信にmTLSを適用

L7機能の有効化

L7機能が必要な場合、waypoint proxyを追加でデプロイします:

# ネームスペースにwaypoint proxyをデプロイ
istioctl waypoint apply --namespace production

# または特定のサービスアカウントにのみ適用
istioctl waypoint apply --namespace production \
  --service-account reviews

性能比較:サイドカー vs Ambient

メモリ使用量

サイドカーモード(100 Pod):
- Envoyプロキシ:100個 x 約100MB = 約10GB
- istio-init:起動時のみ使用

Ambientモード(100 Pod、3ノード):
- ztunnel:3個 x 約50MB = 約150MB
- waypoint(必要時):1-2個 x 約100MB = 約200MB
- 合計:約350MB(サイドカー対比約97%削減)

レイテンシ

サイドカーモード:
Client AppClient EnvoyNetworkServer EnvoyServer App
             (L4+L7)                    (L4+L7)

Ambientモード(L4のみ):
Client App → ztunnel → Network → ztunnel → Server App
             (L4)                 (L4)

Ambientモード(L7含む):
Client App → ztunnel → waypoint → ztunnel → Server App
             (L4)      (L7)       (L4)

L4のみ使用する場合、Ambientがより低いレイテンシを示します。L7が必要な場合、追加のホップ(waypoint)が生じますが、リソース効率性が大幅に向上します。

起動時間

サイドカーモード:
- istio-init iptables設定:1-2- Envoy起動および構成受信:2-5- 追加合計時間:3-7
Ambientモード:
- ztunnelはすでに実行中(DaemonSet)
- Pod起動時の追加オーバーヘッド:ほぼなし
- eBPFルール適用:ミリ秒単位

制限事項と現在の状態

現在の制限事項

  1. プロトコル検出:ztunnelはL4のみ処理するため、プロトコル自動検出が限定的
  2. 一部Envoy機能未サポート:EnvoyFilter、一部高度なトラフィック管理機能
  3. マルチクラスター:まだ完全にサポートされていないシナリオが存在
  4. Windowsノード:現在未サポート

サイドカーからAmbientへのマイグレーション

推奨マイグレーション順序:

1. Ambientモードをインストール(サイドカーと共存可能)

2. テストネームスペースでAmbientを有効化
   kubectl label namespace test istio.io/dataplane-mode=ambient
   kubectl label namespace test istio-injection-  # サイドカー無効化

3. 検証後、本番ネームスペースに適用

4. 必要なネームスペースにwaypoint proxyをデプロイ

5. 既存のサイドカーラベルを削除

どのモードを選択するか

サイドカーモードが適している場合:
├── Pod別のきめ細かいL7制御が必要
├── EnvoyFilterを使用する高度な構成
├── 既存の安定した環境を維持
└── Windowsノードを使用

Ambientモードが適している場合:
├── リソース効率性が重要
├── 高速なPod起動が必要
├── サイドカーアップグレードの負担を最小化
├── 主にL4セキュリティ(mTLS)のみ必要
└── 段階的にL7機能を追加可能

まとめ

Istio Ambient Meshは、サービスメッシュの最大の不満であったサイドカーオーバーヘッド問題を解決する革新的なアプローチです。ztunnel(L4)とwaypoint proxy(L7)に機能を分離することで:

  1. リソース節約:ノード当たり1つのztunnelで数百のPodのmTLSを処理
  2. 運用の簡素化:サイドカー注入/アップグレード不要
  3. 段階的な採用:L4から始めて必要に応じてL7機能を追加

次の記事では、Istioオブザーバビリティの内部実装を見ていきます。