4. Envoy 代理基础与配置

在 Service Mesh 中,Envoy 是数据面的核心代理。无论是 Istio 的 sidecar 模式,还是独立部署的边缘代理,流量最终都要经过 Envoy 完成转发、路由、负载均衡、熔断和可观测性采集。理解 Envoy 的配置模型,是掌握云原生流量治理的关键一步。本节从 Envoy 的核心概念出发,逐步展开监听器、集群、路由三大配置支柱,并通过静态配置与动态配置的对比实战,帮助读者建立完整的配置认知。

一、Envoy 的核心概念与配置模型

Envoy 的配置围绕几个核心对象展开:Listener(监听器)负责在指定地址和端口上接收连接;Cluster(集群)定义一组逻辑上等价的上游主机,并承载负载均衡、健康检查等策略;Route(路由)决定请求如何从监听器匹配到具体集群;Filter(过滤器)则在连接或请求处理链中插入具体能力,如 HTTP 连接管理、限流、鉴权等。这些对象通过 Bootstrap 引导配置串联起来,形成一棵从入口到出口的配置树。

Envoy 的配置分为静态配置和动态配置两类。静态配置在启动时一次性加载,适合结构稳定、变更不频繁的场景;动态配置通过 xDS 协议从控制面(如 Istio 的 Pilot、自研的 xDS Server)实时下发,支持监听器、集群、路由、端点等资源的增量更新,是 Service Mesh 实现动态流量治理的基础。

Envoy 配置模型:从监听器到集群的流量路径 客户端 Client TCP/HTTP Listener 监听器 0.0.0.0:8080 HTTP Connection Manager Filter Chain Filter Chain 过滤器链 CORS / JWT / RateLimit Router Filter (最后执行) Route 路由 /api/v1 → cluster_a /api/v2 → cluster_b / → cluster_default Cluster 集群 LB: Round Robin Health Check Endpoints: 3 上游主机 1 10.0.0.1:8080 上游主机 2 10.0.0.2:8080 上游主机 3 10.0.0.3:8080 xDS 控制面(动态配置) LDS(监听器) · RDS(路由) · CDS(集群) · EDS(端点) 通过 gRPC 流式推送增量更新 支持 ACK/NACK 确认机制 LDS RDS CDS/EDS 静态配置 Bootstrap YAML 启动时加载 变更需重启 适合稳定拓扑 图例: 监听器 过滤器链 路由 集群 xDS 控制面 动态下发 端点连接

二、监听器:流量的入口

监听器是 Envoy 接收流量的第一站。一个监听器至少包含监听地址、端口、协议类型和过滤器链。在 HTTP 场景中,通常使用 envoy.filters.network.http_connection_manager 作为网络过滤器,它负责解析 HTTP 协议、执行路由匹配,并将请求交给后续的 HTTP 过滤器链。

下面是一个静态配置中的监听器示例,监听 0.0.0.0:8080,并将所有请求交给名为 local_route 的路由配置:

static_resources:
  listeners:
  - name: main_listener
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 8080
    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_cluster }
          http_filters:
          - name: envoy.filters.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

这里的关键点在于:route_config 可以直接内联在监听器中(静态路由),也可以通过 rds 字段引用外部路由配置(动态路由)。当使用 RDS 时,监听器只保留一个占位配置,实际路由规则由控制面动态推送。

三、集群:上游主机的逻辑分组

集群定义了一组提供相同服务的上游主机。Envoy 支持多种服务发现方式:静态 IP 列表、DNS 解析、以及通过 EDS 动态获取端点。集群配置中最重要的参数包括负载均衡算法、健康检查、连接池和熔断阈值。

以下是一个静态集群配置示例,使用轮询负载均衡,并配置了主动健康检查:

clusters:
- name: service_cluster
  connect_timeout: 2s
  type: STATIC
  lb_policy: ROUND_ROBIN
  load_assignment:
    cluster_name: service_cluster
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: 10.0.0.1
              port_value: 8080
      - endpoint:
          address:
            socket_address:
              address: 10.0.0.2
              port_value: 8080
  health_checks:
  - timeout: 1s
    interval: 5s
    unhealthy_threshold: 2
    healthy_threshold: 2
    http_health_check:
      path: /healthz

当 type 设为 STATIC 时,端点列表固定不变;若设为 EDS,则端点由控制面通过 EDS 协议动态推送,适合 Pod IP 频繁变化的 Kubernetes 环境。健康检查的 unhealthy_threshold 和 healthy_threshold 决定了主机状态切换的灵敏度,生产环境中需要根据服务特性调整。

四、路由:请求到集群的匹配规则

路由配置决定了请求如何被匹配并转发到目标集群。Envoy 的路由匹配支持前缀、精确路径、正则表达式、请求头、查询参数等多种条件。匹配顺序从上到下,第一个命中的路由生效。路由还可以配置重定向、重写、超时、重试等策略。

一个典型的路由配置如下,将 /api/v1 前缀的请求转发到 v1_cluster,其余请求转发到 default_cluster:

route_config:
  name: local_route
  virtual_hosts:
  - name: backend
    domains: ["*"]
    routes:
    - match:
        prefix: "/api/v1"
      route:
        cluster: v1_cluster
        timeout: 3s
        retry_policy:
          retry_on: "5xx"
          num_retries: 2
    - match:
        prefix: "/"
      route:
        cluster: default_cluster

注意 domains 字段用于匹配 Host 头,"*" 表示匹配所有域名。在生产环境中,通常会根据域名或路径前缀划分不同的虚拟主机,实现多租户或灰度发布。

五、静态配置与动态配置的对比实战

静态配置适合快速验证和稳定拓扑,动态配置适合频繁变更的云原生环境。两者的核心差异在于:静态配置在启动时加载,变更需要重启 Envoy;动态配置通过 xDS 协议实时推送,支持增量更新和 ACK/NACK 确认机制。

对比维度 静态配置 动态配置(xDS)
加载时机 启动时一次性加载 运行时按需推送
变更方式 修改 YAML 后重启 控制面推送增量更新
适用场景 固定拓扑、边缘代理 Kubernetes、Service Mesh
端点发现 STATIC / DNS EDS 动态端点
配置一致性 人工保证 控制面统一管理

在实际操作中,可以先使用静态配置验证 Envoy 的基本转发能力,再逐步迁移到动态配置。例如,在 Kubernetes 中部署 Istio 时,Envoy sidecar 的 Bootstrap 配置只包含最小化的静态部分(如 xDS 服务器地址、节点元数据),其余监听器、集群、路由全部由 Pilot 动态下发。这种设计使得 Envoy 可以快速启动,并在控制面就绪后立即获取完整配置。

实践建议:调试 Envoy 配置时,可以使用 envoy --mode validate -c config.yaml 验证静态配置的语法正确性。对于动态配置,可以通过 Envoy 的管理接口 /config_dump 查看当前生效的完整配置,通过 /clusters 查看集群健康状态,通过 /stats 观察请求计数和延迟分布。