ASI:Alibaba Serverless infrastructure,阿里巴巴针对云原生应用设计的统一基础设施。ASI 基于阿里云公共云容器服务 ACK之上,支撑集团应用云原生化和云产品的 Serverless 化的基础设施平台。
2021 年天猫双十一,对于 ASI 来说又是难忘的一年,今年我们又完成了很多“第一次”:
ASI 在大规模生产应用的锤炼下,不仅沉淀了非常多的 K8s 稳定性运维能力,更是在支持 serverless 场景下孵化了很多创新能力。如果运维过 K8s(特别是运维大规模集群)的同学一定会有很深的感触:把 K8s 用起来很容易,想要用好 K8s 真心不容易。ASI 在使用 K8s 调度体系架构早期成长阶段,也经历过多次血的教训,过程中我们持续成长、学习和成熟。例如:
以上列举的各种故障场景,即使是专业 K8s 团队都无法避雷,如果是对 K8s 了解很少的用户,肯定更无法预防和规避风险。所以,给所有正在使用 K8s 服务,或者想要用 K8s 服务的用户一个中肯建议:不要想着自己就能运维好 K8s 集群,里面有多少坑你真的想象不到,专业的人做专业的事,让专业产品和 SRE 团队来实现运维。在这里,我也是强烈建议用户使用阿里云容器服务 ACK,因为我们在阿里巴巴大规模场景下沉淀能力增强、自动化运维和能力都会反哺到 ACK 中,帮忙更好的维护用户的 K8s 集群。
ASI 能运维好这么多庞大 K8s 集群,一定得有“两把刷子”。今天我会给大家详细介绍 ASI 在为阿里集团构建云原生基础设施,和支持阿里云云产品 Serverless 化方面,我们的运维体系和稳定性工程能力。
在介绍 ASI 的全托管运维体系之前,我花一点篇幅来介绍一下 ASI。ASI 是基于 ACK、ACR 之上面向集团和云产品的 Serverless 化平台,旨在支撑阿里巴巴应用云原生化和阿里云产品 Serverless 化。下面介绍容器服务家族的几位成员:ACK、ASK、ACR。
针对阿里巴巴和云产品业务场景,在 K8s 集群功能层面我们会给用户提供增强的能力,比如调度能力增强、Workload 能力增强、网络能力增强、节点弹性能力增强和多租安全架构等等;在集群运维层面,提供 Serverless 化的 No Ops 体验,比如集群大版本升级、组件升级、节点组件升级、节点 CVE 漏洞修复、节点批量运维等,为用户的 K8s 集群稳定性兜底。
ASI 为大规模 K8s 集群,提供了全托管、免运维的用户体验。这些能力不是 K8s 原生就具备的,而是在大量实践和失败过程中沉淀出来的系统稳定性加固能力。而放眼整个行业,正是阿里巴巴的规模化复杂场景,才能锤炼出大规模场景下的 K8s 运维服务体系。
在讲 ASI 运维体系之前,我先强调一下在做系统能力建设过程的一个重要原则:不重复造轮子,但是也不能完全依赖其他系统的能力。没有哪一款产品、系统能 cover 住所有业务的所有问题(特别是 ASI 这样体量的业务)。依赖上下游链路已经建好的系统能力,但是不会完全依赖,要做好系统分层设计。如果一个系统做好了底层的运维通道,我们一定不会再去做一个运维通道,而是会基于上层运维通道做我们自己业务变更的编排;如果一个系统做好了监控、告警链路的能力,我们会做好监控、告警规则和路由分发的管理。
另外一件非常重要的事情:做稳定性的团队要想做好运维管控系统,就一定要对业务架构有非常全面、深入的了解。稳定性团队不能只做运营,也不能仅仅在架构外面做 1-5-10 能力,这样是很难把控整个架构的稳定性。ASI SRE 虽然是为 ASI 基础设施稳定性兜底的团队,但是很多 SRE 同学都可以独立去对接新的业务,并能决定整个业务上 ASI 的架构。其实很多时候,如果是 SRE 和研发配合去接的业务方,往往问题都少很多,因为两个角色非常互补:研发在技术架构上有很好的判断,SRE 在架构合理性和稳定性风险有很好的判断。
如上图是 ASI 集群部署架构,完全基于 ACK 产品 Infra 架构的 KOK(Kube On Kube)底座。整个架构分层为:
基于 ASI 整个架构,我们经过不断探索、抽象,将 ASI 运维体系,抽象成核心几大模块,如下图所示:
接下来我会针对 ASI 全托管运维体系中关键系统/技术能力的设计思路和具体方案进行阐述,向大家呈现我们是如何一步步将大规模 K8s 全托管运维服务建设起来的。
集群全托管运维能力
当我们在运维大规模 K8s 集群的时候,最深的感受就是:规模化既会给单个运维操作带来很大的复杂度,也会将单个运维操作的风险爆炸半径大大扩大。我们也是经常会被下面的问题挑战:
带着这四个问题,接下来我会详细介绍,我们如何在实践中不断抽象和优化我们的系统能力,并沉淀出目前对 ASI 全托管服务非常重要的稳定性系统能力。
统一变更风险管控
2019 年,当我们刚成立 ASI SRE 团队的时候,就在探索如何把控变更带来的风险。当时的稳定性系统能力还非常弱,真的是百废待兴,新的 SRE 团队的同学都是从阿里云自研的Sigma调度系统各个子研发团队抽调出来的,所以大家对容器、K8s、etcd 这些技术都非常精通,但是对如何做 SRE,如何做稳定性都是一脸懵。记得刚开始,我们在 ASIOps 系统(当时还叫asi-deploy)里接入 ChangeFree 变更审批都花了 2~3 周的时间。面对新的架构(Sigma -> ASI)、新的场景(集团业务上云)和如此复杂、庞大的 K8s 业务体量,我们也没有太多外界的经验可以借鉴。
当时我们想的是靠系统来做变更风险管控肯定是来不及的(集团业务全面上云已经开展起来,大量新的技术方案出来、大量线上变更),只能先靠“人治”。所以我们就在整个 ASI 团队宣导任何变更都要让 SRE 审批,但是 SRE 并不能了解 ASI 所有技术架构细节,做完善的风险评估。为此,我们又开始组建“变更评审”会议,在评审会上邀请每一个领域的专家同学参与进行变更方案的风险评审。也是因为这个变更评审机制,帮助 ASI 在变更风险阻断系统能力非常不足的情况下稳定的渡过了那段“艰难”的时期。ASI 的变更评审会议也一直延续到今天,没有封网特殊时期,都会如期召开。也是那段时间,SRE 通过参加每一次线上变更的审批,也沉淀了非常多的安全生产规则:
与此同时,我们开始将这些已经非常明确的变更风险阻断的规则实现到 ASIOps 系统中。刚开始是实现 ASI 底层系统架构层面的风险阻断能力,后来发现很多变更只通过底层ASI的指标/探测是没办法发现问题的,需要有一种机制能联动上层业务系统来触发业务层面的一些风险阻断规则判断,这样才能尽可能的确保我们的变更不会对上层业务带来影响。所以,我们开始在 ASIOps 实现变更风险规则库的管理,并实现了一种 webhook 的机制,来联动上层业务方的巡检检测/E2E 测试。
ASI 有了这套在线变更风险阻断系统能力之后,我们再也没有出现过封网期私自变更,变更不做灰度、不验证等这类触犯变更红线的行为。
变更灰度能力
从实际经验来看,每一次线上变更,不管我们前期方案评审多么仔细、多么严格,风险阻断做的多么完善,运维功能写的多好。代码上线之后,总是会出现我们“意想不到”的情况。对于已经知道的事情,我们一定会做的很好,可怕的是我们考虑不到的事情,这不是能力问题,现实架构他就是足够复杂。
所以功能上线一定要灰度。当然,我们还要保证变更动作的确定性,不能说张三变更是这样顺序去灰度的,李四同样的变更又是另外的一个灰度顺序。ASI 变更灰度能力,我们也是经过了好多次迭代。
Sigma 时代,集群都是跨机房/跨 Region 部署的,所以如此庞大的业务体量,Sigma 也只需要 10 个不到的集群来承载。对于研发来说,因为集群个数不多,集群做什么用的、业务类型是怎样的,都很清楚,所以发布成本不是很高(当然,由于爆炸半径太大,发布小问题也是不断)。但是演进到 ASI 架构之后,集群规划是严格按照 Region/机房来进行切割的,并且由于 K8s 集群本身可伸缩性问题,无法像 Sigma 集群那样一个集群能承载十几万的节点,K8s 社区当时给的是单集群规模不能超过 5000 节点(虽然现在 ASI 已经优化到单集群上万节点,但是过大的集群在稳定性与爆炸半径方面的风险也更高)。在这种架构形态之下,ASI 集群的个数肯定会远远大于 Sigma 集群的个数。研发同学都还在 Sigma 后期、ASI 早期时代,很多研发习惯还是沿用 Sigma 当时的模式,发布工具还是 Sigma 时代的产物,没办法支持大规模 K8s 集群精细化组件发布。各个团队的研发每次发布也都胆战心惊,也怕出问题。
当时,在集团 ASI 集群个数还没有增长上来之时,我们就已经意识到要去解决变更确定性的问题。ASI 这么多集群,几十万的节点,如果让各个研发同学去决定如何变更肯定是要出问题的。但是,当时我们的系统能力又非常不足,也没办法很智能的通过综合判断各种条件来为研发同学的变更确定一条最佳的变更灰度顺序。那怎么办呢?系统不牛逼,但是也得要解决问题啊。所以我们提出了一个 pipeline 的概念:由 SRE 主导和核心研发TL一起确定线上核心集群的发布顺序,定义为一条 pipeline,然后所有研发在做组件升级的时候,必须要绑定这条 pipeline,发布的时候,就可以按照我们规定好的集群顺序来进行灰度发布了,这就是 pipeline 概念的由来。这一个“看起来很 low”的功能,在当时消耗了我们非常大的精力投入才做出一个初版。不过,当我们“满怀信心”把 pipeline 推广给研发同学用的时候,却没有收到我们想象中的“鲜花和掌声”,而是很多“吐槽和优化建议”。所以我们改变推广策略:逐步小范围推广、逐步修正、然后大范围推广,直到大家完全接受。现在 pipeline 已经成为了 ASI 研发同学必不可少的发布工具了。现在想起来,也觉得蛮有意思的。也让我们明白一个道理:任何新的功能不能“闭门造车”,一定要从我们的用户角度出发来进行设计、优化,只有用户满意,才能证明我们系统/产品的价值。
下图就是我们按照测试->小流量->日常->生产这个顺序,为研发定义的集团核心交易集群的发布顺序:
静态 pipeline 编排 ASI 集群顺序的能力,在当时只支持集团为数不多的 ASI 集群时,问题还不大。但是当 ASI 业务扩展到了阿里云云产品之后,特别是我们和 Flink 产品一起孵化出了 ASI 硬多租 VC 架构之后,一个用户一个小的集群,集群数量陡增,这种人工编排集群顺序就暴露很多问题了:
基于上述静态 pipeline 总总不足,我们也是早就开始了技术方案的优化思考和探索。ASI核心是资源调度,我们的调度能力是非常强的,特别是现在集团做的统一调度项目,将集团电商业务、搜索业务、离线业务和蚂蚁业务,全部用统一的调度协议上了 ASI。我就在想,ASI 统一调度器是资源 cpu、memory 的调度,集群信息、Node 数量、Pod 数量、用户 GC 信息也都是“资源”,为什么我们不能用调度的思想去解决ASI集群灰度顺序编排的问题呢?所以,我们参考了调度器的设计实现了 Cluster-Scheduler,将集群的各种信息整合起来,进行打分、排序,得出一条集群 pipeline,然后提供给研发同学来进行灰度发布。
Cluster-Scheduler 实现了一种“动态”pipeline 的能力,能很好的解决静态 pipeline 碰到的各种问题:
当然静态 pipeline 有一个很大的优点:集群发布顺序可以自助编排,在一些新功能上线场景中,研发需要有这种自助编排能力。所以未来我们也是静态/动态 pipeline 一起配合使用,互相补充。
集群webshell工具
SRE 在做稳定性风险把控的时候,一定是希望所有的变更都是白屏化和在线化。但是从我们运维 K8s 的实际情况来看,没办法将所有的运维操作都白屏化来实现。我们又不能直接将集群证书提供给研发同学:一是会存在权限泄漏安全风险,;二是研发在本地用证书操作集群,行为不可控,风险不可控。ASI 初期也出现过多次在本地用 kubectl 工具误删除业务 Pod 的行为。虽然我们无法将 K8s 所有运维操作都白屏化在系统上提供给研发使用,但是我们可以将 kubectl 工具在线化提供给研发来使用,然后基于在线化工具提供稳定性、安全性加固、风控等能力。
所以,我们在 Ops 系统里提供了集群登陆工具 webshell,研发可以先按“最小可用”原则申请集群资源访问权限,然后通过 webshell 中去访问集群进行相应的运维操作。在的 webshell 中我们会将用户的所有操作记录下来,上传到审计中心。
在线 webshell,对比用户本地证书访问集群,我们做了非常多的安全/稳定性加固:
变更编排能力
前面讲的风险阻断、变更灰度和黑屏变更收敛,都是在解决 ASI 稳定性问题。但是,谁又能帮助解决我们 SRE 同学面临的挑战呢?
做稳定性的同学都知道:只有将变更白屏化/在线化之后,我们才能对这些变更中心化管控,把控变更风险。但是对于 ASI 这种非常庞大复杂的基础设施服务来说,变更场景繁多、复杂。我们 SRE 负责整个 ASIOps 运维管控平台的建设,既要面对每天繁重的运维工作,还要建系统,更要命的是我们的同学都是后端开发工程师出身,Ops 系统需要做前端界面,写前端是后端工程师的梦魇,经常是一个后端功能 1h 写完,前端页面要画至少一天。
SRE 团队是一个技术服务团队,不仅仅要让我们的服务方满意,更要让我们自己满意。所以,我们在搞系统能力建设的过程中,一直在探索怎么降低运维系统开发的成本。大家应该也知道,运维能力和业务系统能力不同,运维操作更多是多个操作编排起来的一个综合操作,比如解决线上 ECS 上 ENI 网卡清理的问题,完整的运维能力是:首先在节点上执行一个扫描脚本,将泄漏的 ENI 网卡扫描出来;然后是将扫描出来的泄漏的 ENI 网卡作为入参传给清理 ENI 网卡的程序;最后 ENI 网卡清理完成,上报相应的状态。所以,我们当时就想做一个事情:实现一套运维操作编排引擎,能快速的将多个单个独立的运维操作编排起来实现复杂的运维逻辑。当时我们也调研了很多编排工具比如 tekton、argo 这类的开源项目。发现要么是项目 PR 的非常好,但是功能还是太基本,没办法满足我们的场景;要么就是在设计上更多的是适用于业务场景,对于我们这种底层基础设施非常不友好。
所以,我们决定取现在已有编排工具的精华,参考他们的设计,实现 ASI 自己的一套运维编排引擎工具。这就是 ASIOps 中 Taskflow 编排引擎的由来,架构设计如下图所示:
举一个节点扩容功能的例子,如果是单独实现一套节点全生命周期管理的功能,所有的操作功能都要自己写。但是在使用了 Taskflow 编排能力之后,只需要实现 3 个 executor(执行器)逻辑:Ess 扩容、节点初始化、节点导入。Taskflow 会将这 3 个 executor 执行流串联起来,完成一次节点扩容操作。
目前 Taskflow 这套编排引擎在 ASIOps 内被广泛使用,覆盖了诊断、预案、节点导入导出、VC 集群开服、一次性运维、发布等场景,也大大提升了新的运维场景系统能力开发的效率。
经过两年多的锻炼,SRE 团队的核心研发同学基本都是“全栈工程师”(精通前、后端研发)。特别是前端界面研发,现在不仅没有成为我们团队的负担,相反成为了我们团队的优势。很多系统能力都需要前端界面暴露给用户来使用,而在 ASI 这个绝大部分研发都是后端工程师的团队,SRE 团队前端开发资源成为了我们非常重要的“竞争力”。也充分证明了:技多不压身。
小结
关于 ASI 集群全托管运维能力,我这边核心介绍了在系统能力实现上是如何做变更风险阻断、变更编排、变更灰度和收敛黑屏变更。当然,我们在 ASI 管控全托管层面做的远远不止这些系统能力,还有非常多次的架构升级的大型线上变更,正是因为我们有如此多场景积累,才能沉淀出很多重要的系统能力。
组件全托管运维能力
关于 ASI 组件全托管能力,我们之前已经发表过一篇文章进行详细介绍:ASI 组件灰度体系建设,大家有兴趣可以详细看一下,确实在 ASI 如此大规模场景下,才会有的技术和经验的沉淀。所以我这里就不做过多的技术方案的介绍,更多是介绍我们技术演进的过程。ASI 在组件灰度能力建设的分享,也入选了 2020 年 KubeCon topic:《How we Manage our Widely Varied Kubernetes Infrastructures in Alibaba》,感兴趣的同学可以去找一下相关的视频。
ASI 全托管模式下组件全托管能力是和目前半托管容器服务云产品一个非常重要的区别:ASI 会负责 K8s 集群中核心组件维护工作(研发、问题排查和运维)。这个其实也是和 ASI 起源有关,ASI 起源于集体业务全面上云时期,我们提供一个大集群+公共资源池的模式让业务逐渐从 Sigma 架构迁移上 ASI。对于集团业务来说,肯定不会去维护 K8s 集群以及集群里的各种组件,所以这块就完全由 ASI 团队来负责,也让 ASI 逐渐孵化出了组件全托管的系统能力
如上图,ASI 整个架构的各种层面的组件现在都是基于 ASIOps 进行统一的变更灰度编排管理。其实,在现在看来 ASI 的所有组件放在一个平台来维护,并且统一来进行灰度能力建设是非常理所当然的事情。但是,在当时我们也是经过了非常长时间的“斗争”,才让今天的架构变得如此合理。在多次激烈的探讨和各种来自稳定性的压力背景下,我们终于探索出了一个比较符合目前 K8s 架构的顶层设计:
经过两年多的发展,ASI 体系下组件变更也完全统一在一个平台下,并且基于云原生的能力也建设出了非常完善的灰度能力:
节点全托管运维能力
前面我也介绍了,我们在建设系统能力时不会重复造轮子,但是也不能完全依赖其他产品的能力。ACK 提供了节点生命周期管理的基本产品能力,而 ASI 作为 ACK 之上的 Serverless 平台,需要在 ACK 基本产品能力之上,建设规模化运维能力。从 Sigma 时代到ASI支持集团超大统一调度集群过程中,ASI 沉淀了非常多规模化运维节点的能力和经验。接下来介绍一下我们在售卖区如何建设节点全托管能力建设起来。
节点全生命周期定义
要建设比较完善的节点全托管运维能力,我们首先要梳理清楚节点全生命周期的每一个阶段需要做哪些事情,如下图我们将节点全生命周期大致分为 5 个阶段:
节点能力建设大图
ASI 售卖区节点托管能力建设 1 年多,已经承载了售卖区所有上 ASI 的云产品,并且大部分核心能力都已经建设比较完善,节点自愈能力我们也在不断优化完善中。
节点弹性
在云上一个最大的特点就是资源弹性,节点弹性能力也是售卖区 ASI 给云产品用户提供的一个非常重要的能力。ASI 的节点弹性能力依靠 ECS 资源的极致弹性,能按照分钟级来进行 ECS 资源购买和释放,帮忙云产品精细化控制资源成本。视频云云产品目前就在 ASI 上重度依赖 ASI 节点弹性能力,进行资源成本控制。视频云平均一天节点弹性 3000 多次,并且经过不断优化,ASI 节点弹性能达到几分钟内完全拉起视频云业务。
在节点弹性上,我们在节点整个生命周期中都进行了性能优化:
1-5-10 能力建设
ASI 全托管模式的服务,最重要的还是我们能为云产品用户进行底层集群稳定性问题进行兜底。这个对 ASI 的 1-5-10 能力要求就非常高,接下来主要给大家介绍 3 个核心稳定性能力:
风控
在任何时刻,ASI 一定要有“踩刹车”的能力,不管是我们自己同学误操作,还是上层业务方误操作,系统必须有及时止损的能力。在文章开头,我也介绍了 ASI 曾经发生过的大规模重启、误删 pod 的事故。正因为之前血泪教训,才造就了我们很多风控能力的诞生。
KubeProbe
KubeProbe 是 ASI 巡检/诊断平台,经过不断迭代,目前我们演进了两种架构:中心架构和 Operator 常驻架构。KubeProbe 也中了今年上海 KubeCon 议题,感兴趣的同学,到时候也可以参加一下上海 KubeCon 线上会议。
1)中心架构
我们会有一套中心管控系统。用户的用例会通过统一仓库的镜像的方式接入,使用我们通用的 sdk 库,自定义巡检和探测逻辑。我们会在中心管控系统上配置好集群和用例的关系配置,如某用例应该执行在哪些集群组上,并做好各种运行时配置。我们支持了周期触发/手动触发/事件触发(如发布)的用例触发方式。用例触发后会在集群内创建一个执行巡检/探测逻辑的 Pod,这个 Pod 里会执行各种用户自定义的业务巡检/探测逻辑,并在成功和失败后通过直接回调/消息队列的方式通知中心端。中心端会负责告警和用例资源清理的工作。
2)常驻 Operator 架构
对于某些需要 7*24 小时不间断的高频短周期探测用例,我们还实现了另外一套常驻分布式架构,这套架构使用一个集群内的 ProbeOperator 监听 probe config cr 变化,在探测pod中周而复始的执行探测逻辑。这套架构,完美复用了 KubeProbe 中心端提供的告警/根因分析/发布阻断等等附加功能,同时使用了标准 Operator 的云原生架构设计,常驻体系带来了极大的探测频率提升(因为去掉了创建巡检 Pod 和清理数据的开销)基本可以做到对集群的 7*24 小时无缝覆盖,同时便于对外集成。
另外还有一个必须要提的非常重要的点,那就是平台只是提供了一个平台层的能力支持,真正这个东西要起作用,还是要看在这个平台上构建的用例是否丰富,能不能方便的让更多人进来写各种巡检和探测用例。就像测试平台很重要,但测试用例更重要这个道理一样。一些通用的 workload 探测,组件探测,固然能发现很多管控链路上的问题,但是更多的问题,甚至业务层的问题暴露,依赖于基础设施和业务层同学的共同努力。从我们的实践上来说,测试同学和业务同学贡献了很多相关的检查用例,比如 ACK&ASK 的创建删除全链路探测巡检,金丝雀业务全链路扩容用例,比如本地生活同学的 PaaS 平台应用检查等等,也得到了很多稳定性上的结果和收益。目前巡检/探测用例有数十个,明年有机会破百,巡检/探测次数近 3000 万次,明年可能会过亿。可以提前发现 99% 以上的集群管控问题和隐患,效果非常好的。
当我们的业务规模达到一定规模,如果仅仅靠 SRE 团队线上 Oncall 去解决问题肯定是远远不够的,一定需要我们系统具备非常强的自愈能力。K8s 面向终态的设计,通过 Readiness、Liveness 机制能帮忙业务 Pod 快速自愈。但是当节点故障时,我们也需要节点能快速自愈,或者能快速将节点上的业务驱逐到正常的节点上。ACK 产品也提供了自愈能力,ASI 在这个之上做了很多基于 ASI 业务场景的能力增强。如下是我们售卖区节点自愈能力的架构设计:
随着 ASI 业务形态的发展,未来我们将在如下场景下进行节点自愈能力增强:
ASI 作为容器服务 ACK 在阿里巴巴内部持续打磨的统一Serverless 基础设施,正在持续构建更强大的全自动驾驶 K8s 集群,提供集群、节点、组件的全托管能力,并一如既往地输出更多经验到整个行业。ASI 作为阿里集团、阿里云基础设施底座,为越来越多的云产品提供更多专业服务,托管底层 K8s 集群,屏蔽复杂的 K8s 门槛、透明几乎所有的基础设施复杂度,并用专业的产品技术能力兜底稳定性,让云产品只需要负责自己的业务,专业的平台分工做专业的事。
原文链接
本文为阿里云原创内容,未经允许不得转载。