开发者学堂课程【ALPD 云架构师系列-云原生 DevOps36计:环境管理3阶段:从说明书到命令到说明式】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/82/detail/1273
环境管理3阶段:从说明书到命令到说明式
内容介绍
一、环境管理三阶段讲解
二、声明式业务操作讲解
一、环境管理三阶段讲解
环境管理分三个阶段,然后一步一步走过去的。可能很多人都经历过这三个阶段。就是像自己最早开始做这个事情的时候,就在第一阶段,比如说每一次做一个项目做一个产品的时候,会写整个产品的部署说明书、说明文档,包括升级文档各种文档,但是文档这个东西它很难保证,就是 update 的它肯定不一定是完全更新的完全准确的,所以那个每次要去客户系统交付的时候,其实会带着文档过去,但是肯定会遇到一些文档里面描述的问题,然后这个时候就得去问人打电话,看看什么地方有问题,然后再改。
所以第一阶段是文档,但是文档往往都是要更新的,很难做到非常好。比如说周末的时候买了一个新手机,是一部华为的手机,然后但是华为的手机里,他没有Google Play,要去安装 Google Play 的时候,只能去网上找资料,但资料里是一个一个说明文档,要按照他的文档一步一步去执行。
但是此时此时和写文档的那个人的那个时候的情节是完全不同,要再去配置,一样的环境给配起来的时候发现很难,而且基本上到现在还没成功,已经两天过去。
这是比较早期的一个阶段,就是说会发现编辑文档的人和执行操作的人,他不是一个人,而且你这文档是不可执行的,不可验证。因为这个文档它是要说明是这个软件的一个资金状态的,但是写软件的人并不用一定会去及时的去更新文档,同时写软件的人即便更新文档,这个文档是否工作,其实他没有办法得到及时验证的,因为他平常用不到。
第二个阶段就是通过命令的这种方式,然后写了各种脚本,然后把所有的命令组合在一起,作为一个批处理文件。
这个里面的一个例子是一个 example,但这个 example 其实是有真实背景的,就是之前自由化化交付的时候,就是当时在一开始的做法就是做这个事情,用file这个方式去写了一个脚本,发现每次要布一个新环境,实在太痛苦,就是花很多时间在改参数,找包,然后配各种各样的IP或者什么东西,那这样的情况下整个这个效率太低,那当然不希望没这个时间,所以就去写一个脚本去做这个事。所以这样的话这个脚本就变成代替文档的作用,用这个脚本就去部署,这是第二个阶段,但这个第二阶段还有问题说这个脚本慢慢就很多,因为要应对各种各样的环境,比如说它有的那个环境,它可能是三个节点,那是这种方式,那么另外话就可能是12个节点,那就得改,很难做到很好的适配。 可能还有一些网络上的差异,什么差异都会存在。所以到第二阶段就是会写一系列的脚本,然后为各种情况去做控制,比如说你要操作6个脚本,那这个时候你会发现写脚本或者维护脚本这个事一般都慢慢的开始希望有专人负责,比如以前就是实施团同学或者 OPS 同学去做这个事,那么慢慢的这个基础设施就开始变成运维的一个工作,对运维的工作同时包括去做自动化运维脚本这个事情,甚至于他会做一个平台。
然后这样的话,在开发是在前面,运维在后面它就是一个上下游的关系,然后它互相之间就是很透明的,你开发好的时候,你给的是一个一个镜像包或者说技术代码,那剩下的工作怎么把它布上去,有哪些安全策略,这些东西全部都是运维的事情。
就是说刚才说到以命令的这种方式,会发现其实维护这些脚本的成本其实是特别高的,而且它是相对来说是偏命令式的的话,就是说所有的东西可能在不同的场景里头,可能要写的命令是不一样的,那这种组合或者这种场景,此时复杂度就非常的多,写过这个就会感受到就是说经常发一个命令之后,要做很多的检查,这个检查是符合预期,然后根据不同的返回去做各种不同的判断,随着这个环境的种类越来越多的时候,这个复杂度会越来越上升。
第三个阶段,就是声明式的,也就是说从文档脚本一直找到现在按声明式的方式去配置的方式来定,表达的环境,然后把的环境给定义出来,定义环境,跟前面第二阶段最大的差别是,第二层面第二个阶段定定义做的是说做什么,比如说要配一个IP 地址,要把内存设为512兆,那第三个阶段是第二阶段是说定义要什么,比如说这个服务有两个副本,然后每个副本需要两个 CPU,然后可能一个g的,内存可能还有哪些网络的要求,那这个是给他定义的,就是定义的终态,所以在这个第三个阶段所有的那个声明,其实声明的是个终态,这个终态是什么样子的,那么怎么到终态这个事情并不会在的里面去把比如12345,该做一做二做三,做四做五,也不会说在做这个事儿,而只需要欢迎这个终态就可以,这个是一个非常大的一个改变,然后这样因为之前那个监督 cdn 时,当时 UCN 跟带宽有关系,其实很多时候需要在各个节点上去布那个服务,然后经常要干的是因为不同的节点它的成本是不一样的,有的贵的有的便宜,所以想要把那个应用布到哪个阶段上合适,然后会去经常维护一下,就是到底把这次部署布到 ABC3个节点,还是 DEF3个节点上,这个事情就会变得非常的繁琐,而且经常会容易出错,因为不知道它的整个最终效果是不是预期的,这个就是第二阶段的一个弊端,所以如果说只要定义说需要三个节点,并且三个节点它的成本是最低的三个节点,那这样的话的声明就很明确。
这个就是声命式的优势。简单的再去想一下,更多是把环境当做被怎么样的一个东西,要去操纵它,而声明式的更多是站在环境,或者说站在应用服务本身来说,需要什么,运行的时候是一个什么样的一个状态,需要把这个东西给供应声明出来,那么这里头的其实是两种不同的思维范式的一个很大的一个转变。
那做简单的一个总结,就是认为声明式的描述,它其实给一个环境的确定性表达,要提供环境的确定性表达,就是说这个描述是什么的环境。 那这是一个非常大的一个跨越。
二、声明式业务操作讲解
那么知道现在基本上所谓讲声明是其实都基于k8s来做,前面的练习也都基于 k8s 来做的。
那现在先看k8s整个体系它是怎么做这个事情的,就这张图上大概非常简单的画了一下 k8s 的一个架构,就是说左上角是 k8s master,然后左下角是 node,然后左上角的 master 可以看到 k8s 有好几个组件,首先它有一个 schedule 的一个组件,有一个 Controller manager 组件,然后有个 apso 的组件,同时它有一个 Etcd 是一个存储,就是分布式存储,比如说各种各样的配置信息其实,都是存在 Etcd 里面的。
node 就是真正的物理机或者虚拟机,和 node 通信是通过 A PI server 去通信的,那在每一个 node 物理机上其实会遇见很多个 pored,然后 Porte 上面会运行很多的容器,这就是它的一个最简单的一个架构的样子。
K8S 的那个一个最小单元是一个 port,那么看到port里面会有容器,也会有各种像网络存储这样的东西,一般就是 KK8qq.com.q
,然后 apply 给他一个文件,然后就完成,然后剩下的事情可以自己做,他其实这个事情就是在 contrller 这个层面去处理这个事情。 右下角看到伪代码,是contrller 这个是说监听一个变化,比如说 apply 里面有一个变化,那这个变化就是告诉他是一个期望的状态。那么 contrller 那边就会去看现在是什么状态,比如现在的那个节点是一个,但是期望有三个,那就会想是不是要去再扩两个,他就会去逐步的去逼近这个目标状态,那么等他达到目标状态的时候,就停下来,所以它整个那个过程其实是一个逐步逼近的过程。
给他下发了一个声明,然后他去把这个声明,慢慢的逼近声明的条件和声明的状态。 所以说其实你的环境的一个定义是面向终态的一个定义。这个是非常主要的一个特点,就跟之前的各种运维的手段特点是鲜明的,就是面向终态去设计的。
上图尝试来讲的是还是 Top 这样的一个概念,其实也是在部署的过程当中,这张图就是这个摩托车在德国很流行。
上面就叫长江750,都知道长江750可能最早的时候就是跟二战时候德国宝马的那个摩托车是非常像的,因为它是中国当时就改解放后,就仿照的苏联的一款摩托车,然后苏联那个是仿照德国的,那么现在全世界可能只有中国还生产这样的摩托车了,所以你会发现就是在一些国际站点上,很多外国人会跑到中国来去买这个车,然后通过海运运到德国,因为他就要寻求那个当时二战时候那种复古的感觉。但这个车有个特点,就是三轮的。这种车这个对旁边有个挎头,这个挎头就是摩托车外面又多了一块,如同 colletor。就是想一般在一个应用开发的时候,写一个应用,然后应用发布发到一个容器里,但事实上这个应用里面大量的代码其实不是业务代码,比如说服务器的相关东西,比如日志模、监控,限流,垄断各种各样的,这种代码是占了很大的比重的。 不管可能用这样的框架,其实也会有这样的问题。就是这里有很多这样的代码,而这样的代码它的维护者和升级节奏跟应用开发者其实不是一拨人。
通常情况下像阿里这个中间件肯定会去做这些事情,然后可能有些公司可能是自己有专门的架构团队去做这个事情,那么他们有不同的节奏和关注点。那如果是传统情况下,其实如果要遇到这样的问题,其实需要整个升级应用本身的才能达到这个效果的。
但是在云原生这个时代,其实现在的通常的做法其实是把它分离掉,所以首先分离掉就是说这个应用容器,应用开发者关心的是应用业务代码,当然这些服务治理相关东西,是放到其他的容器里的,编排在同一个 port 里面,但这个容器的管理开发和发布都跟没关系,这些就是属于叫 colletor 容器,colletor 容器是可以通过注入的方式或者在你的团队上去配置的方式放到的那个 Port 里面跑起来,那这样的话就实现了一个关注点的一个分离,就是说作为应用的开发者和的中间件的开发者,以及一些业务的运维相关的一些开发者,那可以有自己的关注点,而不需要互相之间就是互相和协在这个地方。
这里可以举两个角色,比如说你是一个业务的开发者的话,你关注的是这个应用的容器,所以说你的发布的节奏也好,你的所有的东西,关注度都在发布融资这一块,应用这一块,而如说你是一个运维同学的话,或者无论是应用运维也好,或者说是基础设施应用也好,那你基本上相应的关注点会在这一块,你在这个 port 里相应的服务存储的一些东西,你有你自己的节奏,那这样的话大家的关注点就分离开。 而且分离开来还有一个好处就是说中间件下沉,下沉之后都可以用 colletor 方式来去管理,那么这样的话你比如说一旦遇到相应的一些中间件需要升级这个时候你的业务代码不需要做任何改革,只需要将 colletor 进行升级,确立关注点的几点就是一致的环境,它需要有三个组成部分,一个是相同的制品,一个是相同的运行上下文,还有另外相同的编排规则。
其实相同的运行上下文,其实其本质就是有很多相应的一些配置,那其实到传统文档式要按脚本的这种方式,脚本的方式有很多,可能会写很多很多的脚本,然后针对不同的场景应该是可以营销。
然后所以说到的声明式以配件文件的方式来去保存,但是声明式的方式其实在过程当中及时发现,所以声明式的方式是不是特别完美的,其实是声明式也存在一些问题,就是每一个新技术的引入它都会带来好的地方之后,同时会带来一些成本。
举一个很具体的例子,就是说声明式的方式的话,可能针对应用它应用运行的时候,它需要相应的一些配置,那中间件选一下相应配置,然后的基础资源就是的CPU,的存储,比如说要 SSD 存储,本地 SSD 还是远程 SSD 还是什么,这种存储也会有一个配置。