引言
Envoy是Cloud Native Computing Foundation(CNCF)的毕业项目,作为L7代理和通信总线,被广泛应用于Service Mesh和API网关场景。自2016年由Lyft开源以来,Envoy已迅速成长为云原生生态系统中最为关键的流量管控基础设施组件之一。无论是Kubernetes集群中的Ingress控制器,还是像Istio这样的服务网格数据面,还是大型互联网企业构建的七层流量网关,Envoy都以其卓越的性能表现和高度可扩展的架构,撑起了整个生态的流量治理骨架。
本文将深入讲解Envoy的核心配置和高级用法,从最基础的最小化配置出发,逐步深入HTTP连接管理、四级配置模型、安全加固、可观测性集成、高级流量管理和性能调优等生产级话题。所有配置示例均经过验证,读者可以直接复制到本地环境中进行测试。
Envoy核心概念
理解Envoy的关键在于掌握其配置的整体层级架构。Envoy采用自上而下四级配置模型,每一层清晰分工,通过xDS协议支持全量或增量的动态更新,这使得Envoy可以在不重启进程的前提下零损热加载配置。
四级配置模型
Envoy配置层级:
┌─────────────────────────────────────┐
│ Admin Interface │ 管理接口(9901端口,stats/debug)
├─────────────────────────────────────┤
│ Listeners │ 监听器(接收连接,绑定端口)
├─────────────────────────────────────┤
│ Filter Chains │ 过滤器链(处理请求的核心流水线)
├─────────────────────────────────────┤
│ Routes │ 路由规则(匹配路径与下游集群)
├─────────────────────────────────────┤
│ Clusters │ 集群(后端服务抽象,含负载均衡)
├─────────────────────────────────────┤
│ Endpoints │ 端点(具体实例地址与权重)
└─────────────────────────────────────┘
Listener负责在网络层面接收客户端的连接请求,并为每个连接匹配一条Filter Chain。Filter Chain中按顺序排列多个Filter,其中HTTP Connection Manager(HCM)是处理七层HTTP流量的核心过滤器。HCM内部维护独立的路由表,通过Route将请求映射到对应的Cluster,最终由Cluster管理的一组Endpoint实际承载请求转发。
xDS动态配置协议
Envoy通过xDS API与外部的控制平面(如Istio Pilot、Go Control Plane)交互,实现对配置的全动态管理。xDS家族包含以下核心协议:
- LDS(Listener Discovery Service):动态推送Listener配置。
- RDS(Route Discovery Service):动态推送Route路由规则。
- CDS(Cluster Discovery Service):动态推送Cluster后端集群配置。
- EDS(Endpoint Discovery Service):动态推送Endpoint端点信息。
- ADS(Aggregated Discovery Service):单一gRPC流聚合所有xDS资源,避免资源更新顺序依赖带来的不一致问题。
在生产环境中,强烈建议使用ADS聚合流统一推送所有配置,以保证Listener与Route之间、Route与Cluster之间的引用关系始终保持原子一致性,避免短时间内的配置断层。
基础配置
最小化配置示例
以下是一个最精简但可直接启动的Envoy配置文件,它监听在10000端口,将所有HTTP流量转发到后端服务集群。
# envoy.yaml
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: "/"
route:
cluster: service_backend
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: service_backend
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: service_backend
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: backend-service
port_value: 8080
admin:
address:
socket_address:
address: 0.0.0.0
port_value: 9901
将上述配置保存为envoy.yaml,通过如下Docker命令即可启动Envoy服务:
docker run --rm -it \
-p 10000:10000 \
-p 9901:9901 \
-v $(pwd)/envoy.yaml:/etc/envoy/envoy.yaml \
envoyproxy/envoy:v1.29.0 \
-c /etc/envoy/envoy.yaml
启动成功后,你可以通过curl http://localhost:10000/验证流量是否被正常代理到后端服务,同时通过curl http://localhost:9901/stats/prometheus获取Prometheus格式的原始指标。
Envoy架构与核心概念深度解析
HTTP Connection Manager(HCM)Filter Chain
Envoy的网络模型允许一个Listener绑定多条Filter Chain,每条Chain通过filter_chain_match条件(如SNI、源IP、目的端口等)精确匹配。对于HTTP流量,最常用的过滤器链入口是HttpConnectionManager,它完整接管HTTP/1.1和HTTP/2协议解析,并向下游的HTTP Filter链分发请求。
listeners:
- name: listener_https
address:
socket_address:
address: 0.0.0.0
port_value: 443
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"]
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
common_tls_context:
tls_certificate_sds_secret_configs:
- name: api_example_com_cert
sds_config:
path: /etc/envoy/sds/api_cert.yaml
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_https
codec_type: AUTO
http_protocol_options:
enable_trailers: true
http2_protocol_options:
max_concurrent_streams: 100
initial_stream_window_size: 65536
stream_idle_timeout: 300s
request_timeout: 300s
drain_timeout: 5s
route_config:
name: https_routes
virtual_hosts:
- name: api_vhost
domains: ["api.example.com"]
routes:
- match:
prefix: "/"
route:
cluster: api_cluster
timeout: 30s
http_filters:
- name: envoy.filters.http.cors
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
此配置展示了基于TLS SNI匹配的多域名支持。tls_inspector监听器过滤器在进入主过滤器链前解析TLS握手元数据,从而实现同端口多证书的精细化路由。codec_type: AUTO让Envoy自动在HTTP/1.1和HTTP/2之间协商,极大简化了运维负担。
HTTP连接管理与超时配置
生产环境的超时策略如果配置不当可能导致级联雪崩。Envoy在时间控制层面提供了丰富的粒度,从连接到流、到请求路由、再到重试试次均有独立超时参数。以下是一个经过生产验证的超时配置示例:
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
common_http_protocol_options:
idle_timeout: 3600s
headers_with_underscores_action: REJECT_REQUEST
http_protocol_options:
enable_trailers: true
accept_http_10: true
http2_protocol_options:
max_concurrent_streams: 100
initial_stream_window_size: 65536
initial_connection_window_size: 1048576
stream_idle_timeout: 300s
request_timeout: 300s
drain_timeout: 30s
delayed_close_timeout: 1s
关键超时参数的语义如下:stream_idle_timeout检测单个HTTP流在两次数据帧之间是否超过静默阈值,适用于防止慢攻击;request_timeout涵盖整个请求生命周期,从请求头接收完毕到响应体完全发送;drain_timeout在连接排水期间确保存量请求正常结束。headers_with_underscores_action: REJECT_REQUEST则是一项重要的安全加固手段,能够拦截利用Header名称混淆发起的协议层攻击。
高级路由配置
基于Header的路由
现代微服务发布策略中,金丝雀发布(Canary)和蓝绿部署高度依赖基于Header的流量切分能力。Envoy的路由匹配器支持对Header进行精确匹配、前缀匹配、正则匹配以及基于范围的匹配,足以覆盖绝大多数灰度发布场景。
route_config:
name: advanced_routing
virtual_hosts:
- name: api_service
domains: ["api.example.com"]
routes:
# 基于Header路由到Canary版本
- match:
prefix: "/api/v1/users"
headers:
- name: x-canary
exact_match: "true"
route:
cluster: user_service_canary
timeout: 30s
# 基于Header路由到特定版本
- match:
prefix: "/api/"
headers:
- name: x-api-version
exact_match: "v2"
route:
cluster: api_service_v2
# 默认路由
- match:
prefix: "/api/"
route:
cluster: api_service_v1
retry_policy:
retry_on: "5xx,connect-failure,reset"
num_retries: 3
per_try_timeout: 10s
retry_back_off:
base_interval: 0.25s
max_interval: 1s
在此配置中,金丝雀Header的优先级高于版本Header,因为Envoy按路由列表顺序自上而下匹配,第一条匹配成功即停止搜索。生产系统的最佳实践是将最细粒度的匹配规则放在列表前端,默认兜底规则放在尾部。
加权路由(流量分割)
A/B测试场景中,通过weighted_clusters将流量按比例分配到不同版本的后端集群是一种无侵入的发布方式。
route_config:
virtual_hosts:
- name: payment_service
domains: ["payment.example.com"]
routes:
- match:
prefix: "/process"
route:
weighted_clusters:
clusters:
- name: payment_v1
weight: 90
- name: payment_v2
weight: 10
total_weight: 100
runtime_key_prefix: routing.payment
增加runtime_key_prefix后,可以通过Envoy的运行时接口动态调整权重而无需重新加载配置。例如执行curl -X POST "localhost:9901/runtime_modify?routing.payment.payment_v1=80&routing.payment.payment_v2=20"即可实时切换流量比例。
路由重写与重定向
routes:
# URL重写
- match:
prefix: "/old-api/"
route:
cluster: new_api_service
prefix_rewrite: "/api/v2/"
# 正则重写
- match:
safe_regex:
regex: "^/users/([0-9]+)/profile$"
route:
cluster: user_service
regex_rewrite:
pattern:
google_re2: {}
regex: "^/users/([0-9]+)/profile$"
substitution: "/api/users/\\1"
# 重定向
- match:
prefix: "/legacy/"
redirect:
prefix_redirect: "/modern/"
response_code: MOVED_PERMANENTLY # 301
正则重写利用了Google RE2引擎,因此表达式需符合RE2语法约束。通过正则匹配,可以实现类似RESTful风格的URL重构,将旧版路径透明映射到新服务接口。
Cluster高级配置
熔断器(Circuit Breaker)
熔断器是防止下游故障引发级联雪崩的最后一道防线。Envoy的熔断器支持对每个Cluster按优先级分别控制最大连接数、最大挂起请求数、最大并发请求数和最大重试次数。当任何一项阈值被突破时,Envoy将快速失败,直接向上游返回错误码,避免让已经过载的后端服务雪上加霜。
clusters:
- name: order_service
connect_timeout: 0.5s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
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: 25.0
min_retry_concurrency: 10
- priority: HIGH
max_connections: 2048
max_pending_requests: 2048
max_requests: 2048
# 异常检测(自动剔除故障节点)
outlier_detection:
consecutive_5xx: 5
interval: 10s
base_ejection_time: 30s
max_ejection_percent: 50
enforcing_consecutive_5xx: 100
enforcing_success_rate: 100
success_rate_minimum_hosts: 3
success_rate_request_volume: 100
success_rate_stdev_factor: 1900
load_assignment:
cluster_name: order_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: order-1
port_value: 8080
load_balancing_weight: 100
- endpoint:
address:
socket_address:
address: order-2
port_value: 8080
load_balancing_weight: 100
track_remaining: true允许Envoy暴露remaining_cx、remaining_rq等指标,配合Prometheus可以实时监控熔断器的使用余量。retry_budget引入了基于预算的重试策略,突破了传统固定重试次数的限制,使得重试比例能够根据实际请求量自适应调整。
健康检查
主动健康检查让Envoy能够持续探测后端实例的实际可用性,结合被动异常检测可以实现趋于完美的故障节点自动剔除与恢复。
clusters:
- name: backend_service
connect_timeout: 1s
type: STRICT_DNS
lb_policy: LEAST_REQUEST
least_request_lb_config:
choice_count: 2 # Power of Two Choices算法
active_request_bias:
runtime_key: least_request_active_request_bias
default_value: 1.0
health_checks:
- timeout: 5s
interval: 10s
initial_jitter: 1s
unhealthy_threshold: 3
healthy_threshold: 2
http_health_check:
path: "/health"
expected_statuses:
- start: 200
end: 200
request_headers_to_add:
- header:
key: "x-health-check"
value: "envoy"
event_log_path: "/dev/stdout"
upstream_bind_config:
source_address:
address: 0.0.0.0
port_value: 0
LEAST_REQUEST负载均衡策略配合choice_count: 2即经典的"两权取轻"算法,在大规模后端实例场景下既保证了负载分散的均匀性,又将排序复杂度降到非常低的水平。健康检查的事件日志路径设置为标准输出,便于结合容器日志收集系统进行统一分析。
Filter配置
速率限制
Envoy支持与外部的速率限制服务(如Lyft开源的ratelimit)协同工作,实现细粒度的请求限流控制。以下配置将每条请求的关键描述符发送到限流服务进行计数决策。
http_filters:
- name: envoy.filters.http.ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
domain: api_gateway
stage: 0
timeout: 0.5s
failure_mode_deny: false
rate_limit_service:
grpc_service:
envoy_grpc:
cluster_name: ratelimit_service
timeout: 0.25s
transport_api_version: V3
enable_x_ratelimit_headers: DRAFT_VERSION_03
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
enable_x_ratelimit_headers: DRAFT_VERSION_03会向客户端响应中添加x-ratelimit-limit、x-ratelimit-remaining、x-ratelimit-reset等标准化Header,方便前端和消费方实现友好的限流提示。
CORS配置
跨域资源共享(CORS)策略直接由Envoy在边缘层处理,避免了后端服务重复实现CORS逻辑的可维护性问题。
http_filters:
- name: envoy.filters.http.cors
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
# 在virtual_hosts中配置CORS策略
virtual_hosts:
- name: api
domains: ["api.example.com"]
cors:
allow_origin_string_match:
- exact: "https://www.example.com"
- prefix: "https://"
suffix: ".example.com"
allow_methods: "GET, POST, PUT, DELETE, OPTIONS"
allow_headers: "Content-Type, Authorization, X-Request-ID, X-Correlation-ID"
expose_headers: "X-Request-ID, X-RateLimit-Remaining"
max_age: "3600"
allow_credentials: true
filter_enabled:
runtime_key: cors_filter_enabled
default_value:
numerator: 100
denominator: HUNDRED
filter_enabled_metadata:
filter: envoy.filters.http.cors
path:
- key: cors_proxy
value:
bool_match: true
JWT认证
Envoy原生支持JWT认证,无需额外部署Sidecar即可在网关层面完成身份校验,将认证压力从业务服务中剥离。
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://your-domain.auth0.com/"
audiences:
- "https://api.example.com"
remote_jwks:
http_uri:
uri: "https://your-domain.auth0.com/.well-known/jwks.json"
cluster: auth0_cluster
timeout: 1s
cache_duration:
seconds: 300
forward: true
forward_payload_header: "x-jwt-payload"
from_headers:
- name: Authorization
value_prefix: "Bearer "
rules:
- match:
prefix: "/api/public"
- match:
prefix: "/api/"
requires:
provider_name: auth0_provider
forward_payload_header将解码后的JWT Payload以Base64编码形式透传给后端服务,使后端无需重复解码Token即可获得用户身份信息。
安全加固
TLS终端与mTLS双向认证
在公网网关场景下,TLS加密是底线要求。更进一步,当Envoy作为服务网格Sidecar使用时,需要通过mTLS实现服务间的双向身份校验,确保即使是Pod内部的横向流量也处于加密与认证保护之下。
clusters:
- name: secure_backend
connect_timeout: 1s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
common_tls_context:
tls_certificate_sds_secret_configs:
- name: client_cert
sds_config:
path: /etc/envoy/sds/client_cert.yaml
validation_context_sds_secret_config:
name: server_ca
sds_config:
path: /etc/envoy/sds/server_ca.yaml
tls_params:
tls_minimum_protocol_version: TLSv1_2
cipher_suites:
- "ECDHE-RSA-AES128-GCM-SHA256"
- "ECDHE-RSA-AES256-GCM-SHA384"
load_assignment:
cluster_name: secure_backend
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: secure-backend
port_value: 8443
tls_minimum_protocol_version: TLSv1_2强制禁用所有TLSv1.0和TLSv1.1连接,消除已知的老版本协议漏洞。通过SDS(Secret Discovery Service)动态加载证书,可以在证书轮换期间实现TLS信任的平滑更新,无需重启Envoy进程。
RBAC访问控制
RBAC过滤器允许基于请求属性进行细粒度的授权决策,包括源IP范围、JWT声明、请求路径、HTTP方法等维度,实现网关层的统一鉴权。
http_filters:
- name: envoy.filters.http.rbac
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
rules:
action: ALLOW
policies:
"admin-access":
permissions:
- any: true
principals:
- header:
name: "x-role"
exact_match: "admin"
"user-readonly":
permissions:
- url_path:
path:
prefix: "/api/v1/users"
- method: GET
principals:
- header:
name: "x-role"
exact_match: "user"
"public-health":
permissions:
- url_path:
path:
exact: "/health"
principals:
- any: true
shadow_rules:
action: DENY
policies:
"shadow-deny":
permissions:
- url_path:
path:
prefix: "/internal"
principals:
- any: true
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
shadow_rules是一项极具实用价值的审计特性,它不会实际拦截请求,但会统计影子规则命中的次数并输出到Access Log中。运维人员可以通过影子模式先行评估新策略的影响面,确认无误后再将规则从shadow迁移到正式rules。
可观测性集成
结构化访问日志
统一且结构化的访问日志是现代可观测性体系的基石。Envoy原生支持JSON格式的访问日志输出,字段完全可定制,并且能够无缝接入ELK、Loki等各种日志收集与分析平台。
http_connection_manager:
access_log:
- name: envoy.access_loggers.file
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
path: "/dev/stdout"
log_format:
json_format:
timestamp: "%START_TIME%"
method: "%REQ(:METHOD)%"
path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
protocol: "%PROTOCOL%"
response_code: "%RESPONSE_CODE%"
response_flags: "%RESPONSE_FLAGS%"
bytes_received: "%BYTES_RECEIVED%"
bytes_sent: "%BYTES_SENT%"
duration: "%DURATION%"
upstream_service_time: "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%"
upstream_host: "%UPSTREAM_HOST%"
request_id: "%REQ(X-REQUEST-ID)%"
user_agent: "%REQ(USER-AGENT)%"
trace_id: "%REQ(X-B3-TRACEID)%"
authority: "%REQ(:AUTHORITY)%"
upstream_cluster: "%UPSTREAM_CLUSTER%"
connection_termination_details: "%CONNECTION_TERMINATION_DETAILS%"
grpc_status: "%GRPC_STATUS%"
tracing:
provider:
name: envoy.tracers.zipkin
typed_config:
"@type": type.googleapis.com/envoy.config.trace.v3.ZipkinConfig
collector_cluster: zipkin
collector_endpoint: "/api/v2/spans"
collector_endpoint_version: HTTP_JSON
shared_span_context: true
Prometheus指标暴露
Envoy在Admin端口9901上提供了Prometheus原生格式的指标端点,无需额外Exporter即可被Prometheus直接抓取。常用的核心指标包括:
envoy_cluster_upstream_rq_total:上游请求总数envoy_cluster_upstream_rq_time_bucket:上游请求延迟直方图envoy_http_downstream_rq_total:下游请求总数envoy_cluster_circuit_breakers_default_open:熔断器开启状态envoy_cluster_outlier_detection_ejections_active:当前被剔除的异常节点数
OpenTelemetry Tracing配置
相比传统的Zipkin或Jaeger,OpenTelemetry正逐渐成为分布式追踪领域的事实标准。以下配置展示了Envoy接入OpenTelemetry Collector的方式:
tracing:
provider:
name: envoy.tracers.opentelemetry
typed_config:
"@type": type.googleapis.com/envoy.config.trace.v3.OpenTelemetryConfig
grpc_service:
envoy_grpc:
cluster_name: opentelemetry_collector
timeout: 0.25s
service_name: envoy-gateway
Envoy产生的Span将与后端服务产生的Span汇聚在同一Trace中,通过x-request-id或W3C Trace Context进行跨服务传播,形成端到端的请求调用链全景图。
高级流量管理
全局速率限制与局部速率限制
局部速率限制filter在Envoy进程本地进行计数,不需要外部依赖,适合对全局限流精度要求不高但需要极低延迟的场景。全局速率限制则通过与ratelimit服务交互实现分布式限流,适合多实例网关共享配额的情形。
http_filters:
- name: envoy.filters.http.local_ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
stat_prefix: local_rate_limit
token_bucket:
max_tokens: 10000
tokens_per_fill: 1000
fill_interval: 1s
filter_enabled:
runtime_key: local_rate_limit_enabled
default_value:
numerator: 100
denominator: HUNDRED
filter_enforced:
runtime_key: local_rate_limit_enforced
default_value:
numerator: 100
denominator: HUNDRED
response_headers_to_add:
- append_action: OVERWRITE_IF_EXISTS_OR_ADD
header:
key: x-local-rate-limit
value: 'true'
descriptors:
- entries:
- key: path
value: "/api/v1/expensive"
token_bucket:
max_tokens: 100
tokens_per_fill: 10
fill_interval: 1s
流量镜像
流量镜像(Traffic Mirroring)允许将生产流量无损复制到预发布或新版本集群,而不会影响原请求的响应延迟和成功率。被镜像的请求的响应会被Envoy直接丢弃,原请求的用户对此完全无感知。
routes:
- match:
prefix: "/api/"
route:
cluster: production_service
request_mirror_policies:
- cluster: shadow_service
runtime_fraction:
default_value:
numerator: 10
denominator: HUNDRED
runtime_key: shadow_mirror_percent
trace_sampled: false
此配置将百分之十的生产流量镜像到shadow_service集群。开发者通过观察影子集群的延迟分布、错误率和资源消耗,可以在正式全量上线前获得新版本在真实流量下的表现数据。
故障注入
在混沌工程实践中,故障注入是验证系统韧性的有效手段。Envoy的HTTP Fault Filter支持按照指定百分比注入延迟和故障,是service mesh中实施混沌实验的基础设施。
http_filters:
- name: envoy.filters.http.fault
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.fault.v3.HTTPFault
abort:
http_status: 503
percentage:
numerator: 10
denominator: HUNDRED
delay:
fixed_delay: 2s
percentage:
numerator: 20
denominator: HUNDRED
upstream_cluster:
cluster_name: order_service
headers:
- name: x-envoy-fault
exact_match: "true"
max_active_faults: 100
response_rate_limit:
fixed_limit:
limit_kbps: 1024
percentage:
numerator: 50
denominator: HUNDRED
max_active_faults限制了同时生效的故障注入数量,避免故障实验本身因为过量注入而演变为生产事故。response_rate_limit还可以对响应带宽进行限流,模拟慢速网络环境。
gRPC转码
gRPC-Web支持
浏览器端JavaScript无法直接发起gRPC调用,因为浏览器不支持HTTP/2的 trailers和必要的二进制帧流控。Envoy的gRPC-Web过滤器承担了协议转换的职责,使得前端可以通过gRPC-Web客户端与后端gRPC服务透明通信。
http_filters:
- name: envoy.filters.http.grpc_web
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
- name: envoy.filters.http.cors
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: grpc_service
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
http2_protocol_options: {} # 启用HTTP/2
load_assignment:
cluster_name: grpc_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: grpc-backend
port_value: 50051
REST到gRPC转码
对于已经基于gRPC构建后端服务、但前端或第三方客户坚持使用REST JSON风格的团队,gRPC JSON Transcoder是一个理想的折中方案。
http_filters:
- name: envoy.filters.http.grpc_json_transcoder
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.grpc_json_transcoder.v3.GrpcJsonTranscoder
proto_descriptor: "/etc/envoy/proto_descriptor.pb"
services:
- "bookstore.BookstoreService"
print_options:
add_whitespace: true
always_print_primitive_fields: true
always_print_enums_as_ints: false
preserve_proto_field_names: false
convert_grpc_status: true
auto_mapping: true
// bookstore.proto
syntax = "proto3";
package bookstore;
import "google/api/annotations.proto";
service BookstoreService {
rpc GetBook(GetBookRequest) returns (Book) {
option (google.api.http) = {
get: "/v1/shelves/{shelf}/books/{book}"
};
}
rpc CreateBook(CreateBookRequest) returns (Book) {
option (google.api.http) = {
post: "/v1/shelves/{shelf}/books"
body: "book"
};
}
rpc ListBooks(ListBooksRequest) returns (ListBooksResponse) {
option (google.api.http) = {
get: "/v1/shelves/{shelf}/books"
};
}
}
proto_descriptor.pb文件需要通过protoc工具配合google/api/annotations.proto与google/api/http.proto提前编译生成。将编译后的描述符文件挂载到Envoy容器中,即可实现JSON与Protobuf之间的自动双向转码。
性能调优
工作线程与连接池参数
Envoy的高性能很大程度上源于其多线程无锁架构,每个工作线程独立运行事件循环。合理的工作线程和连接池参数能够显著影响资源利用率和P99延迟表现。
# 启动参数
--concurrency 4 \
--cpuset-threads \
--enable-fine-grain-logging
# cluster中的连接池配置
clusters:
- name: optimized_backend
connect_timeout: 0.25s
type: STRICT_DNS
lb_policy: ROUND_ROBIN
upstream_connection_options:
tcp_keepalive:
keepalive_time: 300
keepalive_interval: 75
keepalive_probes: 9
circuit_breakers:
thresholds:
- priority: DEFAULT
max_connections: 1000
max_pending_requests: 1000
max_requests: 1000
common_http_protocol_options:
idle_timeout: 3600s
http_protocol_options:
enable_trailers: true
typed_extension_protocol_options:
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
upstream_protocol_options:
explicit_http_config:
http2_protocol_options:
max_concurrent_streams: 100
initial_stream_window_size: 65536
initial_connection_window_size: 1048576
--concurrency参数定义了Envoy工作线程的数量,默认自动设置为机器的核心数。在容器化环境中,建议显式设置为容器CPU限额对应的核数,避免调度抖动。TCP Keepalive参数确保空闲长连接不会因为NAT网关或云厂商负载均衡器的静默超时而被意外断开。
热重启机制
Envoy的热重启机制可以在不丢包、不拒绝连接的前提下完成二进制升级和配置重载。通过父子进程间的共享内存和Unix Domain Socket传递监听器文件描述符,Envoy实现了平滑过渡。
# 执行热重启
envoy -c /etc/envoy/envoy.yaml --restart-epoch 1
# 或者通过admin接口热更新配置
curl -X POST "http://localhost:9901/runtime_modify?key1=val1&key2=val2"
curl -X POST "http://localhost:9901/config_dump"
curl -X POST "http://localhost:9901/clusters"
在Kubernetes环境中,利用preStop生命周期钩子调用排水端点curl -X POST http://localhost:9901/drain_listeners?graceful,并设置合理的terminationGracePeriodSeconds,可以让Pod在缩容或滚动更新期间完成存量请求的优雅处理。
总结
Envoy以其灵活的架构设计和丰富的L7功能,成为云原生时代流量治理的事实标准基础设施。本文从最基础的最小化配置出发,逐步深入到HTTP连接管理、四级配置模型、安全加固、可观测性集成、高级流量管理和性能调优等各个维度,提供了可直接运行的生产级配置示例。
综合全文,构建一个健壮且高性能的Envoy API网关需要遵循以下最佳实践:
模块化配置:在生产环境中彻底摒弃static_resources的静态配置方式,全面采用xDS API动态管理所有资源。通过ADS聚合流保障Listener、Route和Cluster之间的引用一致性。
熔断保护:为所有业务Cluster配置合理的circuit breakers阈值,并结合outlier_detection实现故障节点的自动检测与隔离。熔断配置应与实际业务容量相匹配,避免过于宽松失去保护意义,也避免过于严格导致正常流量被拒。
健康检查:同时启用主动健康检查和被动异常检测。主动探测提供最高置信度的节点可用性判断,被动统计则能在主动探测间隙及时发现异常节点。
可观测性 :配置结构化JSON格式的访问日志,集成Prometheus指标和OpenTelemetry分布式追踪,构建从日志到指标再到Trace的三位一体可观测体系。
安全加固:对外启用TLSv1.2及以上版本的加密传输,对内通过mTLS实现服务间双向认证。在网关层部署JWT和RBAC过滤器,将认证和鉴权压力从后端服务中剥离。
性能调优:根据容器CPU限额显式设置并发线程数,合理配置TCP Keepalive和HTTP/2流控窗口,善用热重启和优雅排水机制保障线上的滚动升级平滑无感。
关键优势:
- 高性能(C++实现,零拷贝)
- 丰富的L7功能
- 云原生设计(xDS API)
- 活跃的社区和生态
延伸阅读
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。