关联资料,https://zhaojiew10.github.io/neonote/istio_in_action/3Envoy Proxy详解.html
Envoy是一款为大型现代面向服务架构设计的七层代理与通信总线。该项目的诞生源于以下核心理念:
- 网络应对应用保持透明性
- 当网络和应用出现问题时,应能便捷定位问题根源
Envoy的显著特性包括性能、可扩展性及动态可配置性
- 性能:除了大量功能外,Envoy还提供极高的吞吐量和低尾延迟差异,同时消耗相对较少的CPU和 RAM
- 可扩展性:Envoy在L4和L7上提供丰富的可插拔过滤器功能,允许用户轻松添加新功能;
- API可配置性:Envoy提供了一组可由控制平面服务实现的管理API,也称为xDS API 。若控制平面实现了这所有的API,则可以使用通用引导配置在整个基础架构中运行Envoy,所有进一步的配置更改都可通过管理服务器无缝地进行动态传递,使得Envoy永远不需要重新启动。当与足够复杂的控制平面相结合时,可大大降低整体操作复杂性
Envoy已成为现代服务网格和边缘网关的通用数据平面API,Istio、Ambassador和 Gloo等项目均是为此数据平面代理提供的控制平面
Envoy组件
Envoy组件列表如下
- 主机(Host):一个具有网络通信能力的端点,例如服务器、移动智能设备等
- 集群(Cluster):集群是Envoy连接到的一组逻辑上相似的端点;在v2中,RDS通过路由指向集群,CDS提供集群 配置,而Envoy通过EDS发现集群成员,即端点;
- 下游(Downstream):下游主机连接到Envoy,发送请求并接收响应,它们是Envoy的客户端;
- 上游(Upstream):上游主机接收来自Envoy的连接和请求并返回响应,它们是Envoy代理的后端服务器;
- 端点(Endpoint):端点即上游主机,是一个或多个集群的成员,可通过EDS发现;
- 侦听器(Listener):侦听器是能够由下游客户端连接的命名网络位置,例如端口或unix域套接字等;
- 位置(Locality):上游端点运行的区域拓扑,包括地域、区域和子区域等;
- 管理服务器(Management Server):实现v2 API的服务器,它支持复制和分片,并且能够在不同的物理机器上实现针对不同xDS API的API服务;
- 地域(Region):区域所属地理位置;
- 区域(Zone):AWS中的可用区(AZ)或GCP中的区域等;
- 子区域:Envoy实例或端点运行的区域内的位置,用于支持区域内的多个负载均衡目标;
- xDS:CDS 、EDS、HDS 、LDS、RLS(Rate Limit)、 RDS 、 SDS、VHDS和RTDS等API的统称;
Envoy的架构支持非常灵活的配置方式,简单部署场景可以使用纯静态配置,而更复杂的部署场景则可以逐步添加需要的动态配置机制;
- 纯静态配置:用户自行提供侦听器、过滤器链、集群及HTTP路由(http代理场景),上游端点的发现仅可通过DNS服务进行,且配置的重新加载必须通过内置的热重启(hot restart)完成;
- 仅使用EDS:EDS提供的端点发现功能可有效规避DNS的限制(响应中的最大记录数等);
- 用EDS和CDS:CDS能够让Envoy以优雅的方式添加、更新和删除上游集群。于是初始配置时,Envoy无须事先了解所有上游集群;
- EDS、CDS和RDS:动态发现路由配置;RDS与EDS、CDS一起使用时,为用户提供了构建复杂路由拓扑的能力(流量转移、蓝/绿部署等);
- EDS、CDS、RDS和LDS:动态发现侦听器配置,包括内嵌的过滤器链;启用此四种发现服务后,除了较罕见的配置变动、证书轮替或更新Envoy程序之外,几乎无须再热重启Envoy;
- EDS、CDS、RDS、LDS和SDS:动态发现侦听器密钥相关的证书、私钥及TLS会话票据,以及对证书验证逻辑的配置(受信任的根证书和撤销机制等);
Envoy配置中几个重要的基础概念
- node:节点标识,以呈现给管理服务器并且例如用于标识目的;
- static_resources:静态配置的资源,用于配置静态的listener、cluster和 secret;
- dynamic_resources:动态配置的资源,用于配置基于xDS API获取listener、 cluster和secret配置的lds_config、cds_config和ads_config;
- admin:Envoy内置的管理接口;
- tracing:分布式跟踪;
- layered_runtime:层级化的运行时,支持使用RTDS从管理服务器动态加 载;
- hds_config:使用HDS从管理服务器加载上游主机健康状态检测相关的配 置;
- overload_manager:过载管理器;
- stats_sinks:统计信息接收器;
如下是Node核心配置段,用于标识 Envoy 实例自身的身份、部署位置、版本特征、支持能力等元数据,是 Envoy 与 xDS 管理服务器交互时的核心身份标识配置
yaml
node:
id: ... # Envoy节点的唯一透明标识(无业务语义,仅用于实例区分)
cluster: ... # 定义Envoy运行所在的本地服务集群名称
metadata: {...} # 扩展节点标识的透明元数据,Envoy会将该数据直接传递至管理服务器
locality: # 指定Envoy实例的部署地域信息
region: ... # 部署大区/地域
zone: ... # 部署可用区
sub_zone: ... # 部署子可用区
user_agent_name: ... # 标识配置请求发起方的自定义字符串,示例:"Envoy" 或 "grpc"
user_agent_version: ... # 标识配置请求发起方版本的自定义字符串,示例:"1.12.2"、"abcd1234" 或 "SpecialEnvoyBuild"
user_agent_build_version: # 配置请求发起方的结构化版本信息(标准化的版本定义)
version: ... # 结构化版本号
metadata: {...} # 结构化版本的扩展元数据
extensions: [ ] # 该Envoy节点所支持的扩展插件及其对应版本的列表
client_features: [ ] # Envoy客户端支持的功能特性列表(向管理服务器声明自身能力)
listening_addresses: [ ] # 节点上已配置的监听地址/端口列表,作为提示提供给管理服务器,用于过滤需返回的监听器配置
xDS协议
xDS协议是Envoy动态获取配置的传输协议,也是Istio与Envoy连接的桥梁。Envoy通过文件系统或者查询一个或者多个管理服务器来动态获取配置,也被称为Data Plane API
xDS是一类发现服务的总称,包含LDS、RDS、CDS、EDS及SDS
- LDS:Listener发现服务。Listener监听器控制Envoy启动端口监听(目前只支持TCP),并配置L3或L4层过滤器,在网络连接到达后,由网络过滤器堆栈开始处理
- RDS:Route发现服务,用于 Envoy HTTP连接管理器动态获取路由配置
- CDS:Cluster发现服务,用于动态获取Cluster信息
- EDS:Endpoint发现服务。在Envoy术语中,Cluster成员叫作Endpoint,对于每个Cluster,Envoy都通过EDS API动态获取Endpoint
- SDS:Secret发现服务,用于在运行时动态获取TLS证书
Envoy支持如下类型的配置信息的动态发现机制,相关的发现服务及其相应的API联合起来称为xDS API;
- 基于文件系统发现:指定要监视的文件系统路径
- 通过查询一到多个管理服务器(Management Server)发现:通过DiscoveryRequest协议报文发送请求,并要求服务方以DiscoveryResponse协议报文进行响应
- gRPC服务:启动gRPC流
- REST服务:轮询REST-JSON URL

配置源(ConfigSource)用于指定资源配置数据的来源,用于为Listener、Cluster、Route、 Endpoint、Secret和VirtualHost等资源提供配置数据;
-
目前,Envoy支持的资源配置源只能是path、api_config_source或ads其中之一;
-
api_config_source或ads的数据来自于xDS API Server,即Management Server
基于filesystem的订阅示例
为Envoy提供动态配置的最简单方法是将其放置在ConfigSource中显式指定的文件路径中
Envoy将使用inotify(Mac OS X上的kqueue)来监视文件的更改,并在更新时解析文件中的 DiscoveryResponse报文
- 二进制protobufs,JSON,YAML和proto文本都是DiscoveryResponse所支持的数据格式
- 除了统计计数器和日志以外,没有任何机制可用于文件系统订阅ACK/NACK更新
- 若配置更新被拒绝,xDS API的最后一个有效配置将继续适用
eds配置示例文件/etc/envoy/eds.yaml
yaml
resources:
- "@type": type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment
cluster_name: webcluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 172.31.11.11
port_value: 80
yaml
node:
id: envoy_front_proxy
cluster: MageEdu_Cluster
admin:
profile_path: /tmp/envoy.prof
access_log_path: /tmp/admin_access.log
address:
socket_address:
address: 0.0.0.0
port_value: 9901
dynamic_resources:
lds_config:
path: /etc/envoy/conf.d/lds.yaml
cds_config:
path: /etc/envoy/conf.d/cds.yaml
完整的xDS流程
完整的xDS流程包含三个步骤:请求、响应、ACK或者NACK
- Envoy主动向Pilot发起DiscoveryRequest类型的请求。
- Pilot根据请求生成相应的DiscoveryResponse类型的响应。
- Envoy 接收 DiscoveryResponse,然后动态加载配置,在配置加载成功后进行ACK,否则进行 NACK,ACK或者NACK消息也是以DiscoveryRequest的形式传输的。

一个Management Server实例可能需要同时响应多个不同的Envoy实例的资源发现请求
- Management Server上的配置需要适配到不同的Envoy实例
- Envoy实例请求发现配置时,需要在请求报文中上报自身的信息
Envoy对xDS API的管理由后端服务器实现,包括LDS、CDS、RDS、SRDS(Scoped Route)、VHDS (Virtual Host)、EDS、SDS、RTDS(Runtime)等;
-
所有这些API都提供了最终的一致性,并且彼此间不存在相互影响;
-
部分更高级别的操作(例如执行服务的A/B部署)需要进行排序以防止流量被丢弃,因此,基于一个管理服务器提供多类API时还需要使用聚合发现服务(ADS)API
- ADS API允许所有其他API通过来自单个管理服务器的单个gRPC双向流进行编组,从而允许对操作进行确定性排序;
-
xDS的各API还支持增量传输机制,包括ADS;
对于典型的HTTP路由方案,xDS API的Management Server需要为其客户端(Envoy实例)配置的核心资源类型为Listener、RouteConfiguration、Cluster和ClusterLoadAssignment四个
-
每个Listener资源可以指向一个RouteConfiguration资源,该资源可以指向一个或多个Cluster资源,并且每个Cluster资源可以指向一个ClusterLoadAssignment资源;
-
Envoy实例在启动时请求加载所有Listener和Cluster资源,而后,再获取由这些Listener和Cluster所依赖的RouteConfiguration和ClusterLoadAssignment配置;此种场景中,Listener资源和Cluster资源分别代表着客户端配置树上的"根(root)"配置,因而可并行加载;
-
而类型gRPC类的非代理式客户端可以仅在启动时请求加载其感兴趣的Listener资源,而后再加载这些特定Listener相关的RouteConfiguration资源;再然后,是这些RouteConfiguration资源指向的Cluster资源,以及由这些Cluster资源依赖的ClusterLoadAssignment资源;该种场景中,Listener资源是客户端整个配置树的"根"
Listener和Cluster
Listener和Cluster是最为常用基础配置,无论是以静态或者是动态方式提供

Listener
独立部署时,建议每个主机仅部署单个Envoy实例,并 在必要时于此实例上运行一到多个侦听器;
-
Enovy支持TCP和UDP两种类型的侦听器;
-
侦听器收到的连接请求将由其过滤器链中的各过滤器进行处理;
配置字段如下
json
{
"name": "...",
"address": "{...}",
"stat_prefix": "...",
"filter_chains": [],
"use_original_dst": "{...}",
"default_filter_chain": "{...}",
"per_connection_buffer_limit_bytes": "{...}",
"metadata": "{...}",
"drain_type": "...",
"listener_filters": [],
"listener_filters_timeout": "{...}",
"continue_on_listener_filters_timeout": "...",
"transparent": "{...}",
"freebind": "{...}",
"socket_options": [],
"tcp_fast_open_queue_length": "{...}",
"traffic_direction": "...",
"udp_listener_config": "{...}",
"api_listener": "{...}",
"connection_balance_config": "{...}",
"reuse_port": "...",
"access_log": [],
"tcp_backlog_size": "{...}",
"bind_to_port": "{...}"
}
网络层(L3/L4)过滤器是 Envoy 连接处理的核心组件。网络过滤器分为三种不同类型:
- 读过滤器:当 Envoy 从下游连接接收数据时触发调用。
- 写过滤器:当 Envoy 即将向下游连接发送数据时触发调用。
- 读写过滤器:当 Envoy 从下游连接接收数据时会触发调用(注:原文此处表述不完整,完整逻辑为该类型过滤器在接收和发送下游数据时均会被触发)。
内置 L3/L4 过滤器包括如下
- 代理类:TCP Proxy、HTTP connection manager、Thrift Proxy、Mongo proxy、Dubbo Proxy、 ZooKeeper proxy、MySQL proxy和Redis proxy等
- 其它:Client TLS authentication、Rate limit、Role Based Access Control (RBAC) Network Filter 和Upstream Cluster from SNI等
HTTP connection manager自身是L3/L4过路器,它能够将原始字节转换为HTTP级别消息和事件(例如,headers和body等)
- 它还处理所有HTTP连接和请求共有的功能,例如访问日志记录、请求ID生成和跟踪、 请求/响应头操作、路由表管理和统计信息等;
- 与L3/L4过滤器堆栈相似,Envoy还支持在HTTP连接管理器中使用HTTP级过滤器堆栈
下图是Network (L3/L4) filters and HTTP filters

cluster
Envoy可配置任意数量的上游集群,并使用Cluster Manager进行管理;
- 由集群管理器负责管理的各集群可以由用户静态配置,也可借助于CDS API动态获取;
- 集群中的每个成员由endpoint进行标识,它可由用户静态配置,也可通过EDS或DNS服务动态发现;
- Static:静态配置
- Strict DNS:严格DNS,Envoy将持续和异步地解析指定的DNS目标,并将DNS结果中的返回的每个IP地址视为上游集群中可用成员;
- Logical DNS:逻辑DNS,集群仅使用在需要启动新连接时返回的第一个IP地址,而非严格获取 DNS查询的结果并假设它们构成整个上游集群;适用于必须通过DNS访问的大规模Web服务集群;
- Original destination:当传入连接通过iptables的REDIRECT或TPROXY target或使用代理协议重定向到Envoy时,可以使用原始目标集群;
- Endpoint discovery service (EDS):EDS是一种基于GRPC或REST-JSON API的xDS管理服务器获取集 群成员的服务发现方式;
- Custom cluster:Envoy还支持在集群配置上的cluster_type字段中指定使用自定义集群发现机制;
每个Cluster主要由集群名称,以及集群中的端点(通常是提供服务的IP地址和 端口)所组成
- Envoy Cluster支持纯静态定义方式来指定端点,也允许以动态方式发现各端点, 甚至还支持自定义的发现机制
- 支持用户定义多种高级功能,例如,负 载均衡策略、主动健康状态检查、被动健康状态检查和断路器等;

配置字段如下
json
{
"transport_socket_matches": [],
"name": "...",
"alt_stat_name": "...",
"type": "...",
"cluster_type": "{...}",
"eds_cluster_config": "{...}",
"connect_timeout": "{...}",
"per_connection_buffer_limit_bytes": "{...}",
"lb_policy": "...",
"load_assignment": "{...}",
"health_checks": [],
"max_requests_per_connection": "{...}",
"circuit_breakers": "{...}",
"upstream_http_protocol_options": "{...}",
"common_http_protocol_options": "{...}",
"http_protocol_options": "{...}",
"http2_protocol_options": "{...}",
"typed_extension_protocol_options": "{...}",
"dns_refresh_rate": "{...}",
"dns_failure_refresh_rate": "{...}",
"respect_dns_ttl": "...",
"dns_lookup_family": "...",
"dns_resolvers": [],
"use_tcp_for_dns_lookups": "...",
"outlier_detection": "{...}",
"cleanup_interval": "{...}",
"upstream_bind_config": "{...}",
"lb_subset_config": "{...}",
"ring_hash_lb_config": "{...}",
"maglev_lb_config": "{...}",
"original_dst_lb_config": "{...}",
"least_request_lb_config": "{...}",
"common_lb_config": "{...}",
"transport_socket": "{...}",
"metadata": "{...}",
"protocol_selection": "...",
"upstream_connection_options": "{...}",
"close_connections_on_host_health_failure": "...",
"ignore_health_on_host_removal": "...",
"filters": [],
"track_timeout_budgets": "...",
"upstream_config": "{...}",
"track_cluster_stats": "{...}",
"preconnect_policy": "{...}",
"connection_pool_per_downstream_connection": "..."
}
Envoy通过侦听器监听套接字并接收客户端请求,而Envoy的所有工作线程会同时共同监听用户配置的所有套接字,对于某次连接请求,由内核负责将其派发至某个具体的工作线程处理,随后相关的工作线程基于特定的处理逻辑分别由相关组件依次完成连接管理

管理服务
此外Envoy内建了一个管理服务(administration server),它支持查询和修改操作
yaml
admin:
access_log: [] # 访问日志协议的相关配置,通常需要指定日志过滤器及日志配置等;
access_log_path: ... # 管理接口的访问日志文件路径,无须记录访问日志时使用/dev/null;
profile_path: ... # cpu profiler的输出路径,默认为/var/log/Envoy/Envoy.prof;
address: # 监听的套接字;
socket_address:
protocol: ...
address: ...
port_value: ...
示例配置
yaml
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }

admin接口内置了多个/path,不同的path可能会分别接受不同的GET或POST请求
- GET
/clusters:列出所有已配置的集群,包括每个集群中发现的所有上游主机以及每个主机的统计信 息;支持输出为json格式;- 集群管理器信息:"version_info string",无CDS时,则显示为"version_info::static"
- 集群相关的信息:断路器、异常点检测和用于表示是否通过CDS添加的标识"add_via_api"
- 每个主机的统计信息:包括总连接数、活动连接数、总请求数和主机的健康状态等;不健康的原因通常有以下三种
- failed_active_hc:未通过主动健康状态检测;
- failed_eds_health:被EDS标记为不健康;
- failed_outlier_check:未通过异常检测机制的检查;
- GET
/listeners:列出所有已配置的侦听器,包括侦听器的名称以及监听的地址;支持输出为json格式; - POST
/reset_counters:将所有计数器重围为0;不过,它只会影响Server本地的输出,对于已经发送到 外部存储系统的统计数据无效; - GET
/config_dump:以json格式打印当前从Envoy的各种组件加载的配置信息; - GET
/ready:获取Server就绪与否的状态,LIVE状态为200,否则为503;
部署逻辑
Envoy通常有以下两种部署模式
-
以容器编排系统为底层环境的服务网格中,并以sidecar的形式与主程序容器运行为单个Pod
-
非编排系统环境中测试时,可以将主程序与Envoy运行于同 一容器,或手动组织主程序容器与Envoy容器共享同一网络名称空间;
envoy多平台镜像
- envoy:基于Ubuntu Bionic制作的Docker Image
- envoy-alpine和envoy-alpine-dev:基于alpine制作的Docker Image
- envoy-debug和envoy-debug-dev:基于Ubuntu制作的带有debug环境的Docker Image
- envoy-windows和envoy-windows-dev:基于Windows 1809制作的Docker Image
部署和运行envoy
shell
$ sudo apt update
$ sudo apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common
$ curl -sL 'https://getenvoy.io/gpg' | sudo apt-key add -
$ apt-key fingerprint 6FF974DB | grep "5270 CEAC"
$ sudo add-apt-repository "deb [arch=amd64] https://dl.bintray.com/tetrate/getenvoy-deb $(lsb_release -cs) stable"
$ sudo apt update
$ sudo apt install getenvoy-envoy
启动Envoy时,需要通过"-c"选项为其指定初始配置文件以提供引导配置(Bootstrap configuration)
引导配置是Envoy配置信息的基点,用于承载Envoy的初始配置,它可能包括静态资源和动态资源的定义
-
静态资源(static_resources)于启动直接加载
-
动态资源(dynamic_resources)则需要通过配置的xDS服务获取并生成
-
Listener和Cluster是Envoy得以运行的基础,而二者的配置可以全部为静态格式,也可以混合使用动态及静态方式提供,或者全部配置为动态
纯静态资源配置方式主是直接在配置文件中通过static_resources配置参数明确定义listeners、 clusters和secrets的配置方式
- listeners用于配置纯静态类型的侦听器列表,clusters用于定义可用的集群列表及每个集群的 端点,而可选的secrets用于定义TLS通信中用到数字证书等配置信息
- admin和static_resources两参数即可提供一个最小化的资源配置,甚至admin也可省略
json
{
"listeners": [],
"clusters": [],
"secrets": []
}
动态资源,是指由envoy通过xDS协议发现所需要的各项配置的机制,相关的配置信息保存于称之为**管理服务器(Management Server)**的主机上,经由xDS API向外暴露
json
{
"lds_config": "{...}",
"cds_config": "{...}",
"ads_config": "{...}"
}
使用docker compose启动
yaml
version: '3'
services:
envoy:
image: envoyproxy/envoy:dev
ports:
- "10000:10000"
volumes:
- ./envoy.yaml:/etc/envoy/envoy.yaml
配置示例
Listener简易静态配置
侦听器主要用于定义Envoy监听的用于接收Downstreams请求的套接字、用于处理请求时调 用的过滤器链及相关的其它配置属性
yaml
listeners:
- name:
address:
socket_address: { address: ..., port_value: ..., protocol: ... }
filter_chains:
- filters:
- name:
config:
L4过滤器echo主要用于演示网络过滤器API的功能,它会回显接收到的所有数据至下游的请求者。在配置文件中调用时其名称为envoy.echo
yaml
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 15001
filter_chains:
- filters:
- name: envoy.echo
Cluster简易静态配置
集群代表了一组提供相同服务的上游服务器(端点)的组合,它可由用户静态配置, 也能够通过CDS动态获取
集群需要在"预热"环节完成之后方能转为可用状态,这意味着集群管理器通过DNS解析或 EDS服务完成端点初始化,以及健康状态检测成功之后才可用
yaml
clusters:
- name: ... # 集群的惟一名称,且未提供alt_stat_name时将会被用于统计信息中;
alt_state_name: ... # 统计信息中使用的集群代名称;
type: ... # 用于解析集群(生成集群端点)时使用的服务发现类型,可用值有STATIC、STRICT_DNS、LOGICAL_DNS、ORIGINAL_DST和EDS等;
lb_policy: # 负载均衡算法,支持ROUND_ROBIN、LEAST_REQUEST、RING_HASH、RANDOM、MAGLEV和CLUSTER_PROVIDED;
load_assignment: # 为STATIC、STRICT_DNS或LOGICAL_DNS类型的集群指定成员获取方式;EDS类型的集成要使用eds_cluster_config字段配置;
cluster_name: ... # 集群名称;
endpoints: # 端点列表;
- locality: {} # 标识上游主机所处的位置,通常以region、zone等进行标识;
lb_endpoints: # 属于指定位置的端点列表;
- endpoint_name: ... # 端点的名称;
endpoint: # 端点定义;
socket_adddress: # 端点地址标识;
address: ... # 端点地址;
port_value: ... # 端点端口;
protocol: ... # 协议类型;
静态Cluster的各端点可以在配置中直接给出,也可借助DNS服务进行动态发现
yaml
clusters:
- name: test_cluster
connect_timeout: 0.25s
type: STATIC
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: test_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: { address: 172.17.0.3, port_value: 80 }
- endpoint:
address:
socket_address: { address: 172.17.0.4, port_value: 80 }
(L4 filter)tcp_proxy
TCP代理过滤器在下游客户端及上游集群之间执行1:1网络连接代理
- 它可以单独用作隧道替换,也可以同其他过滤器(如MongoDB过滤器或速率限制过滤器)结合使用;
- TCP代理过滤器严格执行由全局资源管理于为每个上游集群的全局资源管理器设定的连接限制
- TCP代理过滤器检查上游集群的资源管理器是否可以在不超过该集群的最大连接数的情况下创建连接;
- TCP代理过滤器可直接将请求路由至指定的集群,也能够在多个目标集群间基于权重进行调度转发
json
{
"stat_prefix": "...", # 用于统计数据中输出时使用的前缀字符;
"cluster": "...", # 路由到的目标集群标识;
"weighted_clusters": "{...}",
"metadata_match": "{...}",
"idle_timeout": "{...}", # 上下游连接间的超时时长,即没有发送和接收报文的超时时长;
"access_log": [], # 访问日志;
"max_connect_attempts": "{...}" # 最大连接尝试次数;
}
TCP代理配置示例(Front Proxy)
- 基于TCP代理将下游用户(本机)请求代理至后端的两个web服务器
yaml
static_resources:
listeners:
name: listener_0
address:
socket_address: { address: 0.0.0.0, port_value: 80 }
filter_chains:
- filters:
- name: envoy.tcp_proxy
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
stat_prefix: tcp
cluster: local_cluster
clusters:
- name: local_cluster
connect_timeout: 0.25s
type: STATIC
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: local_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: { address: 172.31.0.11, port_value: 8080 }
- endpoint:
address:
socket_address: { address: 172.31.0.12, port_value: 8080 }
(L4 filter)http_connection_manager
http_connection_manager通过引入L7过滤器链实现了对http协议的操纵,其中router过滤器用 于配置路由转发
- 处理请求时,Envoy首先根据下游客户端请求的"host"来搜索虚拟主机列表中各virtual_host中的 domains列表中的定义,第一个匹配到的Domain的定义所属的virtual_host即可处理请求的虚拟主机
- 而后搜索当前虚拟主机中的routes列表中的路由列表中各路由条目的match的定义,第一个匹配到 的match后的路由机制(route、redirect或direct_response)即生效
yaml
listeners:
- name:
address:
socket_address: { address: ..., port_value: ..., protocol: ... }
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: ... # 统计信息中使用的易读性的信息前缀;
route_config: # 静态路由配置;动态配置应该使用rds字段进行指定;
name: ... # 路由配置的名称;
virtual_hosts: # 虚拟主机列表,用于构成路由表;
- name: ... # 虚拟主机的逻辑名称,用于统计信息,与路由无关;
domains: [] # 当前虚拟主机匹配的域名列表,支持使用"*"通配符;匹配搜索次序为精确匹配、前缀通配、后缀通配及完全通配;
routes: [] # 指定的域名下的路由列表,执行时按顺序搜索,第一个匹配到路由信息即为使用的路由机制;
http_filters: # 定义http过滤器链
- name: envoy.filters.http.router # 调用7层的路由过滤器
HTTP L7路由基础配置
route_config.virtual_hosts.routes配置的路由信息用于将下游的客户端请求路由至合适 的上游集群中某Server上
- 路由方式是将url匹配match字段的定义,match字段可通过prefix(前缀)、path(路径)或safe_regex(正则表达式)三者之一来表示匹配模 式;
- 与match相关的请求将由**route(路由规则)、redirect(重定向规则)或direct_response (直接响应)**三个字段其中之一完成路由;
- 由route定义的路由目标必须是cluster(上游集群名称)、cluster_header(根据请求标头中 的cluster_header的值确定目标集群)或weighted_clusters(路由目标有多个集群,每个集群 拥有一定的权重)其中之一
yaml
routes:
- name: ... # 此路由条目的名称;
match:
prefix: ... # 请求的URL的前缀;
route: # 路由条目;
cluster: # 目标下游集群;
route
- 支持cluster、weighted_clusters和cluster_header三者之一 定义目标路由
- 转发期间可根据prefix_rewrite和host_rewrite完成URL重写;
- 可额外配置流量管理机制,例如timeout、retry_policy、 cors、request_mirror_policy和rate_limits等

L7 Front Proxy 代理配置示例
- 定义了两个virtual_host,不过发往第二个virtual_host的请求将被重定向至第一个
yaml
static_resources:
listeners:
- name: listener_0
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
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: web_service_1
domains: ["*.ik8s.io", "ik8s.io"]
routes:
- match: { prefix: "/" }
route: { cluster: local_cluster }
- name: web_service_2
domains: ["*.magedu.com","magedu.com"]
routes:
- match: { prefix: "/" }
redirect:
host_redirect: "www.ik8s.io"
http_filters:
- name: envoy.filters.http.router
L7 Ingress Listener代理配置示例
- 将运行的envoy和demoapp两个应用 的容器设定为共享同一个Network Namespace来模拟Ingress代理的场景
yaml
static_resources:
listeners:
- name: listener_0
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
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: web_service_1
domains: ["*"]
routes:
- match: { prefix: "/" }
route: { cluster: local_cluster }
http_filters:
- name: envoy.filters.http.router
clusters:
- name: local_cluster
connect_timeout: 0.25s
type: STATIC
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: local_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: { address: 127.0.0.1, port_value: 8080 }
L7 Egress Listener代理配置示例
- 运行的envoy和client两个应用的容 器设定为共享同一个Network Namespace来模拟Egress代理的场景
yaml
# Author: MageEdu <mage@magedu.com>
# Site: www.magedu.com
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 127.0.0.1, 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
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: web_service_1
domains: ["*"]
routes:
- match: { prefix: "/" }
route: { cluster: web_cluster }
http_filters:
- name: envoy.filters.http.router
clusters:
- name: web_cluster
connect_timeout: 0.25s
type: STATIC
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: web_cluster
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address: { address: 172.31.4.11, port_value: 80 }
- endpoint:
address:
socket_address: { address: 172.31.4.12, port_value: 80 }