Kubernetes - Envoy
Kubernetes
Kubernetes 主要基于
Kernel技术栈,缺少精细化的高级流量治理
- Kubernetes 已有的流量治理能力:Service + Ingress
- Service 在 L4,基于 Kernel 技术栈,无法实现精细化的高级流量管理
- Ingress 在 L7,主要针对入站流量
架构演进
单体
访问服务
微服务
业务代码一般会集成统一的 SDK,耦合了很多平台侧的能力
Service Mesh
Sidecar
Service Instance 与 Sidecar Proxy 在同一个
Network Namespace,相当于一个 loopback,可以明文传输
能力下沉
通过
Sidecar来实现微服务治理,业务部门更聚焦于业务逻辑
Istio
特性
HTTP、gRPC、WebSocket、TCP的自动负载均衡- 通过丰富的
路由规则实现重试、故障转移、故障注入,可以对流量行为进行细粒度控制 可插入的策略层和配置 API,支持访问控制、速率限制和配额- 对出入集群
入口和出口中的所有流量的自动度量指标、日志记录和跟踪 - 通过强大的
基于身份的验证和授权,在集群中实现安全的服务间通信
功能
一套模型统一:入站流量 + 东西向流量 + 出站流量
Istio 同时支持 Kubernetes 的
Ingress和Service API
如果将IngressClass设置为 Istio,则 Istio 将充当Ingress Controller的角色
流量
- 连接
- 通过简单的规则配置和流量路由,可以控制服务之间的流量和 API 调用
- 简化了
断路器、超时、重试等服务级别属性的配置 - 可以轻松设置 A/B 测试、金丝雀部署、基于百分比的流量分割等任务
- 控制
- 通过更好地了解流量和
开箱即用的故障恢复功能,可以在问题出现之前先发现问题,使调用更可靠 - 如支持
熔断和降级
- 通过更好地了解流量和
安全
- Istio 提供
底层安全通信信道,并大规模管理服务通信的认证、授权和加密 - 在 Istio 中,服务通信在默认情况下都是安全的,允许
跨多种协议和运行时实施一致的安全策略 - Istio 与
Kubernetes 网络策略结合,在网络层和应用层保护Pod 间或者服务间的通信Kubernetes 网络策略在L4,基于 Kernel 技术栈Istio在L7,实现更精细的流量控制
可观测性
监控服务的
SLO(Service Level Objective)
Metrics- Istio 基于
延迟、流量、错误、饱和生成一系列的服务指标 - Istio 为
网格控制平面提供更详细的指标,以及基于这些指标的仪表盘
- Istio 基于
Traces- 为每个服务生成分布式追踪
Span
- 为每个服务生成分布式追踪
Logs- 当流量进入网格中的服务时,Istio 可以生成每个请求的完整记录
架构
因
过度设计而导致运维(问题排查+版本升级)负担重,从微服务架构回归单体架构
| Plane | Desc |
|---|---|
| Data plane | 由一组以 Sidecar 方式部署的代理组成代理可以调节和控制 微服务之间以及微服务与 Mixer 之间所有的网络通信 |
| Control plane | 配置代理来路由流量配置 Mixer 来实施策略和收集遥测数据 |
- Istio 的数据面为 Envoy
- Istio 监听 API Server,主要关注 Kubernetes Service Endpoint 和 Istio CRD
- 将配置信息(
Istio CRD)和状态信息(Kubernetes Service Endpoint)整合成 Envoy 配置 - 然后
下发给 Envoy
- 将配置信息(
- Envoy 是类似于 Nginx 的
反向代理- 加载配置文件后,监听在某个端口,接收并转发请求
设计目标
最大化透明度
- Istio 将自身
自动注入到服务间所有的网络路径中 - Istio 使用
Sidecar来捕获流量,并且尽可能地自动编程网络层来路由流量,对应用无侵入 - 在 Kubernetes 中,
代理被注入到Pod中,通过编写iptables来捕获流量 - 所有组件和 API 在设计时必须考虑
性能和规模
增量
- 只推送
增量策略 - 预计最大的需求为
扩展策略系统集成其它策略和控制来源- 将网格行为信息
传播到其它系统进行分析
策略运行时支持标准扩展机制以便插入到其它服务中
可移植性
- 基于 Istio 的服务的移植成本很低
- 使用 Istio 将同一个服务同时部署到多个环境中
策略一致性
- 通过一套模型
统一所有流量 策略系统作为独立服务,具有自身的 API,并非将其放到 Sidecar 中
Envoy
L7 Proxy
计算选型:能力 -> 性能 -> 稳定性
| Envoy | Nginx | HA Proxy | |
|---|---|---|---|
| HTTP/2 | 完整支持 HTTP/2同时支持 upstream 和 downstream HTTP/2 |
从 1.9.5 开始有限支持 HTTP/2 支持 upstream HTTP/2 仅支持 downstream HTTP/1.1 |
- |
| Rate Limit | 通过插件支持 |
支持基于配置的限流只支持基于源 IP 的限流 |
|
| ACL | 基于插件实现 L4 ACL |
基于源/目标地址实现 ACL |
|
| Connection Draining | 支持 hot reload通过 share memory 实现 connection draining |
Nginx Plus 收费版本支持 | 支持热启动 不保证连接不丢失 |
- 当反向代理重启时,已经存在的连接是不能丢弃的
- 新 Envoy 进程启动时,老 Envoy 进程依然存活
- 新接收的请求会通过
Socket 复制,让新 Envoy 进程去处理 - 本身还在处理的旧请求,会争取在限定时间内处理完
- 新接收的请求会通过
- 当老的 Envoy 进程退出后,新的 Envoy 进程会继续监听端口
配置变更后,反向代理一般都需要重启才能使得配置生效
而Nginx和HA Proxy都不保证Connection Draining
优势
性能- 在具备
大量特性的同时,Envoy 提供了极高的吞吐量和低尾部延迟差异,而 CPU 和 Memory消耗相对较少
- 在具备
可扩展性- 在
L4和L7都同时提供了丰富的可插拔过滤器的能力
- 在
API 可配置性- 核心竞争力(监听端口,接收配置,配置热加载,无需重启)- Envoy 提供了一组可以通过
控制平面服务实现的管理 API - 如果控制平面实现所有的管理 API,则可以使用
通用引导配置在整个基础架构上运行 Envoy 配置更改可以通过管理服务器以无缝方式动态传送,因此 Envoy不需要重新启动- 所以 Envoy 可以成为
通用数据平面,当其与一个足够复杂的控制平面相结合时,会极大地降低整体运维的复杂性
- Envoy 提供了一组可以通过
线程模式
- Envoy 采用
单进程多线程模型主线程负责协调子线程负责监听过滤和转发
- 当某个连接被监听器
接受,那么该连接的全部生命周期会与某线程绑定- 例如
长连接的情况,绑定的好处就是可以实现无锁操作
- 例如
- Envoy 基于
同步非阻塞模式(epoll) - 建议 Envoy 配置的
Worker 数与 Envoy 所在的硬件线程数一致
架构
XDS API 基于
gRPC协议Envoy 启动时会基于一个静态配置文件,表明需要哪些管理服务器来管理 Envoy 的配置
- Envoy 会尝试连接管理服务器,连接建立后,管理服务器会通过 XDS API 下发 Envoy 配置
Envoy 配置 - 即常规反向代理的配置 - 都有对应的
发现机制 - 配置从哪里来ListenerManager -
LDS- 明确监听端口
RouteConfigProvider -
RDS- 提供路由信息或者转发规则,路径 A 对应 SVC_A,而
SVC在 Envoy 中为Cluster
- 提供路由信息或者转发规则,路径 A 对应 SVC_A,而
ClusterManager -
CDS- 记录 host / ip / endpoint 信息 - 来自于 SVC,相当于一个 VIP
TLS - Thread Local Slot
- Worker 线程的 TLS 来自于主线程的 TLS
- 当处理新请求时,Worker 线程将采用由主线程
最新推送下来的 TLS 数据
ConnectionHandler 实际处理网络数据,libevent 是基于 epoll 的框架
发现机制
Istio 配置信息:监听某个端口,且有对应的路由规则列表,Route 匹配 Cluster
1 | - Listener Discovery Service |
Kubernetes 状态信息:Cluster 可以简单对应为 KubernetesService
1 | - Cluster Discovery Service |
- Secret Discovery Service
- 如果监听端口走 HTTPS 协议,通过 SDS 获取密钥对
- Istio 默认去 Kubernetes Service 发现
- Health Discovery Service - Istio 未使用
- 反向代理一般需要对 upstream 进行探活,如果反向代理副本数很多,探活可能会给应用带来很大压力
- 可以
委托其中一个反向代理实例去执行探活,其余实例基于 HDS 获取探活结果
- Aggregated Discovery Service
- 其它 XDS 之间是有
依赖关系的,因此可以聚合好才一起下发 - 一般是除了 EDS(变更频繁,增量),其余的 XDS 聚合在一起,通过 ADS 下发
- 其它 XDS 之间是有
过滤器模式
不支持正则
- TLSInspector - TLS server name
indication- 一个 Envoy Pod 监听在某个端口,但可能承载了很多域名,不同的域名签出的证书是不一样的
- 客户端在做 TLS 握手的时候,需要携带
FQDN,TLSInspector 再去匹配对应域名的证书
- HTTP Filter
- Mixer - 限流
- Router - 路由转发
- VirtualHost - 域名匹配
- 路由匹配成功后,会转发到对应的 Cluster,即 SVC,进而对应不同的 Endpoint
实践
Upstream
1 | apiVersion: apps/v1 |
Envoy
Config
1 | admin: |
- admin 部分为 Envoy 的标准配置,代表管理端口
- static_resources 与 XDS 发现机制无关,属于静态配置
- listeners 与 clusters 位于同一层级
- listeners.address.socket_address 代表监听的端口地址
- listeners.filter_chains.filters.typed_config.route_config 为具体的路由配置
- 匹配任何域名,前缀为
/时,路由到 some_service
- 匹配任何域名,前缀为
- some_service 基于 LOGICAL_DNS,即会解析 Kubernetes Service,实际的 Endpoint 为 simple:80
Proxy
1 | apiVersion: apps/v1 |





















