智能运维:云原生大规模集群GitOps实践
内容介绍:
一、云原生大规模运维挑战
二、云原生运维管理实践
三、云原生GitOps实践
四、云原生智能运维工程体系
本次分享内容是智能运维:云原生大规模集群GitOps实践由阿里云智能集团运维专家钟炯恩分享。
在云原生大规模集群下GitOps实践,可能会有很多同学问:现在不是都已经讲AIOps吗?为什么我还在分享GitOps的内容?经过大量实践发现,GitOps是AIOPS之路上非常重要的一环。所以在这里也加了一个副标题,这是智能运维的工程演进之路。
钟炯恩来自阿里云计算平台,主要负责大数据以及AI平台的基础运维工作。分享会从四个方面展开。首先是云原生大规模运维挑战,稳定性、成本、效率是否能够同时兼顾。第二,云原生运维管理实践,如何用一个运维方案应Kubemete集群的管理复杂性。第三,在云原生的运维方案之上,如何演进GitOps。第四,在GitOps体系之下,如何演进智能运维工程体系,以及大模型时代的智能运维和会给我们带来什么变化?
一、云原生大规模运维挑战
首先当前所面临的挑战,这是我们当前一个超大规模的云原生运维现状。我们负责了 max compute、 flink、PAI 这类大数据以及AI产品,管理了大概一千多个云原生集群,包括ACK集群、容器服务 serverless 版、virtualcluster 等,涵盖了八万多个云原生节点,这些节点比较异构,有些是物理机,有些是虚拟机,也有些是神龙裸金属。我们提供了一个完整的运维方案,使日常的发布非常方便。,我们大概每天有500次云原生的发布,包含阿里集团以及公共云。
面对高频的发布,把大概会遇到四个问题。
首先发布效率和稳定性上的冲突。研发因为发布方便,所以他平时可能会选择比较高频的发布,但是高频的发布又带来了稳定性上的问题,所以我们期望的是发布时的质量要上升,但是频率不需要特别高。
第二是云原生配置是一个很重要的东西,我们提供了 YAML 的制品化管理。在这之上,用过 hlm 的也知道他能抽出很多参数,所以当维护制品时,到底是灵活的抽参数,还是做YAML固化也是一个问题,是我们日常常常会碰到的。
第三和今天的主题密切相关,到底是过程化管理,还是终态化管理。终态的配置是个点,而过程是一条线。很多人觉得只要终态对就行了,反正能够蹂躏到终态,过程不用管的。但实际上,举个例子,你修改了 Kubemete 的某个样貌之后,并不知道他会不会触发破的重启。如果你没有关注,在同一次变更里可能一次性触发了1万个pod重启,立马就把上游的服务打爆了,这就会出现很多非预期问题,这正是对于过程管理的疏忽导致的。
第四是自研方案和社区方案的取舍。我们之前做的更多的是飞天的运维,所以我们很多方案都是自研的。但在云原生场景下,这些都已经有变化了,很多社区里面都有一个完整方案。我们早期自研了一些和hlm类似的一些方案,但最后发现维护成本特别高,最终我们把这些制品作为一个标准的交付物进行。
二、云原生运维管理实践
然后看一下我们面对挑战的运维方案。首先是云原生运维的分层架构。这是我们服务的业务,我们自上而下看。针对这些业务,我们主要服务两方面,一是计算服务,二是管控服务。计算服务包括用户所开的实例。管控服务是用来管理实例的。面对这些运维管理的需求,我们需要一个云原生的全托管底座,包含应用管理和集群管理。在这个底座之下是基于云原生的基础设施底座,即ACK集群,这和大家能在阿里云上买到的ACK集群是一样的。帮我们解决了Kubemete集群下的master组件管理,以及网络管理或者存储管理。
在云原生基础设施底座下,有一个统一的节点资源池,包含了普通的ECS、神龙裸金属、物理机。这里我想强调的是把这块的颜色灰色化,是因为下面的统一节点资源池方案不仅只针对云原生。云原生K8S的节点抽象非常好。我们当前统一节点资源池的方案,不仅可支持K8S,也可支持飞天,甚至可支持较老的hadoop集群,做到了统一的节点资源的管理,和上层是分离的。
针对云原生应用管理和集群管理,继续往往下深入。当前是基于OAM(open application model)的云原生应用模型, 是阿里云和微软一起推出的云原生应用标准。针对这一标准,能够做到关注点分离,即不同角色通过不同的视角能够有不同的管理能力。在集群管理自顶向下看,可以看到一个运维或是IE的同学关注该集群,就会看到这有一些应用实例。在这个应用实例之下会有一些组件实例。同时OIM的模型提供了运维特征的抽象。运维同学就可以把一些运维特征附属到组件实例上,使得它具备更好的运维特性。
比如加解密的一些插件,或者auto scaling,使它可以做快速扩缩容。从应用管理的视角看,这是研发所要看到的视角。研发先会把制品变成binary,然后想办法把它变成container,在网上就变成pod ,用staff set或deployment来管理,这是研发同学需要进行选择的。他就有充分的需求会表达在state for set、deployment、conflict map之上,把它组成一个完整的一个home包交付给运维同学。所以大家的目光就在组件和运维特征聚焦。研发往上看,运维往下看,使大家针对同一事情,但从不同视角具备了不同的管理能力。
可以看一下日常的运维以及研发的过程。云原生应用的生产过程像一个环一样,一直轮转。首先研发同学会开发Docher file,编写出来的镜像就会做一个本地的helm模板验证,然后编排成一个OIM组件进入构建环节。构建环节会把应用镜像和应用YAML制品一起构建,分发到预发实例验证。验证通过后会出一个完整的生产变更单。在生产的变更单里,我们会按照region、不同的地域发布编排。编排完后才进行生产部署,以及可观测的验证。
这个过程像一个接力赛一样,开发同学会把这些东西给到运维同学,然后运维的同学再继续上线。这里面有些边界并没有那么清晰。比如研发的同学一开始只会出boundary, 不会写data file,这时候运维的同学就会向前走一点,把docker file先编完,让整个过程走出来,当研发的同学熟悉后,自己会去编写docker file。 所以这个工程不仅是一个代码工程,更是人员协作的过程。在这个过程中,通过这套流程体系使大家能互相合作,减少扯皮、分歧才是最重要的,使大家最终能够完成制品的完整交付。
看一下当前的生产情况。研发的同学提交了非常多的开发分支,然后我们把它合成一个虚拟的分支进行构建、部署。右图是给我们研发和SRE的同学的职责范围。前半段的CI部分是研发同学所关注的,后半段的CD部分是SRE运维同学所关注的。还有个小点,并不是研发前面搞完后,后面就不用管了,他们是互相配合的过程。以上是当前基于OAM的应用实现的模型。
三、云原生GitOps实践
在这个应用模型之上,如何落地GitOps实践。所以我们要带着问题去看,云原生GitOps到底是不是用Git完成所有的运维管理。首先git和Kubernetes的关联与差异。git和Kubernetes在架构抽象上有非常多的相似点。比如git有file& branch,在Kubernetes里我们能找到对应的是云原生的YAML,也能以树形结构做排列。git有commit记录所有的变化,而在Kubernetes里面,你只要用listwatch对应的资源,就能看到资源每时每刻的变化。
第三是说对git,我们有merge Request对它进行修改,而在Kubernetes里,可用API server CRUD, 或者用kubeCTL apply对它进行修改。第四也是最重要的,就是git有hook让你能够订阅到git的全生命周期的事情,而在Kubernetes,有Operator能让你订阅资源的所有变化。所以大家可以看到git和Kubernetes有非常多的相似性。是不是把Kubernetes YAML直接放到dit里就能完成GitOps呢?
我们最初也是带着怀疑的去看了一下业界的所有产品,大概列了一下。首先是fluxCD,这也是GitOps理念的一个提出者,虽然他的母公司现在有点不太行了,但是fluxCD也算是一个社区产品,也在持续更新,它提供了强大的controller来帮实施者快速达成GitOps目标。但我们实验了之后发现一个问题,就是fluxCD面向比较小的一些应用集群。
对于我们来说,我们每个应用下都会有一百多个甚至两百多个应用实例,如果采用这种方式就比较低效。另外ArgoCD使用的是更轻量级的方案,将Kubernetes集群的局部控制权转移到git仓库,使大家操作git仓库时就能实现对Kubernetes集群的操作,这个方案对我们来说也有点轻量化。另外一个就是Jenkins X+Tekton方案,基本上是老方案的新版。它主要是通过hook进行pipeline的交付流程,严格意义上说它不算是GitOps。
在调研了这些方案后,说我们整理了对GitOps的一些理解。我们认为GitOps方案是一体两面的东西。有人关注终态,有人关注的过程。比如研发的同学可能会关注部署目标的终态是,而运维的同学会关注如何达成目标,要不要做灰度的发布,发布的频率怎么样。
第二是研发的同学会非常在意这次终态和上次终态差的东西。关注过程的同学就会去问这个差异到底代表了什么,到底会不会重启服务,会不会带来一些我们看不到的蹂躏过程。第三是最重要的,我们用了gitops会觉得终是不是所见即所得。
一开始你会这样觉得,但后面你会发现他有一个非常大的问题,就是这个确实是终态,但此终态是否真的生效了,是否有些部署还未完成,这是一个非常大的问题。大家可以看到,在这个过程中,关注结果的人会偏乐观一些,关注过程的人会偏悲观一些。这些都都是合理的。所以我们的方案既要兼顾终态,也要兼顾过程的管理。
这是我们针对常见GitOps方案的一个优化。市面上常见的GitOps方案是先把终态提交,然后进行变更执行。变更执行可能几分钟就完成了,也有可能集群规模大一点,过程要几个小时,可能提交变更的那个人干其他事情去了。而此时,假如另一人又提交了终态,他也去执行了变更,这样变更就会合并,这个过程就会进入复杂的叠加态,前面的变更只进行了一半,后面的变更就开始了。我们认为折中的GitOps方案应该是把这种过程杜绝。我们把GitOps的边界放在发起一个merge Request认为开始做这个事情了。
然后我们会把merge Request做变更执行,一方面他真的去执行了,另一方面他会把终态提交,使变更执行和终态提交基本在非常近的时间内完成。同时提交merge Request的人有有义务观测这个结果直到结束。使每个发起merge Request的人都会对过程负责,而不是只要发起终态就不管过程。
然后我们可以看GitOps云原生变更流程的示意。前面要变更的同学可以fork一个开发分支。开发完后创建merge Request,然后针对merge Request会形成一个面向实体的变更计划。然后我们主管之类的就会审批,审批后会看到代码变化以及变更计划。有了变更计划后到智能变更平台执行,这是我们内部的一个平台,能够完成比较复杂的、面向实体的变更。在变更的过程中,一方面它把云原生对象做一个变更,另一方面它把代码合并。所以云原生对象变更和代码合几乎是同时发生的。有了这个后再去做观测,发现变更符合预期,最后再结束。
所以当讲完这个后,我们可以想一下在讲第三部分之前提出的一个问题GitOps是不是用git来管理所有的运维,我认为当前的方案不是,因为它是一个锦上添花的东西,是我们已有完整的变更方案,可以基于这个方案实施GitOps流程,它不是git base方案。
大家会疑问如何把merge Request转换成一个面向实体的变更计划。本身也是做基础运维的,所以对IaC比较熟悉。对比市面上一些IaC方案。Terraform大家用的比较多,用HCL语言描述ECS.;第二是配置原则方案,用crossplane管理ECS; 第三是用pulumi,这是相对较新的方案,进行ECS管理。
这三种方案里有其中几个问题。
第一是Terraform的这种IaC方案学习成本比较高,需要学习一门新的HCL语言。
第二,虽然crossplane不用学新的语言,但其表达灵活性没有Terraform强,且fls比较难表达。pulumi方案比较符合我们的胃口,我们可用熟悉的语言,比如java或python描述出变更所要参数。但不要真的去做它,只是export即可。
我们借鉴了pulumi方案,最终实现了根据merge Request进行生成变更描述的脚本。我们搞了一个SDK, 通过这个SDK就能方便的把当前gitdiff拿出。可以把gitdiff进行若干个操作后生成变更计划。在这样的脚本里要描述目标,不能是没有目标的变更。其次,要描述出怎么做这件事情,而不是脚本执行完直接做掉,因为脚本只生成变更计划,最终是由执行器做的。
第三,要在这个代码中把目标的终态配置全部说明。基于这一方案,我们基本实现了通过merge Request生成完整的变更。
当我们完成了GitOps目标后,只是运维变更平面收敛的第一步。当前我们要达成变更自动化,即不用再填各种参数了,只要通过git来的东西自动构建触发。
第二是变更代码化,整个过程不再用read me描述变更,而一定git代码的方式来描述。
第三是变更透明化,这涉及制品管理。通过这种方式完成了GitOps目标达成。
四、云原生智能运维工程体系
首先看当前运维工程体系的概览。我们最终输出的是运维产品。对内我们输出了飞天大数据的AI管控平台、专有云的管控;对外我们也做了SREWorks开源、阿里云产品控制台集成。应用SaaS这块,我可以用一个新产品的交付大概描述一下过程。
有六大场景,当我们交付一个新产品时,首先开服,然后做业务部署,完成了交付环节。交付完成之后需要对这些实例进行管理,监控他们到底正不正常,这时可观测、业务巡检、业务诊断就上来了。我们要提供针对这些交付实例的管理能力,以及预算管理,或者链路压测。同时我们还会提供容灾切换、故障自愈使实例能够做到非常好的运维管理。
完成这四个目标后,就会有一些运营商的需求了。前面这四块事情到底做的怎么样,效率怎么样,我们需要进行分析,这是第五块的场景交付能力。第六是面向客户的,产品到底怎么样,出了一个爆破,到底是故障响应,还是它只是一个符合预期的知识答疑、CHATOPS。这就是运维SaaS,是基于运维底座paas而产生的。我前面所讲的主要focus在基础运维平台和云原生运维平台。基于paas产生了SaaS后,我们做了这些场景。
到了智能体运维时代后,这六大场景都值得用智能体重新做一遍。我们把智能体工具分成两块儿。一是它是分析工具,我们以往所做的日志分析、指标分析、报错分析都能给智能体用。二是前面GitOps提到的配置管理,因为我们落地了GitOps, 使得我们把这些配置都能放在同一平面上。所以应用配置管理、集群配置、节点配置和容量配置都在一个平面上,使运维智能体能操作到。我还加了一个副标题,即智能体对个能力的可解释性提出了非常高的要求。我们之前做的工具和配置都比较零散,你在A工具里面有个变量叫做cluster,跑到B的配置里面就叫app了,人去管这个东西的时候,可以口口相传,或者做族群,但在智能体里就不行了。如果你对可解释性做了一些比较confused的事情,你会需要花更多成本在里面把事情说清楚,否则智能体会产生幻觉,把app用成cluster。
我们交付很多智能体后,对于智能体的一些工具也做了总结。什么样的工具适合智能体呢,大家可以看看。如果还没有到这一块的同学以后碰到了,也可以看,也有帮助。
我们认为一个普通的API或脚本在智能运维场景下没有优势。我们接了很多智能体运维场景,当我们把普通的API或运维脚本开发完后,感觉已经完成了百分之八九十的事情了。如果靠智能体的思维链推理脚本,无非是在外围调fls,根本不需要包,一个流程就搞定。所以到底什么样的工具才适合智能体呢?
我们总结了一下,大概有这样几块。
第一是Kubemetes API,它能够举一反三,通过Kubemetes CRD能推导出它的资源点,通过资源点就能知道对这个资源要怎么操作。所以它能让大模型很快的学习到它的使用能力,以及Kubemetes知识本身训练的时候都已经训练进去了。
第二是结构化配置,当我们把集群配置、应用配置放在一个文件数里后,这对大模型来讲,会非常好理解。比如第一层是class, 第二层是APP, 第三层是APP instance,你要创建一个新的实例,大模型可以翻APP instance列表,把以往的APP instance的配置进行参考,生成一个新的APP instance。这和人的操作过程非常像,叫你去开一个新的东西,你也不知道十多个参数怎么用,肯定会去看以往的参数怎么用,然后把它弄过来。使用GitOps之后,它的结构化配置对智能机有非常好的帮助。
第三是SQL,可能很多同学已经用过了。举个例子,比如某个机房出问题了,找到这个机房里面有多少个信用池、多少台机器怎么办?提出这个问题的人可能是一个不会写SQL的人,或者他并不知道这些数据放在哪一张表,这时智能体能直接能把SQL写完,把答案给你,完成整个过程。这是当前介入智能体运维业务过程中发现的,通过这些能低代码化、举一反三的工具,非常好的使智能体运维非常高效。
最后整个智能运维体系基于六大场景,当我们能够完成质量、成本、效率和安全,最后从运维生态中长出了智能运维。如果前面的这四个能力都不是特别完整,有很多时候你都会疲于奔命,会去解决成本的问题,或者解决稳定性的问题,根本没法把精力放在智能运维上。或者可能智能运维一进来后,反而会对成本或质量下降。
云原生运维社区有两个渠道欢迎大家来讨论。一是SREWorks,是一个开源产品,刚刚我讲的东西都能用到,希望大家试用。另外,就是我们的订阅号阿里云大数据AI技术,会定期在里面分享eBPF或者智能体相关的一些实践。