Envoy
Envoy Proxy 包括的技術ガイド
目次
- はじめに - Envoy Proxyとは
- アーキテクチャ概要
- コア概念: Listener, Filter Chain, Cluster, Endpoint
- 設定モデル: 静的設定とxDS動的設定
- フィルタアーキテクチャ
- ロードバランシング
- ヘルスチェックと外れ値検出
- サーキットブレーカー
- TLS/mTLS
- オブザーバビリティ
- 高度なルーティング
- Wasm拡張
- Admin API
- デプロイメントパターン
- ホットリスタート
- 実践的な設定例
- トラブルシューティング
- まとめ
1. はじめに - Envoy Proxyとは
1.1 概要
Envoy Proxyは、Lyftが開発しCloud Native Computing Foundation (CNCF)に寄贈した、高性能なL4/L7プロキシおよび通信バスである。大規模なマイクロサービスアーキテクチャ向けに設計され、現在ではサービスメッシュ(Istio, AWS App Meshなど)の中核データプレーンコンポーネントとして広く採用されている。
1.2 Envoyが解決する課題
マイクロサービスアーキテクチャでは、以下の課題が生じる:
- サービス間通信の複雑性: 数百のサービスが相互に通信する環境での信頼性確保
- 可観測性の欠如: 分散システムにおけるリクエストフローの追跡困難
- 言語・フレームワーク非依存のネットワーク機能: 各サービスが異なる言語で実装される中で、一貫したネットワークポリシーの適用
- 段階的なデプロイメント: カナリアリリース、トラフィックシフティングの実現
- セキュリティ: サービス間の暗号化通信(mTLS)の統一的な管理
Envoyはこれらの課題を、アプリケーションコードの変更なしにインフラストラクチャレイヤーで解決する。
1.3 主要な特徴
| 特徴 | 説明 |
|---|---|
| L3/L4フィルタ | TCP/UDPレベルのプロキシ機能 |
| L7フィルタ | HTTP/2, gRPC, WebSocketなどのアプリケーションプロトコル対応 |
| HTTP/2ファーストクラス | HTTP/1.1とHTTP/2の双方向変換をネイティブサポート |
| gRPCサポート | gRPCトラフィックのルーティング、ロードバランシング |
| 動的設定 | xDS APIによるランタイム設定変更(再起動不要) |
| ヘルスチェック | アクティブ/パッシブヘルスチェック |
| 高度なLB | ラウンドロビン、最小リクエスト、リングハッシュ等 |
| オブザーバビリティ | 統計、分散トレーシング、アクセスログ |
| TLS/mTLS | 証明書の自動ローテーション対応 |
| ホットリスタート | ダウンタイムなしのバイナリ更新 |
1.4 Envoyのエコシステムにおける位置づけ
+------------------------------------------------------------------+
| Control Plane |
| +------------+ +-----------+ +-------------+ +------------+ |
| | Istio | | Consul | | AWS App Mesh| | 自作 CP | |
| | (istiod) | | Connect | | | | (xDS実装) | |
| +------+-----+ +-----+-----+ +------+------+ +-----+------+ |
| | | | | |
| +-------+------+-------+-------+--------+-------+ |
| | | | |
| v v v |
| xDS API xDS API xDS API |
+--------+--------+---------+--------+--------+--------+------------+
| | |
v v v
+------------------------------------------------------------------+
| Data Plane (Envoy) |
| +--------+ +--------+ +--------+ +--------+ |
| |Envoy | |Envoy | |Envoy | |Envoy | |
| |Sidecar |<-->|Sidecar |<-->|Sidecar |<-->|Sidecar | |
| |Proxy | |Proxy | |Proxy | |Proxy | |
| +---+----+ +---+----+ +---+----+ +---+----+ |
| | | | | |
| +---+----+ +---+----+ +---+----+ +---+----+ |
| |Service | |Service | |Service | |Service | |
| | A | | B | | C | | D | |
| +--------+ +--------+ +--------+ +--------+ |
+------------------------------------------------------------------+
2. アーキテクチャ概要
2.1 全体アーキテクチャ
Envoyはシングルプロセス・マルチスレッドアーキテクチャを採用している。メインスレッドがプロセスの管理を担当し、ワーカースレッドがリクエスト処理を行う。
+======================================================================+
| Envoy Process |
| |
| +------------------+ |
| | Main Thread | |
| | +-----------+ | 設定の管理・更新 |
| | | xDS Client| | ワーカースレッドの管理 |
| | +-----------+ | 統計情報の集約 |
| | | Admin API | | ランタイム設定 |
| | +-----------+ | |
| +--------+---------+ |
| | |
| +------+------+------+------+ |
| v v v v v |
| +----+ +----+ +----+ +----+ +----+ |
| | W1 | | W2 | | W3 | | W4 | | WN | Worker Threads |
| +----+ +----+ +----+ +----+ +----+ |
| |
| 各ワーカースレッド: |
| +------------------------------------------------------------+ |
| | Listener --> Filter Chain --> Cluster Manager | |
| | Accept Process Route to | |
| | Connections Requests Upstream | |
| +------------------------------------------------------------+ |
+======================================================================+
2.2 スレッドモデル
- メインスレッド: プロセス管理、設定更新、統計集約
- ワーカースレッド: 各ワーカーは非ブロッキングイベントループ(libevent基盤)を実行
- ファイルフラッシュスレッド: アクセスログの非同期書き込み
各ワーカースレッドは、リスナーのコピーを持ち、カーネルのSO_REUSEPORTを利用して接続を受け付ける。接続は生涯を通じて単一のワーカースレッドに紐づくため、ロックの必要性が最小限に抑えられる。
2.3 接続のライフサイクル
クライアント Envoy アップストリーム
| | |
|--- TCP SYN ------------>| |
|<-- TCP SYN/ACK ---------| |
|--- TCP ACK ------------>| |
| (Listener がAccept) | |
| (Filter Chain選択) | |
|--- TLS ClientHello ---->| (TLS Inspector) |
|<-- TLS ServerHello ------| |
|--- HTTP Request ------->| (HTTP Connection Manager) |
| |--- ルーティング判定 ------->|
| |--- TCP + TLS Handshake --->|
| |--- HTTP Request ---------->|
| |<-- HTTP Response ----------|
|<-- HTTP Response --------| |
2.4 メモリモデル
- TLS(Thread Local Storage)パターン: 設定やクラスタ情報はメインスレッドで更新され、TLSを通じてワーカースレッドに伝播
- 参照カウント: 設定オブジェクトは参照カウントで管理され、古い設定は全ワーカーが参照を解放した時点で解放
- 接続プール: アップストリームへの接続はワーカースレッドごとにプールされ、HTTP/2では多重化
3. コア概念
3.1 Listener (リスナー)
リスナーは、Envoyがダウンストリーム(クライアント)からの接続を受け付けるネットワークロケーション(IPアドレス+ポート)を定義する。
static_resources:
listeners:
- name: listener_http
address:
socket_address:
address: 0.0.0.0
port_value: 8080
listener_filters:
- name: envoy.filters.listener.tls_inspector
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
filter_chains:
- filter_chain_match:
server_names:
- "api.example.com"
filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: api_service
domains: ["api.example.com"]
routes:
- match:
prefix: "/"
route:
cluster: api_cluster
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
3.2 Filter Chain (フィルタチェーン)
フィルタチェーンは、接続に対して適用されるフィルタの順序付きリストである。
ダウンストリーム接続
|
v
+-------------------+
| Listener Filter | (例: TLS Inspector)
+-------------------+
|
v
+----- Filter Chain Match -----+
| SNI, ALPN, Source IP etc. |
+------------------------------+
|
v
+-------------------+
| Network Filter | (例: HTTP Connection Manager)
+-------------------+
|
v
+-------------------+
| HTTP Filter 1 | (例: JWT Authentication)
+-------------------+
|
v
+-------------------+
| HTTP Filter 2 | (例: Router - 常に最後)
+-------------------+
|
v
アップストリームへ
3.3 Cluster (クラスタ)
クラスタは、Envoyがトラフィックを転送するアップストリームサービスのグループを定義する。
clusters:
- name: api_cluster
type: STRICT_DNS
connect_timeout: 5s
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: api_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: api-service
port_value: 8080
- name: dynamic_cluster
type: EDS
connect_timeout: 5s
lb_policy: LEAST_REQUEST
eds_cluster_config:
eds_config:
api_config_source:
api_type: GRPC
grpc_services:
- envoy_grpc:
cluster_name: xds_cluster
service_name: my-service
3.4 クラスタディスカバリタイプ
| タイプ | 説明 | 用途 |
|---|---|---|
STATIC | エンドポイントが設定で静的に定義 | 固定のアップストリーム |
STRICT_DNS | DNSを定期的に解決し、全IPをエンドポイントとして使用 | DNS名で管理するサービス |
LOGICAL_DNS | DNS解決するが、新規接続時のみ最新IPを使用 | 外部サービスへの接続 |
EDS | Endpoint Discovery Service経由で動的取得 | サービスメッシュ環境 |
ORIGINAL_DST | 元の宛先アドレスを使用 | 透過プロキシ |
3.5 Endpoint (エンドポイント)
load_assignment:
cluster_name: my_cluster
endpoints:
- priority: 0
locality:
region: ap-northeast-1
zone: ap-northeast-1a
lb_endpoints:
- endpoint:
address:
socket_address:
address: 10.0.1.10
port_value: 8080
health_status: HEALTHY
load_balancing_weight: 100
- priority: 1
locality:
region: ap-northeast-1
zone: ap-northeast-1c
lb_endpoints:
- endpoint:
address:
socket_address:
address: 10.0.3.10
port_value: 8080
4. 設定モデル
4.1 静的設定
admin:
address:
socket_address:
address: 127.0.0.1
port_value: 9901
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match:
prefix: "/api/v1"
route:
cluster: service_v1
- match:
prefix: "/api/v2"
route:
cluster: service_v2
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: service_v1
type: STRICT_DNS
connect_timeout: 5s
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service_v1
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: service-v1
port_value: 8080
4.2 xDS動的設定
xDS API の一覧:
+--------+-----------------------------------+--------------------------------+
| API | 正式名称 | 配信する設定 |
+--------+-----------------------------------+--------------------------------+
| LDS | Listener Discovery Service | リスナー設定 |
| RDS | Route Discovery Service | ルーティング設定 |
| CDS | Cluster Discovery Service | クラスタ設定 |
| EDS | Endpoint Discovery Service | エンドポイント情報 |
| SDS | Secret Discovery Service | TLS証明書・鍵 |
| VHDS | Virtual Host Discovery Service | 仮想ホスト設定 |
| SRDS | Scoped Route Discovery Service | スコープ付きルート設定 |
| ECDS | Extension Config Discovery Service| 拡張フィルタ設定 |
| RTDS | Runtime Discovery Service | ランタイムフラグ |
+--------+-----------------------------------+--------------------------------+
# ADS (Aggregated Discovery Service)
dynamic_resources:
lds_config:
resource_api_version: V3
ads: {}
cds_config:
resource_api_version: V3
ads: {}
ads_config:
api_type: GRPC
transport_api_version: V3
grpc_services:
- envoy_grpc:
cluster_name: xds_cluster
static_resources:
clusters:
- name: xds_cluster
type: STRICT_DNS
connect_timeout: 5s
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
explicit_http_config:
http2_protocol_options: {}
load_assignment:
cluster_name: xds_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: control-plane.example.com
port_value: 18000
4.3 xDSプロトコルの仕組み
Envoy (Client) <-----> Control Plane (xDS Server)
1. DiscoveryRequest ---> (subscribe)
2. DiscoveryResponse <--- (config delivery)
3. ACK/NACK ---> (confirm or reject)
State of the World (SotW): 全リソースを毎回送信
Incremental (Delta) xDS: 変更されたリソースのみ送信
5. フィルタアーキテクチャ
5.1 リスナーフィルタ
listener_filters:
- name: envoy.filters.listener.tls_inspector # TLS SNI検査
- name: envoy.filters.listener.http_inspector # HTTP/2検出
- name: envoy.filters.listener.original_dst # 元宛先復元
- name: envoy.filters.listener.proxy_protocol # PROXY Protocol
5.2 ネットワークフィルタ
filter_chains:
- filters:
- name: envoy.filters.network.tcp_proxy
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
stat_prefix: tcp_stats
cluster: backend_cluster
idle_timeout: 3600s
5.3 HTTPフィルタ
JWT Authentication
http_filters:
- name: envoy.filters.http.jwt_authn
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
providers:
auth0_provider:
issuer: "https://auth.example.com/"
audiences: ["api.example.com"]
remote_jwks:
http_uri:
uri: "https://auth.example.com/.well-known/jwks.json"
cluster: auth_cluster
timeout: 5s
cache_duration: 600s
forward: true
rules:
- match:
prefix: "/api/"
requires:
provider_name: auth0_provider
- match:
prefix: "/health"
External Authorization
- name: envoy.filters.http.ext_authz
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
grpc_service:
envoy_grpc:
cluster_name: authz_cluster
timeout: 0.25s
failure_mode_allow: false
with_request_body:
max_request_bytes: 8192
Rate Limit
- name: envoy.filters.http.ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
domain: my_rate_limit_domain
rate_limit_service:
grpc_service:
envoy_grpc:
cluster_name: ratelimit_cluster
transport_api_version: V3
enable_x_ratelimit_headers: DRAFT_VERSION_03
Lua フィルタ
- name: envoy.filters.http.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
default_source_code:
inline_string: |
function envoy_on_request(request_handle)
request_handle:headers():add("x-request-timestamp",
os.date("!%Y-%m-%dT%H:%M:%SZ"))
end
function envoy_on_response(response_handle)
response_handle:headers():add("x-envoy-proxy", "true")
response_handle:headers():remove("server")
end
Compression
- name: envoy.filters.http.compressor
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.compressor.v3.Compressor
response_direction_config:
common_config:
min_content_length: 1024
content_type:
- "text/html"
- "application/json"
compressor_library:
name: text_optimized
typed_config:
"@type": type.googleapis.com/envoy.extensions.compression.gzip.compressor.v3.Gzip
compression_level: BEST_SPEED
5.4 推奨フィルタ順序
http_filters:
# 1. CORS
- name: envoy.filters.http.cors
# 2. JWT認証
- name: envoy.filters.http.jwt_authn
# 3. 外部認可
- name: envoy.filters.http.ext_authz
# 4. レートリミット
- name: envoy.filters.http.ratelimit
# 5. カスタムロジック (Lua/Wasm)
- name: envoy.filters.http.lua
# 6. 圧縮
- name: envoy.filters.http.compressor
# 7. Router (常に最後)
- name: envoy.filters.http.router
6. ロードバランシング
6.1 アルゴリズム比較
| アルゴリズム | 適用場面 | 特徴 |
|---|---|---|
| ROUND_ROBIN | 一般的な用途 | シンプル、重み付け対応 |
| LEAST_REQUEST | レイテンシ重視 | 応答時間に基づく分散 |
| RING_HASH | セッション維持 | コンシステントハッシュ |
| MAGLEV | セッション維持 | Ring Hashより均一な分散 |
| RANDOM | テスト・シンプル | ランダム分散 |
clusters:
- name: ring_hash_cluster
lb_policy: RING_HASH
ring_hash_lb_config:
minimum_ring_size: 1024
hash_function: XX_HASH
# ハッシュポリシー
route_config:
virtual_hosts:
- name: cache_host
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: ring_hash_cluster
hash_policy:
- header:
header_name: x-session-id
- connection_properties:
source_ip: true
terminal: true
6.2 ゾーン認識ロードバランシング
node:
locality:
region: ap-northeast-1
zone: ap-northeast-1a
clusters:
- name: zone_aware_cluster
type: EDS
lb_policy: ROUND_ROBIN
common_lb_config:
zone_aware_lb_config:
routing_enabled:
default_value:
numerator: 100
denominator: HUNDRED
min_cluster_size: 6
6.3 Slow Start Mode
clusters:
- name: slow_start_cluster
lb_policy: ROUND_ROBIN
round_robin_lb_config:
slow_start_config:
slow_start_window: 60s
aggression:
default_value: 1.0
min_weight_percent:
value: 10
7. ヘルスチェックと外れ値検出
7.1 アクティブヘルスチェック
clusters:
- name: health_checked_cluster
health_checks:
- timeout: 3s
interval: 10s
unhealthy_threshold: 3
healthy_threshold: 2
no_traffic_interval: 60s
unhealthy_interval: 5s
http_health_check:
path: "/healthz"
expected_statuses:
- start: 200
end: 299
# gRPCヘルスチェック
# - grpc_health_check:
# service_name: "my.service.v1"
# TCPヘルスチェック
# - tcp_health_check:
# send: { text: "PING" }
# receive: [{ text: "PONG" }]
7.2 外れ値検出 (Outlier Detection)
clusters:
- name: outlier_detection_cluster
outlier_detection:
consecutive_5xx: 5
consecutive_gateway_failure: 3
success_rate_minimum_hosts: 3
success_rate_request_volume: 100
success_rate_stdev_factor: 1900
interval: 10s
base_ejection_time: 30s
max_ejection_percent: 50
max_ejection_time: 300s
failure_percentage_threshold: 85
split_external_local_origin_errors: true
consecutive_local_origin_failure: 5
8. サーキットブレーカー
clusters:
- name: circuit_breaker_cluster
circuit_breakers:
thresholds:
- priority: DEFAULT
max_connections: 1024
max_pending_requests: 1024
max_requests: 1024
max_retries: 3
track_remaining: true
retry_budget:
budget_percent:
value: 20.0
min_retry_concurrency: 3
- priority: HIGH
max_connections: 2048
max_pending_requests: 2048
max_requests: 2048
max_retries: 10
サーキットブレーカーの閾値チェック:
max_connections超過 --> 503 (x-envoy-overloaded)
max_pending_requests超過 --> 503
max_requests超過 (HTTP/2) --> 503
max_retries超過 --> リトライスキップ
9. TLS/mTLS
9.1 ダウンストリームTLS
filter_chains:
- transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_params:
tls_minimum_protocol_version: TLSv1_2
tls_maximum_protocol_version: TLSv1_3
tls_certificates:
- certificate_chain:
filename: /etc/envoy/certs/server-cert.pem
private_key:
filename: /etc/envoy/certs/server-key.pem
alpn_protocols: [h2, http/1.1]
9.2 mTLS
# ダウンストリームmTLS
transport_socket:
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
require_client_certificate: true
common_tls_context:
tls_certificates:
- certificate_chain: { filename: /etc/envoy/certs/server-cert.pem }
private_key: { filename: /etc/envoy/certs/server-key.pem }
validation_context:
trusted_ca: { filename: /etc/envoy/certs/ca-cert.pem }
match_typed_subject_alt_names:
- san_type: URI
matcher:
prefix: "spiffe://example.com/service/"
# アップストリームmTLS
clusters:
- name: mtls_upstream
transport_socket:
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
common_tls_context:
tls_certificates:
- certificate_chain: { filename: /etc/envoy/certs/client-cert.pem }
private_key: { filename: /etc/envoy/certs/client-key.pem }
validation_context:
trusted_ca: { filename: /etc/envoy/certs/upstream-ca.pem }
sni: upstream.example.com
10. オブザーバビリティ
10.1 統計情報
stats_sinks:
- name: envoy.stat_sinks.statsd
typed_config:
"@type": type.googleapis.com/envoy.config.metrics.v3.StatsdSink
tcp_cluster_name: statsd_cluster
stats_config:
stats_tags:
- tag_name: service
regex: "^cluster\\.((.+?)\\.).*$"
use_all_default_tags: true
主要な統計:
server.live / server.memory_allocated / server.concurrency
listener.{addr}.downstream_cx_active / downstream_cx_total
http.{prefix}.downstream_rq_total / downstream_rq_2xx / downstream_rq_5xx
cluster.{name}.upstream_cx_active / upstream_rq_total / upstream_rq_time
cluster.{name}.upstream_rq_retry / upstream_rq_timeout
cluster.{name}.membership_healthy / membership_total
cluster.{name}.outlier_detection.ejections_active
cluster.{name}.circuit_breakers.default.remaining_cx / remaining_rq
10.2 アクセスログ
access_log:
- name: envoy.access_loggers.file
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: /var/log/envoy/access.log
log_format:
json_format:
timestamp: "%START_TIME%"
method: "%REQ(:METHOD)%"
path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
response_code: "%RESPONSE_CODE%"
response_flags: "%RESPONSE_FLAGS%"
duration_ms: "%DURATION%"
upstream_host: "%UPSTREAM_HOST%"
request_id: "%REQ(X-REQUEST-ID)%"
trace_id: "%REQ(X-B3-TRACEID)%"
10.3 レスポンスフラグ
| Flag | 説明 |
|---|---|
| UH | アップストリームにhealthyなホストがない |
| UF | アップストリーム接続障害 |
| UO | アップストリームオーバーフロー(サーキットブレーカー) |
| NR | ルートが見つからない |
| URX | リトライ上限超過 |
| UT | アップストリームリクエストタイムアウト |
| RL | レートリミット |
| DC | ダウンストリーム接続終了 |
10.4 分散トレーシング
tracing:
provider:
name: envoy.tracers.opentelemetry
typed_config:
"@type": type.googleapis.com/envoy.config.trace.v3.OpenTelemetryConfig
grpc_service:
envoy_grpc:
cluster_name: otel_collector
service_name: my-envoy-proxy
random_sampling:
value: 10.0
11. 高度なルーティング
11.1 ヘッダーベースルーティング
routes:
- match:
prefix: "/api"
headers:
- name: x-api-version
exact_match: "v2"
route:
cluster: api_v2_cluster
- match:
prefix: "/api"
headers:
- name: x-canary
present_match: true
route:
cluster: api_canary_cluster
11.2 重み付きルーティング(カナリア)
routes:
- match:
prefix: "/"
route:
weighted_clusters:
clusters:
- name: production_cluster
weight: 90
- name: canary_cluster
weight: 10
total_weight: 100
11.3 リトライポリシー
route:
cluster: api_cluster
timeout: 30s
retry_policy:
retry_on: "5xx,reset,connect-failure,retriable-4xx"
num_retries: 3
per_try_timeout: 10s
retry_back_off:
base_interval: 0.1s
max_interval: 1s
retriable_status_codes: [503, 429]
retry_host_predicate:
- name: envoy.retry_host_predicates.previous_hosts
11.4 リクエストミラーリング
route:
cluster: production_cluster
request_mirror_policies:
- cluster: shadow_cluster
runtime_fraction:
default_value:
numerator: 100
denominator: HUNDRED
11.5 ヘッダー操作
virtual_hosts:
- name: header_manipulation
domains: ["*"]
request_headers_to_add:
- header:
key: x-forwarded-service
value: envoy-proxy
request_headers_to_remove:
- x-internal-token
response_headers_to_add:
- header:
key: strict-transport-security
value: "max-age=31536000; includeSubDomains"
- header:
key: x-content-type-options
value: "nosniff"
response_headers_to_remove:
- x-powered-by
- server
routes:
- match:
prefix: "/"
route:
cluster: backend
host_rewrite_literal: backend.internal.example.com
prefix_rewrite: "/v2/"
11.6 タイムアウト設定
# ルートレベル
route:
cluster: backend
timeout: 300s
idle_timeout: 60s
# HTTP Connection Managerレベル
http_connection_manager:
request_timeout: 300s
request_headers_timeout: 10s
stream_idle_timeout: 300s
drain_timeout: 30s
12. Wasm拡張
http_filters:
- name: envoy.filters.http.wasm
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
config:
name: my_custom_filter
root_id: my_root_id
configuration:
"@type": type.googleapis.com/google.protobuf.StringValue
value: '{"allowed_origins": ["example.com"]}'
vm_config:
runtime: envoy.wasm.runtime.v8
code:
local:
filename: /etc/envoy/wasm/my_filter.wasm
Rust Wasm フィルタ例
use proxy_wasm::traits::*;
use proxy_wasm::types::*;
proxy_wasm::main! {{
proxy_wasm::set_root_context(|_| -> Box<dyn RootContext> {
Box::new(MyFilterRoot { config: String::new() })
});
}}
struct MyFilter { config: String }
impl Context for MyFilter {}
impl HttpContext for MyFilter {
fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
self.add_http_request_header("x-wasm-filter", "processed");
if let Some(path) = self.get_http_request_header(":path") {
if path.contains("/admin") {
self.send_http_response(403, vec![], Some(b"Forbidden"));
return Action::Pause;
}
}
Action::Continue
}
}
13. Admin API
admin:
address:
socket_address:
address: 127.0.0.1 # ローカルホストのみ
port_value: 9901
| エンドポイント | 説明 |
|---|---|
| GET /server_info | サーバー情報 |
| GET /ready | レディネスチェック |
| GET /stats | 全統計情報 |
| GET /stats?format=prometheus | Prometheus形式 |
| GET /clusters | クラスタ・エンドポイント状態 |
| GET /config_dump | 設定ダンプ |
| POST /logging?level=debug | ログレベル変更 |
| POST /drain_listeners | リスナードレイン |
| POST /healthcheck/fail | ヘルスチェック失敗強制 |
| POST /healthcheck/ok | ヘルスチェック復帰 |
14. デプロイメントパターン
14.1 サイドカープロキシ
+------------------------------------------------------------------+
| Kubernetes Pod |
| +-------------------+ +-------------------+ |
| | Application | localhost | Envoy |<-- External |
| | Container |<---------->| Sidecar | Traffic |
| +-------------------+ +-------------------+ |
+------------------------------------------------------------------+
14.2 フロントプロキシ
Internet --> LB --> Envoy Front Proxy
| | |
Svc A Svc B Svc C
14.3 Ingress/Egressゲートウェイ
External --> Ingress GW --> Pods --> Egress GW --> External Services
15. ホットリスタート
+----------+ +----------+
| Old Envoy| fork & FD transfer | New Envoy|
| Process | -------------------------> | Process |
| drain | 新規接続は新プロセスへ | リスナー |
| 開始 | | バインド |
| 既存接続| | 新規接続 |
| 処理中 | | 受付 |
| 終了 X | | 完全稼働 |
+----------+ +----------+
envoy -c /etc/envoy/envoy.yaml \
--restart-epoch 1 \
--drain-time-s 60 \
--parent-shutdown-time-s 90
16. 実践的な設定例
本番環境向けサイドカー設定(インバウンド+アウトバウンドリスナー、mTLS、ヘルスチェック、サーキットブレーカー、外れ値検出、OpenTelemetryトレーシング、JSON形式アクセスログを含む完全な設定)は、本ドキュメントのセクションファイル(/tmp/envoy_jp_sec08.md)に記載されています。
17. トラブルシューティング
17.1 一般的な問題
| 問題 | 原因 | 対処 |
|---|---|---|
| 503 UH | healthyなアップストリームなし | ヘルスチェック設定確認、upstream稼働確認 |
| 503 UO | サーキットブレーカー発動 | 閾値調整、upstream スケールアウト |
| タイムアウト | connect_timeout / route timeout | タイムアウト値確認、ネットワーク経路確認 |
17.2 デバッグ
curl -X POST "http://localhost:9901/logging?level=debug"
curl -X POST "http://localhost:9901/logging?paths=connection:trace,http:debug"
curl -X POST "http://localhost:9901/logging?level=info" # 元に戻す
envoy --mode validate -c /etc/envoy/envoy.yaml # 設定検証
18. まとめ
SREエンジニアへの推奨事項
| 推奨事項 | 詳細 |
|---|---|
| 段階的導入 | まずフロントプロキシとして導入し、徐々にサイドカーへ移行 |
| オブザーバビリティ優先 | 統計、アクセスログ、トレーシングを最初に設定 |
| サーキットブレーカー | 本番トラフィックパターンに基づいた閾値設定 |
| 外れ値検出 | アクティブヘルスチェックと併用で信頼性向上 |
| TLS/mTLS標準化 | SDSを活用した証明書管理の自動化 |
| リトライの慎重な設定 | リトライバジェットでリトライストーム防止 |
| Admin API保護 | 必ずローカルホストのみでリッスン |
| ホットリスタート活用 | ゼロダウンタイムのバイナリ更新 |
参考リソース
- Envoy公式ドキュメント: https://www.envoyproxy.io/docs/envoy/latest/
- Envoy GitHub: https://github.com/envoyproxy/envoy
- xDS API仕様: https://www.envoyproxy.io/docs/envoy/latest/api-docs/xds_protocol
- proxy-wasm SDK: https://github.com/proxy-wasm