2. Envoy 架构核心:Listener、Cluster、Endpoint、Route、Filter 链
Envoy 作为服务网格的数据面核心,其架构围绕五个关键抽象构建:Listener(监听器)、Cluster(集群)、Endpoint(端点)、Route(路由)和 Filter 链(过滤器链)。理解这五个组件及其协作关系,是进行流量拓扑分析和日志故障排查的基础。
核心原则:Envoy 采用“先监听、再路由、后转发”的流水线模型。流量从 Listener 进入,经过 Filter 链处理,由 Route 匹配规则,最终转发到 Cluster 中的某个 Endpoint。
2.1 五大核心组件概述
| 组件 | 职责 | 故障排查关注点 |
|---|---|---|
| Listener | 定义 Envoy 监听的 IP 地址和端口,接收入站流量。 | 端口冲突、监听失败、TLS 证书加载错误。 |
| Filter 链 | 挂载在 Listener 上的处理管道,执行协议解析、流量劫持、日志生成等。 | 过滤器顺序错误、配置缺失导致连接断开、日志字段丢失。 |
| Route | 根据请求属性(Host、Path、Header)匹配虚拟主机,决定流量去向。 | 路由规则未命中、权重分配异常、重定向循环。 |
| Cluster | 定义一组提供相同服务的上游主机集合,包含负载均衡策略和健康检查。 | 集群为空、健康检查失败、连接池耗尽。 |
| Endpoint | Cluster 中的具体上游实例(IP:Port),是流量的最终目的地。 | 端点不可达、DNS 解析失败、熔断触发。 |
2.2 组件协作流程
下图展示了 Envoy 处理一次请求的完整路径,从 Listener 接收到 Endpoint 转发,清晰呈现了五个核心组件的协作关系。
2.3 Listener 与 Filter 链详解
Listener 是流量的入口。每个 Listener 可以绑定多个 Filter 链,通过 filter_chain_match 条件(如 SNI、ALPN、源 IP)进行区分。最常见的场景是:一个 Listener 同时处理 HTTP 和 HTTPS 流量,通过 TLS 检查器过滤器分流。
排查技巧:当客户端连接被拒绝时,优先检查 Listener 的
bind_to_port 和 reuse_port 配置。使用 curl -v 测试端口可达性,结合 Envoy 的 /listeners 管理端点确认监听状态。
2.4 Route 与 Cluster 的映射关系
Route 配置位于 HTTP 连接管理器(HCM) 过滤器内部。一个典型的虚拟主机(VirtualHost)包含多个路由规则,每个规则指向一个 Cluster。Envoy 支持多种路由匹配条件:
- 前缀匹配:
prefix: /api/v1→ 匹配以该路径开头的请求。 - 精确匹配:
path: /healthz→ 仅匹配完全相同的路径。 - 正则匹配:
safe_regex: /users/\d+→ 匹配用户 ID 为数字的请求。 - Header 匹配:
headers: [name: :method, value: POST]→ 仅匹配 POST 方法。
2.5 Cluster 与 Endpoint 的负载均衡
Cluster 管理一组 Endpoint,Envoy 支持多种负载均衡策略:
| 策略 | 说明 | 适用场景 |
|---|---|---|
| 轮询(ROUND_ROBIN) | 依次将请求分发到每个 Endpoint。 | 通用场景,各实例性能相近。 |
| 最少请求(LEAST_REQUEST) | 选择当前活跃请求数最少的 Endpoint。 | 请求处理时间差异大的场景。 |
| 一致性哈希(RING_HASH) | 根据请求属性(如源 IP、Cookie)哈希到固定 Endpoint。 | 需要会话保持的场景。 |
| 随机(RANDOM) | 随机选择一个 Endpoint。 | 测试或低负载场景。 |
常见故障:当 Cluster 的
type 设置为 STRICT_DNS 时,如果 DNS 解析失败或返回空结果,Envoy 会标记该集群为“未就绪”,导致 503 响应。排查时检查 /clusters 管理端点,观察 membership_total 和 host_status 字段。
2.6 配置示例:核心组件联动
以下是一个简化的 Envoy 配置片段,展示了 Listener、Filter 链、Route、Cluster 和 Endpoint 的完整定义:
static_resources:
listeners:
- name: ingress_listener
address:
socket_address: { address: 0.0.0.0, port_value: 80 }
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" }
route: { cluster: service_cluster }
http_filters:
- name: envoy.filters.http.router
clusters:
- name: service_cluster
type: STRICT_DNS
lb_policy: LEAST_REQUEST
load_assignment:
cluster_name: service_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: { address: service.default.svc.cluster.local, port_value: 8080 }
该配置中,Envoy 在 80 端口监听,所有进入的 HTTP 请求经过 HTTP 连接管理器过滤器,匹配 /api 前缀的请求被路由到 service_cluster,该集群通过 DNS 解析获取 Endpoint 列表,并使用最少请求策略进行负载均衡。