- Authors

- Name
- Youngju Kim
- @fjvbn20031
- はじめに
- Istioアーキテクチャ概要
- istiod:統合コントロールプレーン
- Envoyサイドカー注入メカニズム
- xDSプロトコル詳細
- Envoyフィルターチェーンアーキテクチャ
- ワークロードアイデンティティ:SPIFFE
- 構成変換:Istio CRDからEnvoy構成へ
- 構成同期とデバッグ
- パフォーマンスの考慮事項
- まとめ
はじめに
IstioはKubernetes環境で最も広く使用されているサービスメッシュです。しかし「VirtualServiceを作成するとトラフィックがルーティングされる」というレベルを超えて、内部で実際に何が起きているかを理解することは、運用とトラブルシューティングに大きな違いをもたらします。
この記事では、Istioのコントロールプレーンとデータプレーンがどのように相互作用し、ユーザーが定義したCRDがどのようにEnvoy構成に変換されるかの内部メカニズムを分析します。
Istioアーキテクチャ概要
Istioは大きく2つの部分で構成されます:
┌─────────────────────────────────────────────────┐
│ Control Plane │
│ ┌───────────────────────────────────────────┐ │
│ │ istiod │ │
│ │ ┌─────────┐ ┌─────────┐ ┌──────────┐ │ │
│ │ │ Pilot │ │ Citadel │ │ Galley │ │ │
│ │ │ (xDS) │ │ (CA) │ │(Validate)│ │ │
│ │ └─────────┘ └─────────┘ └──────────┘ │ │
│ └───────────────────────────────────────────┘ │
├─────────────────────────────────────────────────┤
│ Data Plane │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ App + EP │ │ App + EP │ │ App + EP │ │
│ │ (Pod A) │ │ (Pod B) │ │ (Pod C) │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ EP = Envoy Proxy (istio-proxy sidecar) │
└─────────────────────────────────────────────────┘
istiod:統合コントロールプレーン
歴史的背景
Istio 1.5以前は、Pilot、Citadel、Galley、Mixerがそれぞれ別のマイクロサービスとしてデプロイされていました。Istio 1.5からistiodという単一バイナリに統合され、Mixerは1.8で完全に削除されました。
Pilot:トラフィック管理エンジン
PilotはistiodのコアでありI、以下の役割を果たします:
- サービスディスカバリ:Kubernetes APIサーバーを監視してService、Endpoint、Pod変更を追跡
- 構成変換:Istio CRD(VirtualService、DestinationRuleなど)をEnvoy構成に変換
- xDSサーバー:変換された構成をgRPCストリームで各Envoyプロキシにプッシュ
Kubernetes API Server
│
▼
┌─────────┐
│ Pilot │ ← Istio CRD監視 (VirtualService, DestinationRule, Gateway...)
│ │ ← Kubernetesリソース監視 (Service, Endpoints, Pod...)
└────┬────┘
│ xDS (gRPC stream)
▼
┌─────────┐
│ Envoy │ ← LDS, RDS, CDS, EDS, SDS受信
└─────────┘
Citadel:証明書管理
Citadel(現在istiodに統合)はメッシュ内のワークロードアイデンティティと証明書を管理します:
- **CA(Certificate Authority)**の役割を遂行
- 各ワークロードにX.509証明書を発行
- SPIFFE標準ベースのアイデンティティ付与
- 証明書の自動ローテーション(デフォルト24時間)
Galley:構成検証
GalleyはIstio構成の妥当性を検証します:
- Kubernetes Admission Webhookによる構成検証
- CRDスキーマ検証
- 構成間の参照整合性確認(例:VirtualServiceが参照するGatewayの存在確認)
Envoyサイドカー注入メカニズム
MutatingWebhookConfiguration
Istioのサイドカー注入はKubernetesのMutatingAdmissionWebhookを活用します:
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: istio-sidecar-injector
webhooks:
- name: sidecar-injector.istio.io
namespaceSelector:
matchLabels:
istio-injection: enabled
rules:
- apiGroups: ['']
apiVersions: ['v1']
operations: ['CREATE']
resources: ['pods']
Podが作成される際、以下のプロセスが進行します:
1. kubectl apply -f deployment.yaml
│
2. Kubernetes API ServerがAdmission Webhookを呼び出し
│
3. istiodのSidecar InjectorがPodスペックを修正
│
4. 修正されたPodスペックが返却
│
5. 修正されたスペックでPodを作成
注入されるコンテナ
サイドカー注入時に2つのコンテナが追加されます:
1. istio-init(Initコンテナ)
initContainers:
- name: istio-init
image: proxyv2
command:
- istio-iptables
- '-p'
- '15001' # Envoy outboundポート
- '-z'
- '15006' # Envoy inboundポート
- '-u'
- '1337' # istio-proxy UID(このUIDのトラフィックはリダイレクト除外)
- '-m'
- 'REDIRECT'
securityContext:
capabilities:
add: ['NET_ADMIN', 'NET_RAW']
istio-initコンテナはiptablesルールを設定して、すべてのインバウンド/アウトバウンドトラフィックをEnvoyプロキシにリダイレクトします。
2. istio-proxy(サイドカーコンテナ)
containers:
- name: istio-proxy
image: proxyv2
ports:
- containerPort: 15090 # Prometheusメトリクス
- containerPort: 15021 # ヘルスチェック
env:
- name: ISTIO_META_CLUSTER_ID
value: 'Kubernetes'
- name: PILOT_CERT_PROVIDER
value: 'istiod'
iptablesトラフィックリダイレクト
istio-initが設定するiptablesルールのフロー:
[インバウンドトラフィック]
外部 → Pod IP:Port
→ iptables PREROUTING
→ ISTIO_INBOUNDチェーン
→ REDIRECT to 15006 (Envoy inbound listener)
→ Envoyが処理後localhost:AppPortに転送
[アウトバウンドトラフィック]
App → 外部サービス IP:Port
→ iptables OUTPUT
→ ISTIO_OUTPUTチェーン
→ REDIRECT to 15001 (Envoy outbound listener)
→ Envoyが処理後実際の宛先に転送
[例外]
UID 1337 (istio-proxy)のトラフィックはリダイレクト除外 → 無限ループ防止
xDSプロトコル詳細
xDS(x Discovery Service)はEnvoyが動的に構成を受信するAPIプロトコルです。
xDS API種類
| API | 正式名称 | 役割 |
|---|---|---|
| LDS | Listener Discovery Service | リスナー構成(ポート、プロトコル) |
| RDS | Route Discovery Service | HTTPルーティングルール |
| CDS | Cluster Discovery Service | アップストリームクラスター定義 |
| EDS | Endpoint Discovery Service | クラスター内の実際のエンドポイントリスト |
| SDS | Secret Discovery Service | TLS証明書とキー |
構成プッシュフロー
[1] ユーザーがVirtualServiceを作成
│
[2] PilotがKubernetes API監視で変更を検知
│
[3] PilotがVirtualServiceをEnvoy RDS構成に変換
│
[4] 関連するCDS、EDS構成も同時に生成
│
[5] gRPCストリームで該当ワークロードのEnvoyにプッシュ
│
[6] Envoyが新しい構成をホットリロード(接続切断なし)
ADS(Aggregated Discovery Service)
IstioはADSを使用してすべてのxDSレスポンスを単一のgRPCストリームに統合します。これにより構成の一貫性が保証されます:
- CDSとEDS間の順序保証(クラスター定義が先、エンドポイントが後)
- LDSとRDS間の順序保証
- アトミックな構成更新
構成の確認方法
# 特定PodのEnvoyリスナー確認
istioctl proxy-config listeners PODNAME.NAMESPACE
# ルート構成確認
istioctl proxy-config routes PODNAME.NAMESPACE
# クラスター構成確認
istioctl proxy-config clusters PODNAME.NAMESPACE
# エンドポイント確認
istioctl proxy-config endpoints PODNAME.NAMESPACE
# 全Envoy構成ダンプ
istioctl proxy-config all PODNAME.NAMESPACE -o json
Envoyフィルターチェーンアーキテクチャ
Envoyプロキシは階層的なフィルターチェーンでリクエストを処理します:
[リクエストフロー]
Listener(ポートバインディング)
│
▼
Filter Chain(一致するフィルターチェーンを選択)
│
├── Network Filters
│ ├── TCP Proxy Filter (L4)
│ └── HTTP Connection Manager (L7)
│ │
│ ├── HTTP Filters
│ │ ├── RBAC Filter(認可)
│ │ ├── JWT Authn Filter(認証)
│ │ ├── Fault Injection Filter
│ │ ├── CORS Filter
│ │ ├── Stats Filter(メトリクス)
│ │ └── Router Filter(最終ルーティング)
│ │
│ └── Route Configuration
│ ├── Virtual Host選択
│ └── Routeマッチングとクラスター決定
│
▼
Cluster(アップストリーム選択)
│
▼
Endpoint(実際の宛先Pod)
リスナー構造
Listener 0.0.0.0:15006 (Inbound)
├── FilterChain: Appポート(例:8080)
│ ├── TLS Inspector
│ ├── HTTP Connection Manager
│ │ ├── istio_authn filter
│ │ ├── envoy.filters.http.rbac
│ │ └── envoy.filters.http.router
│ └── Route: inbound|8080|http|service.ns.svc.cluster.local
└── FilterChain: Default (passthrough)
Listener 0.0.0.0:15001 (Outbound)
├── FilterChain: サービス別マッチング
│ ├── HTTP Connection Manager
│ │ ├── envoy.filters.http.fault
│ │ ├── envoy.filters.http.cors
│ │ ├── istio.stats
│ │ └── envoy.filters.http.router
│ └── Route: サービス別VirtualHost
└── FilterChain: PassthroughCluster(マッチしないトラフィック)
ワークロードアイデンティティ:SPIFFE
SPIFFE IDスキーム
IstioはSPIFFE(Secure Production Identity Framework For Everyone)標準を使用します:
spiffe://TRUST_DOMAIN/ns/NAMESPACE/sa/SERVICE_ACCOUNT
例:
spiffe://cluster.local/ns/production/sa/frontend
証明書発行フロー(CSR Flow)
[1] istio-agent(Pod内)が鍵ペアを生成
│
[2] CSR(Certificate Signing Request)を作成
│
[3] CSRをistiodに送信(gRPC、ブートストラップトークンで認証済み)
│
[4] istiodがCSRを検証:
- ServiceAccountトークンの妥当性
- ネームスペース所属の確認
│
[5] istiodのCAがX.509証明書に署名
│
[6] 署名済み証明書をistio-agentに返却
│
[7] istio-agentがSDSを通じてEnvoyに証明書を配信
│
[8] EnvoyがmTLSに証明書を使用
SDS(Secret Discovery Service)
証明書はファイルシステムではなくSDSを通じてEnvoyに配信されます:
- istio-agentがローカルSDSサーバーの役割を担当
- EnvoyがSDS APIで証明書をリクエスト
- 証明書ローテーション時にEnvoyの再起動不要
- 証明書がディスクに書き込まれないためセキュリティが向上
構成変換:Istio CRDからEnvoy構成へ
VirtualService変換例
ユーザーが定義したVirtualService:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: reviews-route
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
これがEnvoy RDS構成に変換されます:
{
"name": "reviews.default.svc.cluster.local:9080",
"virtual_hosts": [
{
"name": "reviews.default.svc.cluster.local:9080",
"domains": ["reviews.default.svc.cluster.local"],
"routes": [
{
"match": {
"prefix": "/",
"headers": [
{
"name": "end-user",
"string_match": {
"exact": "jason"
}
}
]
},
"route": {
"cluster": "outbound|9080|v2|reviews.default.svc.cluster.local"
}
},
{
"match": {
"prefix": "/"
},
"route": {
"cluster": "outbound|9080|v1|reviews.default.svc.cluster.local"
}
}
]
}
]
}
DestinationRule変換例
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: reviews-destination
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
これがEnvoy CDS構成に変換されます:
{
"name": "outbound|9080|v1|reviews.default.svc.cluster.local",
"type": "EDS",
"eds_cluster_config": {
"service_name": "outbound|9080|v1|reviews.default.svc.cluster.local"
},
"circuit_breakers": {
"thresholds": [
{
"max_connections": 100
}
]
},
"transport_socket": {
"name": "envoy.transport_sockets.tls",
"typed_config": {
"common_tls_context": {
"tls_certificate_sds_secret_configs": [
{
"name": "default",
"sds_config": {
"api_config_source": {
"api_type": "GRPC",
"grpc_services": [
{
"envoy_grpc": {
"cluster_name": "sds-grpc"
}
}
]
}
}
}
]
}
}
}
}
構成同期とデバッグ
proxy-statusで同期状態を確認
$ istioctl proxy-status
NAME CDS LDS EDS RDS ECDS ISTIOD
frontend-v1-xxx.prod SYNCED SYNCED SYNCED SYNCED istiod-abc
reviews-v1-yyy.prod SYNCED SYNCED SYNCED SYNCED istiod-abc
ratings-v1-zzz.prod STALE SYNCED SYNCED SYNCED istiod-abc
ステータスコード:
- SYNCED:プロキシが最新の構成を受信済み
- NOT SENT:istiodがまだ構成を送信していない
- STALE:istiodが構成を送信したがACKを受信していない
構成差分の比較
# istiodが送信した構成とプロキシの現在の構成を比較
istioctl proxy-config all PODNAME -o json > proxy-config.json
istioctl proxy-status PODNAME --diff
パフォーマンスの考慮事項
コントロールプレーンのスケーリング
- istiodは水平スケール可能(複数レプリカ)
- 各Envoyは1つのistiodインスタンスに接続
- istiod障害時、Envoyは最後に受信した構成で動作を継続
大規模メッシュでの最適化
- Sidecarリソースの使用:各ワークロードが知る必要のあるサービス範囲を制限
- exportToの設定:CRDの可視性範囲を制限
- イベントバッチ処理:istiodは短期間内の複数変更をまとめてプッシュ
- 増分xDS(Delta xDS):変更部分のみ送信
# SidecarリソースでEnvoyメモリを最適化
apiVersion: networking.istio.io/v1beta1
kind: Sidecar
metadata:
name: default
namespace: production
spec:
egress:
- hosts:
- './*' # 同じネームスペースのサービス
- 'istio-system/*' # Istioシステムサービス
- 'monitoring/prometheus' # 特定の外部サービス
まとめ
Istioの内部アーキテクチャを理解すると、以下のメリットがあります:
- トラブルシューティング能力の向上:xDS同期問題、サイドカー注入失敗、証明書期限切れなどを迅速に診断
- パフォーマンス最適化:Sidecarリソース、接続プールチューニング、構成範囲制限などを適切に活用
- セキュリティ強化:mTLSの動作原理を理解し、正しいPeerAuthentication設定を行う
次の記事では、トラフィック管理エンジンの内部動作をさらに深く見ていきます。