编辑推荐: |
文章首先介绍了云原生到底是什么?云原生带来的
DevOps 有什么技术挑战,围绕这些挑战我们会有什么样的新的实践.
本文来自于微信公众号 - DevOps时代,由火龙果软件Anna编辑推荐。 |
|
今天的第一个话题是我带来的《云原生时代 DevOps 的最新实践》,也不敢说最新,这是一个实践。因为你知道一个实践从开始构想到确立需要要在不同的场景去实践,证明这个实践是可以被复制的。
所以它需要一段验证时间。这个时间通常是在6个月到12个月,也就是说我们确立一个实践可以被复制需要至少
6 个月。
DevOps的书上看到很多实践都已经沉淀了很久,起码3-5年。是沉淀下来很长的东西了,所以我们今天讲的实践买书是看不到的,有些技术细节等一会儿我们可以讨论。因为时间有限,在众多实践我只选了我觉得几个比较有代表性的,他们代表了未来的方向。
1. 云原生是什么?
1.1 云原生背景和概念
因为 Cloud Native 的概念诞生有两三年时间,在最初没有云原生计算基金会的时候就有Cloud
Native 概念了。当时提出云原生概念主要是基于四点:DevOps、持续交付、微服务、容器化,但是在这之后出现了云原生的概念,有没有同学在
6月份听过我讲云原生的?有,非常感谢。在6月份之后,7月份 CNCF 也就是说云原生计算基金会已经修改了云原生的定义,已经不是那四点的组合了。
新的定义更加开放一点,我猜是因为 CNCF 要打包卖更多的东西。
这是比较完整的定义的中文版。上面这一句话可以理解为应用无状态化,只有你能做到无状态之后,你才可以构建一个弹性可扩展的应用,剩下的技术都是为了这个目标服务的技术。
第二条定义我们是构建一个反脆弱系统,所以需要两部分,我的应用既然可以进行无状态的可扩展、弹性扩展,我要在上面运行的时候就需要为各种失败情况做好准备。
我们把这两个概念拆解一下:
首先在私有云、公有云、混合云的环境下,因为之前最早讨论云原生的时候,它的概念里是不区分云的。我们有云之后就有公有云和私有云。这个区别是它在不在我的机房里面,我能不能管到它,所以现在我们在讨论云的时候,不仅有公有云,还有私有云和混合云。
你的应用程序是可弹性扩展的,它的意思也就是说你要为你的应用做好无状态化准备,可以随时进行扩展,而且减少失误、不一致性或者其中带来的问题。
容器,以前我们讨论云原生,就是 Docker,而现在说容器,还有其它的容器化技术。
最近流行的微服务 Service mesh、不可变基础设施等,这些是为这个目的服务的一些技术工具,当然技术还在不断的发展。我们在未来的云原生的技术实践发展里面,尤其是工具发展里面还是为了运行可弹性扩展而服务的。
后面两点是刚才说的第二条,构建容错性好、易于管理和便于观察的松耦合系统。这里面的一个重点是容错性好,如果是高可用前面就已经保障了,后面是一定要易于管理。
其实我们知道很多同学开始实践微服务的时候,你做微服务化的时候,你把应用拆解到一定层次的时候发现这不是技术问题,而是管理性的问题。你采用什么方式管理微服务中运维的复杂度、以及它们之间的关系、以及它们的版本之类的。
因为我昨天听到好几个朋友带来这样的问题,我怎么通过大版本发布微服务,这是一类管理性问题,但是我们通过技术手段解决。尤其在云原生的环境下变得更加复杂一点,基础设施容易了,但是管理应用更复杂了。
结合这两类技术之后就会得到后面的结果,能够轻松的对系统作出频繁和可预测的重大变更,频繁的变更以前可能一天部署10次、一天部署1次,这个系统指的变更是不仅你的应用程序,也包括你的基础设施。
我今天调整网络,我再调整我网络的时候的时候应用系统可不可以不受影响,是有办法做到的,我们等一会儿会介绍这方面的实践。
可预测对时间的要求比较高,可预测跟我们说的 AIOps 有点关系。但是这个可预测是基于资源和容量,即在保证上面的条件都满足的情况下,我如何做到这一点。
1.2 云计算定义
云原生意味着什么呢?下面有一行小字,我们在讨论云计算的时候,这个定义是谁给出的。你在 Google
上搜索到10个条目,大概会有11到12个对云的定义。现在比较公认的是美国国家标准语技术研究院的定义,它有5个特征:
按需自助的服务
低门槛的网络接入
池化的资源
快速的弹性化
度量的服务
这几句话比较抽象,我们来解读一下这5个定义到底是什么意思。
早晨我问大家有没有吃早饭是这个原因,就是为了放这张图。并不是所有人都喜欢吃火锅,但是有些同学看到这张图就饿了。
什么叫按需自助的服务,就是说当你有了云计算基础设施之后,你所需要的东西不是需要第三方支付的,比如说我可能需要一个系统管理员给我创建一些资源,而这些资源已经存在和运行了,只需要开发者申请,这就是按需自助的服务。也就是说,当你有了云原生之后,所需要的资源是开发人员可以自己按需获得的,不需要再去搭建一套数据库,直接调用这种服务,无论是在PaaS平台或者公有云平台上就可以达到目的。
就像你吃自助火锅不会去自己洗菜和切肉。都是加工好的,但需要根据你自己的口味再加工。
当然我们说到缓存和或者数据库太底层了,更高的会有一个比较抽象的应用。比如说我们需要一个负载均衡,负载均衡有硬件方案,也有软件方案。你需要负载均衡的时候,在云环境的情况下只是一个API,你就可以自己去创造这么一个负载均衡。
第二是低门槛的网络接入。在座的有没有运维工程师,见过这样的机房的举手,你们的机房是这样的吗?
这里有一个很重要的东西,在这张图片里面右边是线,在最开始做运维的时候是插拔网线、一堆交换机、背板、路由器,只要来了设备,我只要哪些是我的线,上面打个标志插进去就行了。我们曾经见过陕西省出口的一个对外网络,它就集成在一根网线上,那是很久以前的事情了,就这么一根线关联整个陕西电信网络对外的出口。还有一个东西是风扇,这个东西的散热性并不是那么好,别看它那么松散。
低门槛的网络接入就是在你以前使用云自己建机房最初级的时候是这样的,现在高级一点,大家缠蜘蛛网和拔蜘蛛网有一个经验,就会变成这样美观一点的,用不同颜色的线,把线绑得比较美观,做精细化的网线管理。但是在云计算平台上你很少能这么直观的看见网络了。
我们主要有一个数据中心,需要下面有一台风扇,也不需要机房建设、空调、防火、防潮。以前我在银行工作的时候管理过机房、也建设过机房,我知道要构建一个数据中心不是我一个人就能负担得起的,但现在想要有这个机房把自己的应用接入网络必须刷身份证,用支付宝交钱,你就能得到可以用的计算资源。这是低门槛的网络接入。
第三是池化资源。它是一个停车场,我知道东北有一个全国最大的停车场,什么是池化资源?我们都知道我们有一个局部性原理,在学操作系统和计算机原理的时候有一个局部性原理,也就是说你的计算机在使用的时候总是有一些空闲资源。
当这些空闲资源很多的情况下,被浪费的空闲资源就会变成很可观的浪费资源,我们能不能这些资源通过租户隔离租的方式给别人,他用完之后再归还回来。
池化资源的意思是有足够大的请求量、使用量和弹性空间,能够应对我当前所需要的需求。所以在这种情况下,你的构建机房和使用资源的成本会大大减少,这也是很多企业为什么要投入做云的原因。
有了池化资源之后,你的资源在当天使用的时候不一定在你所在的机房里面,如果你有机房,你的应用肯定在你的机房里面,但是如果是两地三中心的,你的应用在运行的时候,这个应用当前就访问A机房,可能到B机房了,因为哪里有可用资源,他会尽全力先把这些资源用完。
第四是快速的弹性。弹性我们都知道是水平扩展,什么是快速的弹性,比如说瞬间秒级的情况下可以并发产生很多资源。为什么需要快速的弹性呢?因为在云计算特别是公有云的情况下,很多流量是不可预测的。
比如说我以前在中国移动做大型机系统的时候,每个月都有一个出让期,出让期是在月初1号和月末最后一天,这段时间用户的访问量是非常巨大的。但是这个是可预测的,因为用户的访问量再大也不可能大于中国移动在一个省里面的用户总和,是有上限的。
但是在互联网不可能把全球或者中国所有人都点一遍给它增加一个最大的资源,而这个时间的突发访问比如说即将到来的双11就是很大规模的访问。
如果备这么大的访问量是没有必要的,像池化资源,你只要有这么多空闲,我只要能随时把基础设施和应用程序快速扩展起来,能够满足我当前的业务需求,使每个用户都有同样的体验,这个是很重要的。而这个能力在之前并不是很容易的能力,但是我们现在有了云计算平台,它一定会提供这样的能力。
第五是可度量的服务。前面几个都是环环相扣的,度量的服务是非常重要的一点,在大规模、不可预知、而且池化资源在随时变动的情况下,你想定位一个问题是非常困难的。比如说昨天腾讯做的AI
Ops,在这样的环境下你想知道究竟出现什么状况是非常困难的,所以需要每个服务都有一个度量的数据,可以让我们及时知道云上的服务应用基础设施都处于什么状态。
Cloud Native 带来的影响就是通过 DevOps,基础设施即代码这样的技术再一次降低了互联网化的门槛,如果你之前要把你的应用接入到互联网上,你需要有一个机房或者起码有一台托管的机器,后面慢慢有服务,但还是需要很多人需要有运维的知识、系统的知识、网络的知识才能做到。而到了现在的Cloud
Native,你可能只需要支付宝账号或者微信可以支付,你就可以立即获得这些资源。以前我们想构建一个互联网应用可能需要投很大一笔钱,而现在,任何一个中学生都可以完成一个互联网应用。
2. 云原生带来的 DevOps 新挑战
在现今这种状态下实践 DevOps 会有新的问题,第一个问题是我们所说的后 DevOps 时代,DevOps
时代是开发和运维,我们认为甲方管理资产、乙方开发服务应用程序的。我们会把这两个分开来,它不仅是组织上的隔离,也是生命周期的隔离。所以一个应用程序的生命周期是分裂的,
DevOps 就是要把这个重新分裂的角色完整的合上,让它变成一个完整的生命周期。
但是我们现在看到越来越少人关注运维是什么样的,因为我知道现在很多做 DevOps 的也不关注机房、也不关注网络、也不关注散热,我们更多的是通过软件定义基础设施的方式把你的基础设施当成一个软件产品进行研发、进行端到端的维护。
2.1 后 DevOps 时代
在后 DevOps 时代,我们的运维工程师和开发工程师团队就变成两个不同团队了,一个是应用程序服务团队。这跟我们以前的开发团队做的事情没有太多的不一样,只是要把应用程序上线后的修
Bug 归到自己来管完成了,这样带来的改变主要是从项目制规划到产品制规划,在项目制的规划下,因为要满足预算和时间的要求,造成质量下降和技术债。
而在产品制的情况下,一个软件会按产品路线图很好的规划,而这一部分,从以前的 Ops 团队的工作任务中被剥离了。现在的
Ops 团队也在维护着一个产品,就是对内的 DevOps 平台,这样一个团队要根据产品开发团队对基础设施的要求,并参与应用架构的设计。
在这种情况下,这两者之间就会形成一个断层,我们之前说的 DevOps 后面进行分裂就会变成这两类不一样的团队。现在我们很多企业开始用云、用
PaaS 就会有一个专门管理 PaaS 的团队,这个也是我们现在推出大中台的一个前提。
应用和基础设施的分界线越来越清晰。在后 DevOps 时代,写应用的时候关注运维的细节了,这些能力都被
PaaS 平台集成并简化。所以我们可以看到,基础设施已经慢慢把业务从技术层面剥离了,我们会发现我们的基础设施越来越厚,运行在上面的应用程序越来越薄。因为下面的东西越来越稳定,上面的东西变动越来越频繁,我们希望上层跟用户贴近的东西能够更加的灵活和轻便。
我们等会会介绍一个实践,看看我们怎么能够做到一天需求提出,我们在一天之内就把从需求到上线全部完成了。后
DevOps 时代的一个特征,我们的应用程序部分会越来越薄,程序员只需要写好代码,剩下的事情什么都不用管,剩下的事情会落到基础设施团队上。
2.2 软件定义的基础设施
在很多云环境下很多事情没有办法依靠人工操作,例如登录到一台机器里修改配置。你碰到大规模批量性的应用基础设施的时候,你需要自动化的方式实现。所以我们有了基础设施即代码,但是这只是我们在
DevOps 里的一个实践,而我们现在的软件定义基础设施更加的偏向于一个编程模型。
当你的基础设施和应用程序变成软件的时候,我们能不能用开发实践解决运维问题?现场做一个调查,在团队里面用
TDD 测试驱动开发的同学请举手,非常不错。当我们开始用云化 Cloud Native 方式的时候,你发现运维的同学会面对更多底层的编程操作,刚才那3位有运维的同学吗?没有运维的同学,都是开发的,有运维同学是做基础设施编程的吗?有,也有用其它语言的。这边是开发的同学,他们用TDD,运维同学没有用TDD。
讲一下历史,在软件发展的历程中,我们为了证明软件是正确的有两种方法,一种是形式化证明。很多人没有听说过这种方法,这是一种偏数学的方法,它的难度非常大。另外一种方法是怎么保证软件是正确的,这是测试反证法。
举个例子,有个人能吃 20 个包子,他自己说了不算,我们需要有 20 个包子来验证他吃过20个包子。他今天吃过不算,要每天吃才算,才能证明他是每天吃20个包子的人。自动化测试和TDD就解决了这个问题,第一是验证了他的能力,第二是持续自动化做验证,他就能每天达到这样的能力。
另外一点,我们这样的实践有很多,如果大家去年关注技术雷达就知道,我们很多基础设施的部分都可以做TDD,比如说在
docker 上面做了TDD,我们开发 docker 镜像的时候采用TDD方式开发。
我们的基础设施在规划容量的时候,我们采用TDD的方式先构建如何验证基础设施的测试,之后再实现基础设施的调整。当你面对的基础设施规模越大、使用越复杂的时候,因为你的基础设施都已经是通过软件定义或者代码定义的方式,你的基础设施的代码会变得很复杂,我们有了TDD就有了基础设施即代码的重构。
像我们刚才看到的机房一样,左边是比较凌乱的机房、右边是比较整齐的机房,我们要从左边凌乱的机房要右边比较整齐的机房,在以前的规划中是要新规划一个机房,把左边机房的应用和网络慢慢切换到这边来。我们现在在做基础设施的时候,一开始没有注重基础设施的网络规划和资源规划,它在你的代码里面一定也是非常凌乱的。你可以通过TDD的方式对基础设施即代码进行重构。
我的行为和验证方式是不变的,通过这个方式创建新的基础设施比较整齐的架构的时候就有了一个验证,可以让你更快的得到结果。因为我知道一些数据中心的网络重新切换大概会需要两到三年的时间,如果完成基于基础设施即代码的重构两三个月就完成了,你会得到更加整齐的规划更加合理的基础设施架构。
另外一个是基于基础设施和代码的解耦,大家知道微服务应用层面的解耦,但是基础设施PaaS平台慢慢会变成很大的一块。但是有一点,它的变化不会像应用变化那么频繁剧烈,而且带来更多的依赖性。
通过基础设施代码解耦解决什么问题?解决并发问题,比如前端做一个网站从前端设计到CDN到数据库到应用到底层实施,每一个部分实施变更的周期是不一样的,我们通过合理的解耦可以让大的问题变小、小的问题变得更快。
这样基础设施就更加有弹性,而不是来了一个应用需求说我的基础设施已经是这样了,更改太困难,或者没法改变基础设施。如果我动一点点,比如说大家用的共享存储,只要动一点点上面云计算平台或者PaaS平台的所有应用都会受到影响,这就是基础设施的大而不敢倒。为了应对这种情况,我们根据基础设施即代码,重新看待基础设施即代码,把它规划得更好。
在这种情况下,我们采用编程是面向资源的总架构,实际上你可以认为它是一种API,你的资源、磁盘、网络、负载均衡等很多东西都可以看作API资源。我通过URL访问它,它有这种架构,我们就可以通过状态机的思想对它编程。
每种资源都是不同的状态机,在不同的状态之间进行切换。如果你的计算资源,比如虚拟机是一个状态机。你部署上去的应用实际上是这个资源的一种配置。所以你要用状态和状态机分离的方式来看待你的应用程序。
从状态机管理的角度看,就是所有的状态机都有生命周期。生命周期里的每一个状态都需要版本化管理。而状态和状态之间的变化是通过事件触发的。状态机是不存储状态的,所以状态机可以水平扩展。但对于每个事件来说,它的上下文结果都是一致的。
举个例子,每个虚拟机实例实际上最开始的时候都是一样的。你通过触发启动或者关机事件让让他的运行状态进行变化。而这些变化的记录就是日志——可以通过版本化管理。操作系统也是这样一种状态,安装操作系统或者还原操作系统镜像就是一种事件,而操作系统镜像本身就是虚拟机状态的版本化存储。
2.3 回顾 Cloud Native 带来的挑战
首先,在后DevOps时代下,基础设施变得越来越厚,应用程序变得越来越薄。基础设施和应用都要求变动频繁的情况下,以前的
DevOps 摸清和 DevOps 的实践合作模式可能已经不再适用了。独立的全功能 DevOps 团队的可用资源很有限。我们要看到新的DevOps,新的
DevOps 是我基础设施端的 DevOps 和应用程序端的 DevOps,我们中间会有一个很明显的分界线。
我们现在大部分实践都是用 Docker,Docker 以内都是应用开发的,Docker 以外都是基础设施管理的,但是应用程序会越来越薄。而所有的运维工作会被按照风险和可用资源分成产品团队内部的运维和运维平台的统一运维。我们接下来所要讲的实践里面,你不需要关注环境怎么样,只需要把代码写好就好了。
然后是软件定义基础设施,我们的基础设施在云上、在PaaS平台上,在机房看到物理性的东西越来越少,用软件来解决的问题越来越多。我们可以开始用一些开发的实践优化Ops
的工作,Ops 更多的是规划处理的问题。
最后一点是我们在这种状态下,我们编程的方式和架构的方式已经发生了变化,它是一种面向资源的计算架构。
|