本文为《蚂蚁金服 Service Mesh 大规模落地系列》第七篇 - 控制面篇,该系列将会从核心、RPC、消息、无线网关、控制面、安全、运维、测试等模块对 Service Mesh 双十一大规模落地实践进行详细解析。文末包含往期系列文章。node
Service Mesh 是蚂蚁金服下一代架构的核心,本次主题主要分享在蚂蚁金服当前的体量下,控制面平稳支撑大规模 Sidecar 的落地实践。聚焦控制面核心组件 Pilot 和 Citadel,分享蚂蚁金服双十一控制面如何管理并服务好全站 Sidecar。git
本次分享主要分为两大部分,分别是:github
在开始分享落地实践以前,咱们先来看看 Istio 的架构图:缓存
理想很丰满,现实很骨感。因为性能等方面的综合考虑,咱们在落地过程当中,将控制面的组件精简为 Pilot 和 Citadel 两个组件了,不使用因性能问题争议不断的 Mixer,不引入 Galley 来避免多一跳的开销。安全
在架构图中,控制面组件 Pilot 是与 Sidecar 交互最重要的组件,负责配置转化和下发,直面 Sidecar 规模化带来的挑战。这也是双十一大促中,控制面最大的挑战。性能优化
规模化的问题在生产实践中,是一个组件走向生产可用级的必经之路。接下来将会分别从稳定性、性能优化、监控这三个方面分别展开。网络
咱们先梳理下 Pilot 提供的服务能力,从功能实现上来看,Pilot 是一个 Controller + gRPC Server 的服务,经过 List/Watch 各种 K8s 资源,进行整合计算生成 XDS 协议的下发内容,并提供 gRPC 接口服务。本次分享咱们先把关注点放在 gRPC 接口服务这个环节,如何保证接口服务支撑大规模 Sidecar 实例,是规模化的一道难题。架构
负载均衡app
要具有规模化能力,横向扩展能力是基础。Pilot 的访问方式咱们采用经常使用的 DNSRR 方案,Sidecar 随机访问 Pilot 实例。因为是长链接访问,因此在扩容时,原有的链接没有重连,会形成负载不均。为解决这个问题,咱们给 Pilot 增长了链接限流、熔断、按期重置链接功能,并配合 Sidecar 散列重连逻辑,避免产生链接风暴。负载均衡
为了下降大量 MOSN 同时链接同一个 Pilot 实例的风险,在 gRPC 首次链接时,Pilot 增长基于令牌桶方案的流控能力,控制新链接的处理响应,并将等待超时的链接主动断连,等待 Sidecar 下一次重连。
基于使用场景的压测数据,限制单实例 Pilot 同时可服务的 Sidecar 数量上限,超过熔断值的新链接会被Pilot 主动拒绝。
为了实现负载均衡,对于已经存在的旧链接,应该怎么处理呢?咱们选择了 Pilot 主动断开链接,不过断开链接的周期怎么定是个技术活。要考虑错开大促峰值,退避扩缩容窗口之类,这个具体值就不列出来了,你们按各自的业务场景来决定就行了。
最后还有一点是 Client 端的配合,咱们会控制 Sidecar 重连 Pilot 时,采用退避式重试逻辑,避免对 DNS 和 Pilot 形成负载压力。
规模化的另外一道难题是怎么保证服务的性能。在 Pilot 的场景,咱们最关注的固然是配置下发的时效性了。性能优化离不开细节,其中部分优化是通用的,也有部分优化是面向业务场景定制的,接下来会分享下咱们优化的一些细节点。
社区方案里 Pilot 是经过 Pod.Status 来获取 Pod 的 IP 信息,在小集群的测试中,这个时间基本秒级内能够完成。然而在大集群生产环境中,咱们发现 Status 的更新事件时间较慢,甚至出现超过 10s 以上的状况,并且延迟时间不稳定,会增长 Pilot 首次下发的时延。咱们经过与基础设施 K8s 打通,由 PaaS 侧将 Pod 分配到的 IP 直接标记到Pod.Annotation 上,从而实如今第一次获取 Pod 事件时,就能够获取到 IP,将该环节的时延减小到0。
这是一个面向 DBMesh 业务场景的定制性优化,是基于按需获取的逻辑来实现的。其目的在于解决 DBMesh CR 数量过多,过大致使的性能问题,同时避免 Pilot 因为 List/Watch CR 资源致使 OOM 问题,Pilot 采用按需缓存和过时失效的策略来优化内存占用。
社区方案中当 Pilot List/Watch 的资源发生变动时,会触发所有 Sidecar 的配置推送,这种方案在生产环境大规模集群下,性能开销是巨大的。举个具体例子,若是单个集群有 10W 以上的 Pod 数量,任何一个 Pod 的变动事件都会触发所有 Sidecar 的下发,这样的性能开销是不可接受的。
优化的思路也比较简单,若是可以控制下发范围,那就能够将配置下发限制在须要感知变动的 Sidecar 范围里。为此,咱们定义了 ScopeConfig CRD 用于描述各种资源信息与哪些 Pod 相关,这样 Pilot 就能够预先计算出配置变动的影响范围,而后只针对受影响的 Sidecar 推送配置。
强管控能力是大促基本配备,咱们给 Pilot Admin API 补充了一些额外能力,支持动态变动推送频率、推送限流、日志级别等功能。
安全生产的基本要求是要具有快速定位和及时止血能力,那么对于 Pilot 来讲,咱们须要关注的核心功能是配置下发能力,该能力有两个核心监控指标:
针对下发的时效性,咱们在社区的基础上补充完善了部分下发性能指标,以下发的配置大小分布,下发时延等。
而对于配置准确性验证是相对比较复杂的,由于配置的准确性须要依赖 Sidecar 和 Pilot 的配置双方进行检验,所以咱们在控制面里引入了 Inspector 组件,定位于配置巡检,版本扫描等运维相关功能模块。
配置巡检的流程以下:
因为 Sidecar 的数量较大,Inspector 在巡检时,支持基于不一样的巡检策略执行。大致能够分为如下两类:
Sidecar 基于社区 SDS 方案 (Secret Discovery Service),支持证书动态发现和热更新能力。同时蚂蚁金服是一家金融科技公司,对安全有更高的要求,不使用 Citadel 的证书自签发能力,而是经过对接内部 KMS 系统获取证书。同时提供证书缓存和证书推送更新能力。
咱们先来看看架构图,请看图:
对总体架构有个大体理解后,咱们分解下 Sidecar 获取证书的流程,一图胜千言,再上图:
补充说明下图中的每一步环节:
国密通讯是基于 TLS 通讯实现的,采用更复杂的加密套件来实现安全通讯。该功能核心设计是由 Policy 和 Certificate 两部分组成:
在落地过程当中,仅依靠社区的 PERMISSIVE TLS MODE 还不能知足蚂蚁金服可灰度、可监控、可应急的三板斧要求。因此在社区方案的基础上,引入 Pod 粒度的 Sidecar 范围选择能力(也是基于 ScopeConfig ),方案基本以下图所示:
流程以下:
Citadel Agent 经过 Citadel 去同步 POD 及 CRD 等信息,虽然避免了 Node 粒度部署的 Citadel Agent 对 API Server 的压力。可是使用 MCP 协议同步数据时,咱们遇到了如下两个挑战:
为了解决以上两个问题,就须要对 MCP 实现进行改造。改造的目标很明确,那就是减小同步信息量,下降推送频率。为此,咱们强化了社区 MCP 的实现,补充了这些功能:
本次大促的控制面的重心在于解决规模化问题,后续控制面将会在服务发现、精细化路由、Policy As Code 等领域深刻探索。咱们将与社区深度合做,控制面将支持经过 MCP 对接多种注册中心(SOFARegistry(已开源), Nacos等)进行服务发现信息同步,解决大规模服务注册发现问题,支持增量推送大量 endpoint。同时控制面还能经过加强配置下发能力,为应用启动提速,将在 Serverless 极速启动场景获取技术红利。控制面还将结合 Policy As Code,从而更具想象空间,具有极简建站,默认安全等能力。
到此,本次分享的内容就结束了。Istio 生产级实践机会可贵,而且任重道远。最后,欢迎有志之士加入咱们,一块儿打造世界级规模的 Service Mesh。
本文做者:彭泽文(花名:封尘),蚂蚁金服 Mesh 控制面主站负责人,主要 Focus 领域:Service Mesh(SOFAMosn、Istio)。