@gaoxiaoyunwei2017
2020-06-03T17:55:59.000000Z
字数 8347
阅读 809
彭小阳
作者简介
王昕,来自阿里云开放平台团队,具有10多年软件系统开发和架构经验,在自动化运维平台、云原生平台和分布式系统领域经验丰富,长期参与云平台管理系统和云原生自动运维系统的设计与构建,有多年OpenStack 、Kubernetes、OpenShift和Terraform等开源平台和工具的实施经验,在国内外有 10 多项授权和在审软件技术发明专利。
我们团队主要负责阿里云对外的开放 API,以及阿里云所有的基础人财物权法的企业IT管理功能,包括登录到云上、身份认证、登陆以及云上管控哪些资源,权限管理、计费、分组、打Tag ,所有的人财物权法的资源管理,都是在开放平台。
云上所有的能力通过console(控制台)是远远不够的,很大程度需要通过原生API把我们的能力暴露出去,让开发者和合作伙伴可以通过API集成云上的能力,这样可以把相关能力自动建设在弹性的计算基础上。
今天主题尽量紧扣运维的主题,云计算时代的基础设施即代码,但是这个题目为什么给改成 Ansible,一会儿会提到。
本文主要介绍四个部分:
最近这些年接触了很多国内尤其是一些中小公司,如果不是很技术驱动型其实运维还是比较偏传统,即使在阿里云上买了虚拟机,可能也是在用传统的运维方式把虚拟机和物理机一块运行。
云计算出现的背景正符合当今业务变化迅速的背景,云上弹性的能力用的非常好,云原生技术,基础资源变化快,计算容量大,我们基础设施运维的目标是什么?就是支撑上面的业务。
我们整个IT可以分两块,一块是应用,一块是基础设施。基础设施是提供资源能力,主要作用就是快速高频的应对业务的需要,但这种变化带来了要求,因为作为基础设施要给上面的应用提供稳定的环境,如果基础设施不稳定,上面的应用就没办法平稳运行。
所以说这里面其实是最主要的一些挑战,包括安全性、性能、稳定性、合规性和可维护性,在基础设施上一定要弹性情况下提供稳定性。
这是我们最常遇到的一个问题,我们搞运维,同时也搞开发,遇到基础设施出现了很多不一致的情况怎么办?每天都是手动变更写脚本,机器都不一致了,这个时候才想起来,我的基础设施配置不一致了。
什么时候做一个系统,利用一个自动化系统维护起来,保证一致,等你把自动化系统基本模型写出来了,代码做好了,这个时候要开始自动化上线了,上线的时候又担心,完全自动化还是不可靠的。
2008年奥运会时候,张艺谋说当时团队有自动行走系统,但最终需要有一波人去保卫,真正上线的时候还得有人看着,自动化上去以后,又担心一下会把变更做的非常大,所以要手动去变更,这样就造成了基础设施不一致的循环。
怎么解决这个问题?我们以前的自动化基础设施自动化,往往都是写脚本的,你的里面有很多复杂的逻辑,靠程序逻辑写,而其实我们今天也有不少同学谈过这个问题,我们能不能只把我希望的目标写上去,写的非常简单,就是一个配置文件,配置上需要哪些网络设施、服务器和存储,系统保证自动实现这个功能。
基础设施即代码有 Wikipedia 和 Gartner 的定义,首先是说我们有一个定义配置文件,这个配置文件配置了基础设施,基础设施不是指一般的服务器上装了哪些版本的软件,而更多是指传统物理版本,有几台服务器,网络和存储是什么样。
第二是自文档化,即基础设施即代码的编排语法,基本上是yaml或json,看到这个代码就能明白含义。
第三是版本化,基础设施即代码可以用版本变更保护起来,同时还能够实现支持上层业务的持续部署和测试。
最后是前面提到的怎么样保护和防止自动化不会出现问题,能迭代变化,这其实也是通过基础设施即代码,把你的需要通过代码维护起来,这样的话其实做自动化,如果没有用版本维护这种方式保护起来,其实并不是一个能够稳定的实现自动化的这样个流程。
这是我们另外一种说法,配置管理,配置管理有软件的配置管理和服务器的配置管理。
过去最早提配置管理,往往是软件开发里面的配置管理,说你的代码是用配置管理,用 Github 或各种版本管理措施管理起来。现在的云计算时代,不仅代码用版本管理管理起来,而且基础设施的配置需要几台服务器,也需要维护起来,这样才能应对基础设施变化的稳定性。
这张图是 DevOps 的流程,其实在 GOPS 会上有很多 section 都在讲 DevOps,DevOps 的理念是提升开发与运维之间的沟通,其实有一种重要且稳定的沟通渠道就是开发者喜欢用代码来沟通,有时候说不清楚的事情反而通过代码能沟通下来。
这其实是基础设施即代码的概念,在软件的生命周期中,编译->部署->基础设施都是用代码来定义的,
我们的源代码表示应用的逻辑,持续集成或者说 DevOps 的流程,是通过 DevOps 的引擎,流程引擎代码定义的,比如 Jenkins 有Jenkinsfile,Github 有 Travis 类似的语法。
代码编译完之后需要一些打包的工具,比如 dockerfile可以把编译结果打包成一个可部署的,通过镜像定义;部署到实际的应用环境当中,需要一些PaaS编排文件,比如 Kubernetes 的编排文件;Openshift、CloudFoundry也是类似。Spinnaker 是做持续部署的,把已经准备好的应用的这些镜像在运行环境当中做应用编排,同时这些 PaaS 服务也会在自动触发一些在云设施上创建这些基础设施。
而 Ansible 和 Terraform 是定义基础设施资源相关的,首先第一个基础设施的定义,我们主要是如何编排,我们给上层应用提供这些计算、存储和网络的技术资源。
Terraform是开源的基础设施编排工具,支持多云。下面的这些基础设施编排语言都是各个云厂商自有的,ROS是阿里云的编排语言,Cloudformation是AWS,Heat是OpenStack的编排语言。这些资源准备好了之后,我们可能需要对这些资源做一些配置,更改上面的软件和系统,这就需要我们前面的现在经常做运维同学用的比较多的开源工具:Ansible,Puppet,Chef,Salt,这些工具在基础设施的基础上做软件的管理和配置。
Ansible,其实我们现在做基于开源也好,或者做各种技术,其实技术趋势是非常重要的,今天下面听到一个说法,对于云计算,过去你爱搭不理,今天你高攀不起,从 Docker 刚出现的,Kubernetes 也经历过这些过程,现在我们看到对于基础设施配置管理趋势,Ansible 是持续领先,非常高。
还有是 Terraform 在悄悄崛起,已经超过了除了Ansible以外的其他工具,这也是为什么题目可以改成Ansible。我一开始想介绍这个,另外一个想更突出的介绍一下Terraform,这个可能了解的少一些。
Ansible 确实还是作为系统作为软件管理还是一个最大的社区,对比和传统的Puppet 系统,贡献者分布非常平均。Terraform作为基础设施即代码,已经崛起;Ansible大家了解的比较多,是Redhat的开源工具。主要做IT自动化,也做基础设施即代码。Ansible有两个特点,一个是无agent,不需要往机器里装代理;另外一个No Script即声明式,这样可以减少错误。
简单即合理,用Ansible的人越来越多。Ansible的主要架构如图中所示,主程序是Python实现的,左边的Inventory是主机的配置机制,Playbook是流程配置的机制。核心有两块,一个模块和一个插件,插件是在Ansible的control端做功能扩展的,moudle 在远端执行脚本的,可以连接不同的主机进行配置。
Inventory 的功能就是用来配置服务器的设备信息,有不同的模式,最初 Inventory 很像一个 host 文件,可以配置主机地址,可以支持一些主机组,后来也支持 yaml 格式 你可以给他做一些属性的特别配置,默认web.example去连接,可能是 22 端口。为了防止别人攻击,更改一些端口,下面可以通过一些属性做特别配置。
Playbook 是在远端执行脚本的Module,是yaml格式声明式的语言,在这个截图中我们可以看到第一个有一个hosts字段,这个字段指定操作和配置要到远端哪个服务器执行,在上图的 Inventory 里声明过 dbservers 指向哪些服务器,在远端使用什么用户名(dbadmin)。下面是一系列的 Ansible 任务,每个任务对应了 Ansible 中实现的 module,自己定义了很多核心 module,但是也允许开源社区自定义软件包管理。
这里怎么体现呢?是一个声明式的,不像你用YUM命令式执行,目标让这个软件达到什么样的版本。对于执行命令,后面是一个文件,执行顺序是在同一个主机当中会按照task列表,按顺序进行执行,多主机之间可以进行并行的。
这是一个Ansible Modules,yum 对应了使用过程当中通过这个使用,但是扩展要在Ansible Modules扩展,还有就是改变文件属性。
这是一个阿里云上扩展的一个Modules,交换Cloud Modules,做基础设施即代码的实现,我们可以看到实现了什么样的能力,实现的能力就是这个名字叫做阿里云的ECS的实例,实现这个实例之后,定义了一些相应属性,定义属性之后我们可以通过阿里云上的这些对于机器需要的属性。
定义好之后一键启动,这个模式会帮你自动创建阿里的ECS机器。当然整个代码都是开源的大家都可以去看,也欢迎大家在上面开源社区贡献你的代码,这里会生成一个Modules。
完成了Terraform这些基础设施编排工具同样的能力,我们前面提到了,Ansible其实是做配置管理和主机上软件管理的,但是也可以用来编排基础设施,但是目前来说,其实作为基础设施即代码的这个方向发展并不如Terraform好,但是也是有这个能力的。
接下来介绍一下Terraform,Terraform是一个做构建变更和版本化关系基础设施,特别是云上基础设施的工具,这个工具最近这些年,特别是国外厂商已经成为他们默认的进行云上资源管理的一个工具。
这里面首先是实现基础设施即代码,另外一个Terraform有一个非常好的能力叫生成执行计划,生成执行计划这个很像所有声明式的语言都有这个能力,这些DB的管理系统都有这种能力,声明出来我希望达到什么过程,你的引擎帮你我生成一个执行计划,告诉我怎么执行。
Terraform 有 plan 的能力,在变更前可以运行一个命令,Terraform plan,你希望搭建的基础设施怎么执行,会模拟执行一遍,看到整个过程是否符合你的预期,这是一个Terraform的特别的能力。
并发执行。速度非常快,对于不同的资源会自动解析出来资源之间的彼此依赖,可以对需要和不需要有依赖性的资源并发执行,自动创建。
变更自动化。通过Terraform声明式脚本语言进行维护。
这是Terraform的系统架构,主要是三个部分,第一部分是Terraform的内核,Terraform的内核会读取基础设施的定义,属于一个脚本语言,也是声明式的,非常像一个配置,同时会读取Terraform的对应资源状态,生成一个当前资源视图,确定有哪些任务进行变更。
这里面执行能力是通过两种插件,一种插件是Provisioners,另外一种是providers,对应的是不同基础设施提供者,对应各个云厂商的openAPI,整个性能非常好。
下面就是每个providers会对应每个云厂商的openAPI实现了什么功能,当你用云厂商的openAPI管理设施的时候,你其实用了命令式的格式,所有的逻辑判断都需要你的各种条件做判断,但是Terraform把这些逻辑实现在内部,对于用户来说只需要做声明式的变更就可以了。
Terraform的核心概念,第一个概念就是Terraform因为要实现声明式的能力,所以必须要保存实时当前对应的资源状态,因为我们经常说要事先声明式的配置或者说引擎的话,要区分维护两种状态,一种叫做目标的状态是什么,另外一种是真实的实现了的状态是什么。
要比较两者的差异,这个过程都是Terraform引擎来实现的,所以要保存两个东西,当时刚才说的目标状态是什么,就是配置文件,就是我们说的基础设施即代码,那份代码就是目标状态,同时Terraform系统必须要保持所管理的资源实际状态,在文件当中保存。
当然这个只是一种,保存状态其实作为Terraform有多种后台,后台用来保持Terraform运行资源的状态,有两种后台,一种是本地后台,一种是远程后台,本地后台其实用在本地文件上,当你个人用Terraform做管理的时候,就适合用本地,这可以看一下。
这是一个例子,本地Terraform的文件,其实是列举了所有的当前状态,同时如果说是一个大的团队做基础设施即代码的维护,可能需要对整个资源要做统一的维护,要共享这些状态,这个时候就需要一个远程的,需要一个服务端的保存状态的,这个时候Terraform也支持保存在远程服务器。
最常用的AWS,S3,阿里云的对象存储上面可以保存Terraform的状态,但是用的时候只要把后台配置成远程服务,就可以在团队当中共享适合于团队工作的场景。下面是对接不同的云厂商资源管理的API,比如说阿里云、AWS、后台的这些API,这当然也是开源的,这是一个例子,这是实现我们阿里云Provider的代码,在上面可以定义新的Provider。
这一点刚才说了,当你用这个的时候会实现这样的Provider,但是你作为整体的Terraform的语法,只需要一套就可以了。创建资源以后可能要做一些预先配置,支持两种,比如说远端的执行,也可以在本地执行,现在默认的支持官方local还有file的执行器。
你也可以用Ansible原生执行。也可以用本地执行实现Ansible调用,可以用本地安装一个Ansible,然后在本地调用local exec,当成Ansible的控制器,远端再配置服务器。
这里有一个技巧,在执行local exec为先定一个远端执行,要告诉你有一个依赖的关系,根据这个依赖关系,保证远端服务器建立连接的,如果没有上面远端服务器,很有可能你的远端服务器还没建起来,可能连不上,所以说这里有一个小技巧,把上面远端服务器先连上,再用Ansible去连就可以了。
这个就是我们前面介绍了一下,我们的Ansible和Terraform,这些基础设施即代码的技术,这里面引出了一个趋势,就是命令式和声明式的区别。
我们可以看到同样在阿里云上创建一个ECS,这个虚拟机依赖很多环境,首先要有一个模拟的网络环境,网络环境下可能要建一个交换机,还要依赖一些存储,比如说一些硬盘,他们之间是互相依赖关系的。
如果说用一个命令式的代码,你自己写脚本,或者说API去调,这里面就要实现一个算法,创建完了要写代码等一直监听,看到ECS已经起来了,然后我再往前创建,所有这些逻辑都要用代码实现,用Terraform不需要了,需要写什么呢?只需要声明,你需要阿里云的ABC,需要交换机。
你会引用某个交换机,当你只要在代码里面引用了变量的时候就会自动解析出来你会依赖这个资源,会子对解析出来你对资源的依赖数,根据这个资源的数,按照合理的顺序帮你并行创建起来所有资源,这可能就是前面说的执行计划,我只声明我想要什么,里面一些依赖关系的计算,和计划是由引擎帮你计算的。
这也是基础设施即代码的趋势,大家越来越喜欢用的最重要的原因。这是我们说的我们现在常用的配置管理和自动化运维的工具简单的比较,里面大家比较熟悉的应该是chef、Puppet、Salt、Ansible,这是在云服务器上做配置管理的。
Ansible是声明语言,社区也是非常大的,非常大的开源社区,目前来说整个发展趋势还是相对于Ansible来说还是弱很多,Ansible本身既支持服务器配置,也支持制备服务器,创建虚拟机和网络的能力,但是我刚才说到了虽然支持,但是在制备这块,是较弱的,不是最强的。
接下来的四个主要作为制备的能力,CloudFormation,Terraform是开源的,支持所有常见的公有云。你把Terraform+Ansible去做,如果基本都是用基础设施,用镜像就能解决的这些配置,就可以直接用Terraform,如果说除了启动虚拟机以后还要做一些特殊更改,可以加上Ansible做两方面的配置。
这是我们列举了根据网上的一些调查,TOP 5的原因,选用Ansible和选用Terraform。选用Ansible的TOP 5的原因,不需要agent,现在Ansible已经是配置管理的带民此。配置管理的代名词,Terraform是基础设施即代码的代名词,同时非常明确声明式的语法。
Ansible也是声明式的语法,本身对于依赖检测并没有默认资源检测的模型,这往往不能保证你使用起来爽,很多东西自由扩展的时候不会做的非常优秀,这块声明式语法是Terraform最明显的,可以自然实现计划。强有就是执行前的plan功能,会把执行计划显示出来,使用简单,同时是并发执行,执行效率非常高。
后面简单介绍几个案例,创建VPC资源,声明VPC资源,这是创建一个交换机,创建一个安全组,一旦建一个模板基本就知道了,如果用代码的话就更麻烦了,因为要判断很多的条件,创建交换机,这是创建Ansible,但是可能不如Terraform做的那么丰富。这是用Terraform来部署一个Web集群,这个语法比刚才的更简单简洁。
简单介绍一下最佳实践,一定要命名,比较容易找到,因为所谓的自描述,基础设施代码希望自描述,如果不写文本解释的话别人就看不懂了。还有Ansible是支持在代码里写比较复杂的属性配置,但是不建议你这么写,尽量用yaml语法直接实现,还有就是注意不同的Linux发行版语言可能是不同的。
这其实也是另外一个方面,Ansible 作为声明式语言,因为你对不同的发行版的命令是不一样的。这些最佳实践,最好先用 check - mode 检查一下,看命令是否都写对了,然后再做配置。
这是Terraform的一些小的命令和最佳实践,比如说很多时候你的参数特别多,希望你的Terraform脚本特别简洁,不需要把这些环境和变量全部定义到Terraform文件本身里面,可以用var file引进进来。
还有就是说尽量在基础设施即代码的过程当中,尽量用不同的东西把不同的环境,不同的维度不同的环境都隔离开,比如说有些可能是应用的环境,有些可能是本地的一些变量,有些是不同资源,都用不同的环境变量去代表。
另外一个最佳实践,Terraform里面有很多比较好的命名,刚才说了Terraform plan可以进行格式化校验,fmt可以帮助你把Terraform文件格式化出来。最后是现在生产环境基础设施管理的一些常用的任务,我们也和我们常用的一些开源的一些工具有关系。
第一个安装软件依赖包,撇之也是用这些工具,制备我们用来配置服务器网络存储和负载均衡,这些是云上的编排,开源跨云的是Terraform。部署是把我们的应用部署到云环境当中,或者说基础设施上,以前部署依赖于脚本,K8S是一个声明式的脚本,你只需要声明启动几个就可以自动帮你实现。
如果你过去错过了K8S,你今天不要错过Terraform,这也是必然在云上基础设施运营一定要使用到的。在安全领域有很多安全管理的开源工具,SAML和Oauth是SSO的标准,vault也是一个管理工具。
最后简单总结一下,我们用这个基础设施即代码,可以实现快速简单,关键是配置一致性和风险最小化,提高我们软件的开发效率,节省成本。我们的开放平台对于这些开源工具都支持还是比较好的,对于Terraform和Ansible在通过这些工具自动在云上编排你的资源,都是有很好的支持。
同时我们在阿里云上我们有一些工具,直接把工具安装好,比如说命令行里,包括Cloudshell,可以把你需要的Ansible、Terraform工具自动帮你安装好,同时我们还有一个可视化的编排各种API和命令的工具,叫做逻辑编排,通过这个可以把你的API自动组合起来。