本文为《蚂蚁金服 Service Mesh 大规模落地系列》 运维篇,该系列将会从核心、RPC、消息、无线网关、控制面、安全、运维、测试等模块对 Service Mesh 双十一大规模落地实践进行详细解析。前端
Service Mesh 是蚂蚁金服下一代架构的核心,也是蚂蚁金服内部向云原生演进的重要一环。本文为 Service Mesh 系列文章的运维篇,做者:黄家琦 (花名:嘉祁),蚂蚁金服运维专家,Service Mesh SRE,主要关注云原生基础设施、中间件及 Service Mesh 的稳定性,同时也是 Pythoner,sofa-bolt-python 做者。python
本文将主要分享大规模服务网格在蚂蚁金服当前体量下落地到支撑蚂蚁金服双十一大促过程当中,运维角度所面临的挑战与演进。内容包括云原生化的选择与问题,对资源模型的挑战,大规模下运维设施的演进,以及周边技术风险能力的建设。git
Service Mesh 在2019年获得了大规模的应用与落地,截止目前,蚂蚁金服的 Service Mesh 数据平面 MOSN 已接入应用数百个,接入容器数量达数十万,是目前已知的全世界最大的 Service Mesh 集群。同时,在刚刚结束的双十一大促中,Service Mesh 的表现也十分亮眼,RPC 峰值 QPS 达到了几千万,消息峰值 TPS 达到了几百万,且引入 Service Mesh 后的平均 RT 增加幅度控制在 0.2 ms 之内。github
Service Mesh 在软件形态上,是将中间件的能力从框架中剥离成独立软件。而在具体部署上,保守的作法是以独立进程的方式与业务进程共同存在于业务容器内。咱们在蚂蚁金服内部的作法,则从开始,就选择了拥抱云原生。后端
业务容器内独立进程的好处在于与传统的部署模式兼容,易于快速上线;但独立进程强侵入业务容器,对于镜像化的容器更难于管理。而云原生化,则能够将 Service Mesh 自己的运维与业务容器解耦开来,实现中间件运维能力的下沉。在业务镜像内,仅仅保留长期稳定的 Service Mesh 相关 JVM 参数,从而仅经过少许环境变量完成与 Service Mesh 的联结。同时考虑到面向容器的运维模式的演进,接入 Service Mesh 还同时要求业务完成镜像化,为进一步的云原生演进打下基础。安全
优 劣网络
独立进程架构
兼容传统的部署模式 侵入业务容器app
改形成本低 镜像化难于运维负载均衡
快速上线
Sidecar
面向终态 依赖 K8s 基础设施
运维解耦 运维环境改形成本高
应用须要镜像化改造
在接入 Service Mesh 以后,一个典型的 POD 结构可能包含多个 Sidecar:
MOSN:RPC Mesh, MSG Mesh, ...(扩展中);
其它 Sidecar;
MOSN:https://github.com/sofastack/sofa-mosn
这些 Sidecar 容器,与业务容器共享相同的网络 Namespace,使得业务进程能够以本地端口访问 Service Mesh 提供的服务,保证了与保守作法一致的体验。
咱们也在基础设施层面同步推动了面向云原生的改造,以支撑 Service Mesh 的落地。
首先是在蚂蚁金服内部推动了全面的镜像化,咱们完成了内部核心应用的全量容器的镜像化改造。改造点包括:
基础镜像层面增长对于 Service Mesh 的环境变量支撑;
应用 Dockerfile 对于 Service Mesh 的适配;
推动解决了存量先后端分离管理的静态文件的镜像化改造;
推动了大量使用前端区块分发的应用进行了推改拉的改造;
大批量的 VM 模式的容器升级与替换;
除了业务镜像层面的改造,Sidecar 模式还须要业务容器所有跑在 POD 上,来适应多容器共享网络。因为直接升级的开发和试错成本很高,咱们最终选择将接入 Service Mesh 的 数百个应用的数万个非 K8s 容器,经过大规模扩缩容的方式,所有更换成了 K8s PODs。
通过这两轮改造,咱们在基础设施层面同步完成了面向云原生的改造。
Sidecar 模式的带来一个重要的问题,如何分配资源。
最初的资源设计基于内存没法超卖的现实。咱们作了一个假设:
MOSN 的基本资源占用与业务选择的规格同比例这一假设。
CPU 和 Memory 申请与业务容器相应比例的额外资源。这一比例最后设定在了 CPU 1/4,Memory 1/16。
此时一个典型 Pod 的资源分配以下图示:
这一方式带来了两个问题:
蚂蚁金服已经实现了业务资源的 Quota 管控,但 Sidecar 并不在业务容器内,Service Mesh 容器成为了一个资源泄漏点;
业务不少样,部分高流量应用的 Service Mesh 容器出现了严重的内存不足和 OOM 状况;
不止于此,为了快速支撑 Service Mesh 在非云环境的铺开,上线了原地接入 Service Mesh。而原地接入 Service Mesh 的资源没法额外分配,在内存不能超卖的状况下,采起了二次分割的分配方式。此时的 POD 内存资源被切分为1/16内存给 Sidecar,与15/16给业务容器。除了以上两个问题,还带来一些新的问题:
业务可见内存不一致,业务监控误差,业务进程 OOM 风险。
讨论以后,咱们追加了一个假设:
Service Mesh 容器占用的资源实质是在接入 Service Mesh 以前业务已使用的资源。接入 Service Mesh 的过程,同时也是一次资源置换。
基于这个假设,推动了调度层面支持 POD 内的资源超卖,新的资源分配方案以下图,Service Mesh 容器的 CPU、MEM 都从 POD 中超卖出来,业务容器内仍然能够看到所有的资源。
考虑到内存超卖也引入了 POD OOM 的风险,所以对于 Sidecar 容器还调整了 OOM Score,保证在内存不足时,Service Mesh 进程可以发挥启动比 Java 业务进程更快的优点,下降影响。
新的分配方案解决了同时解决了以上两个问题,而且平稳支持了大促前的多轮压测。
但新的分配方案上线时,Service Mesh 已经在弹性建站时同步上线。同时咱们还发如今一些场景下,Service Mesh 容器没法抢占到 CPU 资源,致使业务 RT 出现了大幅抖动,缘由是在 CPU Share 模式下,POD 内默认并无等额的分配 CPU Quota 给 Sidecar。
因而还有两个问题待解决:
存量的已分配 Sidecar 仍有 OOM 风险;
Sidecar 没法抢占到 CPU;
咱们已经没法承受更换所有 POD 的代价。最终在调度的支持下,经过对 Pod Annotation 的手动从新计算+修改,在 POD 内进行了所有资源的重分配,来修复这两个风险。最终的修复容器总数约 25w 个。
Service Mesh 的变动包括了接入与升级,全部变动底层都是由 Operator 组件来接受上层写入到 POD annotation 上的标识,对相应 POD Spec 进行修改来完成,这是典型的云原生的方式。因为蚂蚁金服的资源现状与运维须要,又发展出了原地接入与平滑升级。与 Operator 有关的具体细节在 Operator 篇中会详细介绍,请持续关注本公众号。
最初的 Service Mesh 接入只提供了建立时注入 Sidecar。以后引入原地接入的缘由,是为了支撑大规模的快速接入与回滚。
建立接入:
资源替换过程须要大量 Buffer;
回滚困难;
原地接入:
不须要从新分配资源;
可原地回滚;
原地接入/回滚须要对 POD Spec 进行精细化的修改,实践中发现了不少问题,当前能力只作了小范围的测试。
Service Mesh 是深度参与业务流量的,所以最初的 Sidecar 的升级方式也须要业务伴随重启。看似简单的这个过程当中,咱们也遇到了一个严重问题:
Pod 内的容器启动顺序随机致使业务没法启动。
这个问题最终依赖于调度层修改了启动逻辑,POD 内须要优先等待全部 Sidecar 启动完成,因而带来第二个问题:
Sidecar 启动慢了,上层超时。
此问题仍在解决中。
Sidecar 中,MOSN 提供了更为灵活的平滑升级机制:由 Operator 控制启动第二个 MOSN Sidecar,完成链接迁移,再退出旧的 Sidecar。小规模测试显示,整个过程业务能够作到流量不中断,几近无感。目前平滑升级一样涉及到 POD Spec 的大量操做,考虑到大促前的稳定性,目前此方式未作大规模使用。
在逐渐达到大促状态的过程当中,接入 Service Mesh 的容器数量开始大爆炸式增长。容器数量从千级别迅速膨胀到10w+,最终达到全站数十万容器规模,并在膨胀后还经历了数次版本变动。
快速奔跑的同时,缺乏相应的平台能力也给大规模的 Sidecar 运维带来了极大挑战:
版本管理混乱:
Sidecar 的版本与应用/ Zone 的映射关系维护在内部元数据平台的配置中。大量应用接入后,全局版本,实验版本,特殊 Bugfix 版本等混杂在多个配置项中,统一基线被打破,难于维护。
元数据不一致:
元数据平台维护了 POD 粒度的 Sidecar 版本信息,可是因为 Operator 是面向终态的,会出现元数据与底层实际不一致的状况,当前仍依赖巡检发现。
缺乏完善的 Sidecar ops 支撑平台:
缺乏多维度的全局视图;
缺乏固化的灰度发布流程;
依赖于人工经验配置管理变动;
监控噪声巨大;
固然,Service Mesh 与 PaaS 的开发团队都已经在建设相应的一些能力,这些问题正获得逐步的缓解。
咱们的监控平台为 Service Mesh 提供了基础的监控能力和大盘,以及应用维度的 Sidecar 的监控状况。包括:
系统监控:
CPU;
MEM;
LOAD;
业务监控:
RT;
RPC 流量;
MSG 流量;
Error 日志监控;
Service Mesh 进程还提供了相应的 Metrics 接口,提供服务粒度的数据采集与计算。
在 Service Mesh 上线后,巡检也陆续被加入:
日志 Volume 检查;
版本一致性;
分时调度状态一致;
Service Mesh 自身具有按需关闭部分功能的能力,当前经过配置中心实现:
日志分级降级;
Tracelog 日志分级降级;
控制面(Pilot)依赖降级;
软负载均衡长轮询降级;
对于 Service Mesh 依赖的服务,为了防止潜在的抖动风险,也增长了相应的预案:
软负载均衡列表中止变动;
服务注册中心高峰期关闭推送;
Service Mesh 是很是基础的组件,目前的应急手段主要是重启:
Sidecar 单独重启;
POD 重启;
除了传统的变动三板斧以外,咱们还引入了无人值守变动,对 Service Mesh 变动作了自动检测,自动分析与变动熔断。
无人值守变动防控主要关注变动后对系统和业务和影响,串联了多层检测,主要包括:
系统指标:包括机器内存、磁盘、CPU;
业务指标:业务和 Service Mesh 的 RT、QPS 等;
业务关联链路:业务上下游的的异常状况;
全局的业务指标;
通过这一系列防控设施,能够将全站性的 Service Mesh 变动风险在单一批次变动内发现和阻断,避免了风险放大。
Service Mesh 在快速落地的过程当中,遇到并解决了一系列的问题,但同时也要看到还有更多的问题还亟待解决。作为下一代云原生化中间件的核心组件之一,Service Mesh 的技术风险能力还须要持续的建议与完善。
将来须要在下面这些方面持续建设:
大规模高效接入与回滚能力支撑;
更灵活的变动能力,包括业务无感的平滑/非平滑变动能力;
更精准的变动防控能力;
更高效,低噪声的监控;
更完善的控制面支持;
应用维度的参数定制能力;
欢迎有志于中间件 Service Mesh 化与云原生稳定性的同窗加入咱们,共同建设 Service Mesh 的将来。