全部产品

服务网格最佳实践之控制面

更新时间:2020-09-30 10:52:55

Service Mesh 是蚂蚁集团下一代架构的核心,本文主要分享在蚂蚁集团当前的体量下,控制面平稳支撑大规模 Sidecar 的落地实践。主体部分将聚焦控制面核心组件 Pilot 和 Citadel,分享蚂蚁金服双十一控制面如何管理并服务好全站 Sidecar。

本文主要内容为下述几个部分:

Pilot 落地实践

在开始落地实践部分之前,先引入 Istio 的架构图:

Istio架构

  • 出于性能等方面的综合考虑,在落地过程中,蚂蚁团队将控制面的组件精简为 Pilot 和 Citadel 两个组件,不使用因性能问题争议不断的 Mixer,不引入 Galley 来避免多一跳的开销。
  • 在架构图中,控制面组件 Pilot 是与 Sidecar 交互最重要的组件,负责配置转化和下发,直面 Sidecar 规模化带来的挑战。这也是双十一大促中,控制面最大的挑战。

在生产实践中,规模化问题是一个组件走向生产可用级的必经之路。下文会从以下几个方面展开:

稳定性增强

从功能实现上来看,Pilot 提供的服务能力可以总结为:Pilot 是一个 Controller + gRPC Server 的服务,通过 List/Watch 各类 K8S 资源进行整合计算,生成 XDS 协议的下发内容,并提供 gRPC 接口服务。

本文将把关注点放在 gRPC 接口服务这个环节:如何保证接口服务支撑大规模 Sidecar 实例,是规模化的一道难题。

负载均衡

要具备规模化能力,横向扩展能力是基础。蚂蚁团队采用常用的 DNSRR 方案来访问 Pilot,Sidecar 随机访问 Pilot 实例。由于是长连接访问,所以在扩容时,原有的连接没有重连,会造成负载不均。为解决这个问题,蚂蚁团队配合 Sidecar 散列重连逻辑,给 Pilot 增加了下述功能,以避免产生连接风暴。

  • 连接限流
  • 熔断
  • 定期重置

负载均衡.png

  • 连接限流:为了降低大量 MOSN 同时连接同一个 Pilot 实例的风险,在 gRPC 首次连接时,Pilot 增加基于令牌桶方案的流控能力,控制新连接的处理响应,并将等待超时的连接主动断连,等待 Sidecar 下一次重连。
  • 熔断:基于使用场景的压测数据,限制单实例 Pilot 同时可服务的 Sidecar 数量上限,超过熔断值的新连接会被Pilot 主动拒绝。
  • 定期重置:为了实现负载均衡,对于已经存在的旧连接,蚂蚁团队选择让 Pilot 主动断开连接,不过断开连接的周期需要考虑错开大促峰值、退避扩缩容窗口等问题,需要按具体的业务场景来确定。
  • Sidecar 散列重连:该功能涉及 Client 端的配合,让 Sidecar 重连 Pilot 时,采用退避式重试逻辑,避免对 DNS 和 Pilot 造成负载压力。

性能优化

规模化的另一道难题是如何保证服务的性能。在 Pilot 的场景,最受关注的是配置下发的时效性。性能优化离不开细节,其中部分优化是通用的,也有部分优化是面向业务场景定制的,接下来会介绍一下蚂蚁团队优化的一些细节点。

  • 首次请求优化:社区方案里 Pilot 是通过 Pod.Status 来获取 Pod 的 IP 信息,在小集群的测试中,这个时间基本秒级内可以完成。大集群生产环境显示 Status 的更新事件时间较慢,甚至出现超过 10s 以上的情况,而且延迟时间不稳定,会增加 Pilot 首次下发的时延。通过与基础设施 K8s 打通,由 PaaS 侧将 Pod 分配到的 IP 直接标记到Pod.Annotation 上,从而实现在第一次获取 Pod 事件时,就可以获取到 IP,将该环节的时延减少到 0。
  • 按需获取 & Custom Resource 缓存:这是一个面向 DBMesh 业务场景的定制性优化,是基于按需获取的逻辑来实现的。其目的在于解决 DBMesh CR 数量过多、过大导致的性能问题。同时避免 Pilot 由于 List/Watch CR 资源导致 OOM 问题。Pilot 采用按需缓存和过期失效的策略来优化内存占用。
  • 局部推送:社区方案中当 Pilot List/Watch 的资源发生变更时,会触发全部 Sidecar 的配置推送,这种方案在生产环境大规模集群下,性能开销是巨大的。例如:如果单个集群有 10 W 以上的 Pod 数量,任何一个 Pod 的变更事件都会触发全部 Sidecar 的下发,这样的性能开销是不可接受的。
  • 其他优化:强管控能力是大促基本配备,蚂蚁团队给 Pilot Admin API 补充了一些额外能力:支持动态变更推送频率、推送限流、日志级别等功能。

优化的思路也比较简单,如果能够控制下发范围,那就可以将配置下发限制在需要感知变更的 Sidecar 里。为此,蚂蚁团队定义了 ScopeConfig CRD,用于描述各类资源信息与哪些 Pod 相关,这样 Pilot 就可以预先计算出配置变更的影响范围,然后只针对受影响的 Sidecar 推送配置。

监控能力

安全生产的基本要求是具备快速定位和及时止血能力。对于 Pilot 来说,需要关注的核心功能是配置下发能力,该能力有下述几个核心监控指标:

  • 下发时效性:针对下发的时效性,蚂蚁团队在社区的基础上补充完善了部分下发性能指标,如:下发的配置大小分布、下发时延等。
  • 配置准确性:配置准确性的验证是相对比较复杂的,因为配置的准确性需要依赖 Sidecar 和 Pilot 的配置双方进行检验。因此,蚂蚁团队在控制面里引入了 Inspector 组件,用来定位配置巡检,版本扫描等运维相关功能模块。

配置巡检的流程,示例如下:
巡检流程.png

流程说明

  1. Pilot 下发配置时,将配置的摘要信息与配置内容同步下发。
  2. MOSN 接收配置时,缓存新配置的摘要信息,并通过 Admin API 暴露查询接口。
  3. Inspector 基于控制面的 CR 和 Pod 等信息,计算出对应 MOSN 的配置摘要信息,然后请求 MOSN 接口,对比配置摘要信息是否一致。

由于 Sidecar 的数量较大,Inspector 在巡检时,支持基于不同的巡检策略执行巡检。大体可以分为以下几类:

  • 周期性自动巡检,一般使用抽样巡检。
  • SRE 主动触发检查机制。

Citadel 安全方案

证书方案

Sidecar 基于社区 SDS 方案 (Secret Discovery Service),支持证书动态发现和热更新能力。蚂蚁集团是一家金融科技公司,对安全有更高的要求,不使用 Citadel 的证书自签发能力,而是通过对接内部 KMS 系统获取证书,同时提供证书缓存和证书推送更新能力。

证书方案架构图

架构图.png

Sidecar 获取证书的流程,示例如下:

sidecar获取证书流程.png

流程说明

  1. Citadel 与 Citadel Agent (nodeagent) 组件通过 MCP 协议(Mesh Configuration Protocol) 同步 Pod 和 CR 信息,避免 Citadel Agent 直接请求 API Server 所导致的 API Server 负载过高问题。
  2. Citadel Agent 会进行防篡改校验,并提取 appkey。
  3. Citadel Agent 携带 appkey 请求 Citadel 签发证书。
  4. Citadel 检查证书是否已缓存,如无证书,则向 KMS 申请签发证书。
  5. KMS 会将签发的证书响应返回 Citadel,另外 KMS 也支持证书过期轮换通知。
  6. Citadel 收到证书后,会通过步骤 7、8、9 将证书层层传递,最终到达 MOSN。

国密通信

国密通信是基于 TLS 通信实现的,采用更复杂的加密套件来实现安全通信。该功能核心设计是由 Policy 和 Certificate 两部分组成:

  • Pilot 负责 Policy 的下发。
  • Citadel 负责 Certificate 下发 (基于 SDS 证书方案)。

在落地过程中,仅依靠社区的 PERMISSIVE TLS MODE 还不能满足蚂蚁集团可灰度、可监控、可应急的三板斧要求。所以,在社区方案的基础上,引入了 Pod 粒度的 Sidecar 范围选择能力(也是基于 ScopeConfig ),方案示例如下:

国密通信.png

流程如下:

  1. Pilot List/Watch ScopeConfig CRD 和 Policy CRD ,基于 Pod Label 选择 Pod 粒度范围实例。
  2. Provider 端 MOSN 收到 Pilot 下发的国密配置后,通过 SDS 方案获取证书,成功获取证书后,会将服务状态推送至 SOFARegistry。
  3. SOFARegistry 通知 Consumer 端:MOSN 特定 Provider 端已开启国密通信状态,要重新发起建连请求。

MCP 优化

Citadel Agent 通过 Citadel 同步 POD 及 CRD 等信息时,虽然避免了 Node 粒度部署的 Citadel Agent 对 API Server 的压力,但是,使用 MCP 协议同步数据时,蚂蚁团队遇到了下述挑战:

  • 大集群部署时,POD 数量在 10 W 以上时,全量通信时,每次需同步的信息在 100 M 以上,性能开销巨大,网络带宽开销也不可忽视。
  • Pod 和 CR 信息变更频繁,高频的全量推送直接制约了可拓展性,同时效率极低。

为了解决以上问题,就需要对 MCP 实现进行改造。改造的目标很明确:减少同步信息量,降低推送频率。为此,蚂蚁团队强化了社区 MCP 的实现,补充了下述功能:

  • 为 MCP 协议支持增量信息同步模式,性能大幅优于社区原生方案全量 MCP 同步方式。
  • Citadel Agent 是 Node 粒度组件,基于最小信息可见集的想法,Citadel 在同步信息给 Citadel Agent 时,通过 Host IP,Pod 及 CR 上的 Label 筛选出最小集,仅推送每个 Citadel Agent 自身服务范围的信息。
  • 基于 Pod 和 CR 的变更事件,可以预先知道需要推送给哪些 Citadel Agent 实例,只对感知变更的 Citadel Agent 触发推送事件,即支持局部推送能力。

未来思考

本次大促,控制面的重心在于解决规模化问题,后续控制面将会在下述领域深入探索:

  • 服务发现
  • 精细化路由
  • Policy As Code

蚂蚁团队将与社区深度合作,控制面将支持通过 MCP 对接多种注册中心,例如 SOFARegistry(已开源), Nacos等,并实现下述功能:

  • 服务发现信息同步
  • 大规模服务注册发现
  • 增量推送大量 endpoint

同时控制面还能通过增强配置下发能力,为应用启动提速,将在 Serverless 极速启动场景获取技术红利。控制面还将结合 Policy As Code,具备极简建站,默认安全等能力,未来极具想象空间。