envoy部分二: envoy的配置组件
1、envoy启动时从Bootstrap配置文件中加载初始配置。
2、支持静态和动态配置。
静态配置:
纯手工指定配置。
动态配置:
1)xDS API
◆从配置文件加载配置
◆从管理服务器(Management Server )基于xds协议加载配置
2) runtime
◆某些关键特性(Feature flags )保存为key/value 数据
◆支持多层配置和覆盖机制
3、启用全动态配置机制后,仅极少数场景需要重新启动Envoy进程。
支持热重启。
4、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会 话票据, 以及对证 书 验证逻辑的配置(受信任的根证书和撤销机制等 );
1、Bootstrap配置中几个重要的基础概念
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": "{...}", "static_resources": "{...}", "dynamic_resources": "{...}", "cluster_manager": "{...}", "hds_config": "{...}", "flags_path": "...", "stats_sinks": [], "stats_config": "{...}", "stats_flush_interval": "{...}", "stats_flush_on_admin": "...", "watchdog": "{...}", "watchdogs": "{...}", "tracing": "{...}", "layered_runtime": "{...}", "admin": "{...}", "overload_manager": "{...}", "enable_dispatcher_stats": "...", "header_prefix": "...", "stats_server_version_override": "{...}", "use_tcp_for_dns_lookups": "...", "bootstrap_extensions": [], "fatal_actions": [], "default_socket_interface": "..." }
三、侦听器和集群配置基础
1、侦听器 listener
侦听器(Listener
)就是 Envoy 的监听地址,可以是端口或 Unix Socket
。Envoy 在单个进程中支持任意数量的监听器。通常建议每台机器只运行一个 Envoy 实例,每个 Envoy 实例的监听器数量没有限制,这样可以简化操作,统计数据也只有一个来源,比较方便统计。目前 Envoy 支持监听 TCP
协议和 UDP
协议。
TCP
每个监听器都可以配置多个过
除了过滤器链之外,还有一种过滤器叫监听器过滤器(Listener filters),它会在过滤器链之前执行,用于操纵连接的元数据。这样做的目的是,无需更改 Envoy 的核心代码就可以方便地集成更多功能。例如,当监听的地址协议是 UDP
时,就可以指定 UDP 监听器过滤器。
UDP
Envoy 的监听器也支持 UDP
协议,需要在监听器过滤器中指定一种 UDP 监听器过滤器(UDP listener filters)。目前有两种 UDP 监听器过滤器:UDP 代理(UDP proxy) 和 DNS 过滤器(DNSfilter)。UDP 监听器过滤器会被每个 worker
线程实例化,且全局生效。实际上,UDP 监听器(UDP Listener)配置了内核参数 SO_REUSEPORT
,这样内核就会将 UDP 四元组相同的数据散列到同一个 worker
线程上。因此,UDP 监听器过滤器是允许面向会话(session)的。
每个侦听器可以包含多个L3/L4的过滤器,并对其进行独立配置。
1)侦听器收到的连接请求将由其过滤器链中的各过滤器进行处理; 2)Envoy侦听器构架支持大多数的不同proxy的任务。 如: rate limiting TLS client authentication HTTP connection management raw TCP proxy ......
侦听器(Listener
)功能:
2)代理类的过滤器负责路由请求,例如tcp_proxy和http_connection_manager等
监听器的配置结构如下:
{ "name": "...", "address": "{...}", "filter_chains": [], "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": [] } name : 监听器名称。默认情况下,监听器名称的最大长度限制为 60 个字符。可以通过 --max-obj-name-len 命令行参数设置为所需的最大长度限制。 address : 监听器的监听地址,支持网络 Socket 和 Unix Domain Socket(UDS) 两种类型。 filter_chains : 过滤器链的配置。 per_connection_buffer_limit_bytes : 监听器每个新连接读取和写入缓冲区大小的软限制。默认值是 1MB。 listener_filters : 监听器过滤器在过滤器链之前执行,用于操纵连接的元数据。这样做的目的是,无需更改 Envoy 的核心代码就可以方便地集成更多功能。例如,当监听的地址协议是 UDP 时,就可以指定 UDP 监听器过滤器。 listener_filters_timeout : 等待所有监听器过滤器完成操作的超时时间。一旦超时就会关闭 Socket,不会创建连接,除非将参数 continue_on_listener_filters_timeout 设为 true。默认超时时间是 15s,如果设为 0 则表示禁用超时功能。 continue_on_listener_filters_timeout : 布尔值。用来决定监听器过滤器处理超时后是否创建连接,默认为 false。 freebind : 布尔值。用来决定是否设置 Socket 的 IP_FREEBIND 选项。如果设置为 true,则允许监听器绑定到本地并不存在的 IP 地址上。默认不设置。 socket_options : 额外的 Socket 选项。 tcp_fast_open_queue_length : 控制 TCP 快速打开(TCP Fast Open,简称 TFO)。TFO 是对TCP 连接的一种简化握手手续的拓展,用于提高两端点间连接的打开速度。它通过握手开始时的 SYN 包中的 TFO cookie(一个 TCP 选项)来验证一个之前连接过的客户端。如果验证成功,它可以在三次握手最终的 ACK 包收到之前就开始发送数据,这样便跳过了一个绕路的行为,更在传输开始时就降低了延迟。该字段用来限制 TFO cookie 队列的长度,如果设为 0,则表示关闭 TFO。 traffic_direction : 定义流量的预期流向。有三个选项:UNSPECIFIED、INBOUND 和 OUTBOUND,分别代表未定义、入站流量和出站流量,默认是 UNSPECIFIED。 udp_listener_config : 如果 address 字段的类型是网络 Socket,且协议是 UDP,则使用该字段来指定 UDP 监听器。 connection_balance_config : 监听器连接的负载均衡配置,目前只支持 TCP。 reuse_port : 布尔值。用来决定是否设置 Socket 的 SO_REUSEPORT 选项。如果设置为 true,则会为每一个 worker 线程创建一个 Socket,在有大量连接的情况下,入站连接会均匀分布到各个 worker 线程中。如果设置为 false,所有的 worker 线程共享同一个 Socket。 access_log : 日志相关的配置。
◼ 一组上游主机的逻辑组合
◼ 每个主机映射为集群中的一个端点
◼ 下游的请求被调度至上游主机
1) Envoy可配置任意数量的上游集群,并使用Cluster Manager进行管理。
(1)由集群管理器负责管理的各集群可以由用户静态配置,也可借助于CDS API动态获取; (2)集群中的每个成员由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字段中指定使用自定义集群发现机制;
3) Envoy Cluster支持纯静态定义方式来指 定端点,也允许以动态方式发现各端点, 甚至还支持自定义的发现机制。
4) 支持用户定义多种高级功能,例如,负 载均衡策略、主动健康状态检查、被动 健康状态检查和断路器等。
{ "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": "...", "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 进程中运行着一系列 Inbound/Outbound
监听器(Listener),Inbound
代理入站流量,Outbound
代理出站流量。Listener 的核心就是过滤器链(FilterChain),链中每个过滤器都能够控制流量的处理流程。过滤器链中的过滤器分为两个类别:
-
网络过滤器(Network Filters): 工作在
L3/L4
,是 Envoy 网络连接处理的核心,处理的是原始字节,分为Read
、Write
和Read/Write
三类。 -
HTTP 过滤器(HTTP Filters): 工作在
L7
,由特殊的网络过滤器HTTP connection manager
管理,专门处理HTTP1/HTTP2/gRPC
请求。它将原始字节转换成HTTP
格式,从而可以对HTTP
协议进行精确控制。
除了 HTTP connection manager
之外,还有一种特别的网络过滤器叫 Thrift Proxy
。Thrift
是一套包含序列化功能和支持服务通信的 RPC 框架。Thrift Proxy 管理了两个 Filter:
除了过滤器链之外,还有一种过滤器叫监听器过滤器(Listener Filters),它会在过滤器链之前执行,用于操纵连接的元数据。这样做的目的是,无需更改 Envoy 的核心代码就可以方便地集成更多功能。例如,当监听的地址协议是 UDP
时,就可以指定 UDP 监听器过滤器。
1、网络级(L3/L4)过滤器构成了Envoy连接处理的核心
1)过滤器API允许将不同的过滤器集混合、匹配并附加到给定的侦听器。 2)有三种不同类型的网络过滤器: Read:当Envoy从下游连接接收数据时,读取过滤器被调用。 Write:当Envoy正要将数据发送到下游连接时,会调用Write filter。 Read/Write:当Envoy从下游连接接收数据和将要向下游连接发送数据时,会调用读/写过滤器。 3)网络级过滤器的API相对简单,因为最终过滤器只操作原始字节和少量连接事件。 4)链中的过滤器可能会停止,随后继续迭代进一步筛选。
2、网络过滤器访问和操作L4连接上的原始数据,即TCP数据包
例如,TCP代理过滤器将客户端连接数据路由到上游主机,并生成连接统计信息等
3、Enovy内置了许多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 等;
4、HTTP connection manager
(1)HTTP connection manager自身是L3/L4 过路器,它能够将原始字节转换为HTTP级别消息 和事件(例如,headers和body等) (2)它还处理所有HTTP连接和请求共有的功能,例如访问日志记录、请求ID生成和跟踪、 请求/响应头操作、路由表管理和统计信息等; (3)与L3/L4过滤器堆栈相似,Envoy还支持在HTTP连接管理器中使用HTTP级过滤器堆栈; HTTP过滤器在L7运行,它们访问和操作HTTP请求和响应;例如,gRPC-JSON Transcoder Filter为gRPC后端公开REST API,并将请求和响应转换为相应的格式; 常用的HTTP过路器有Router、Rate limit 、Health check 、Gzip和Fault Injection等。
Envoy使用单进程/多线程的架构模型,一个主线程 (Main thread)负责实现各类管理任务,而一些工作线 程(Worker threads)则负责执行监听、过滤和转发等代 理服务器的核心功能。
主线程:负责Envoy程序的启动和关闭、xDS API调用处 理(包括DNS、健康状态检测和集群管理等)、运行时配 置、统计数据刷新、管理接口维护和其它线程管理(信号 和热重启等)等,相关的所有事件均以异步非阻塞模式完成. 工作线程:默认情况下,Envoy根据当前主机CPU核心数 来创建等同数量的工作线程,不过,管理员也可以通过程 序选项--concurrency具体指定;每个工作线程运行一个非 阻塞型事件循环,负责为每个侦听器监听指定的套接字、接收新请求、为每个连接初始一个过滤器栈并处理此连接 整个生命周期中的所有事件。 文件刷写线程:Envoy写入的每个文件都有一个专用、独 立的阻塞型刷写线程,当工作线程需要写入文件时,数据 实际上被移入内存缓冲区,最终通过文件刷写线程同步至文件中。
六、Envoy连接处理