Everything as Code 一切皆代码?
文章来源:DevOps
作者:冬哥
1
部署经历过三个阶段的发展
单体结构部署的过程,较为简单,通过手工操作就可以完成。
随着分布式应用的普及,出现了很多自动化部署工具,采用脚本的形式,按照提前准备好的逻辑,按序执行部署。
以应用为中心的微服务快速发布的诉求,通过流水线出发部署任务,实现标准化,版本化的部署。
传统项目中,采用开发人员手动部署的方式,每次需要发布、更新都要远程连接到服务器上,手动地部署新版本。
存在的问题是:
容易出错、效率低。
依赖人员、耗费大量人力成本。
流程繁琐、操作复杂。
对于机器集群部署服务实现困难。
所以,在随着公司的业务的不断扩大、项目迭代速度变快,实现自动化部署显得尤为重要。自动化部署是将可交付产品,快速且安全地交付用户使用的一套系统和工具。系统会自动构建、测试并准备代码变更,以便将其发布到指定环境的过程,包括开发环境、预发布环境、生产环境等。
2
一切皆代码,Everything as Code,这个说法最早来源于基础设施即代码Infrastructure as Code。
基础设施可以代码化,通过脚本来定义;环境也可以通过Dockerfile进行定义,进而将环境代码化;在此之上进一步将环境的编排、环境配置信息、数据库结构和数据、测试用例/测试数据/测试环境、流水线的编排以及文档均可代码化和脚本化,从而实现(几乎)一切皆代码。
一切皆代码的好处在于:一旦代码化就可以版本化,将其纳入版本管理系统,纳入统一的分支管理模式,从而将代码与其需要的基础设施、运行的环境、环境上的配置、配套的数据库和测试等等一切,通过统一的一个基线打在一起。当版本发布时,构建出来的二进制包与其依赖的所有环境信息全都是打包在一起的,就不会出现“在你的环境上可以运行,在我的环境上不行”的情况。
代码化(脚本化)的另一个好处是:可以通过自动化的方式来驱动,从而实现一致性和幂等性。所谓幂等性就是无论是何时何地在什么样的基础环境之上,都可以根据脚本的描述构建出同样的一套环境出来。这样就可以解决环境和配置不一致的情况,而大部分的部署错误都是因为环境和配置信息导致的。
一切皆代码实际讨论的就是自动化,利用自动化来处理繁琐的工作,从而让“痛苦的事情反复做”。
3
自动化不仅对于管理、更改和调整IT基础架构至关重要,同时对于你的业务流程运作的方式也至关重要。通过自动化简化变更,你可以将时间和精力专注于创新。自动化的目标是更快地确定性的完成工作,这让IT人员能够专注于解决更大的问题。
自动化并不一定意味着要取代人,重点和优势在于提升生产力、一致性和效率。随着你采用自动化变得富有效率,人工参与变得更为重要但并不那么频繁。
自动化不是一种消除工作的工具,事实上它让更有经验的 IT 员工能够专注于更大的问题及其解决方案,而不是平凡的、日常的、重复的任务。
自动化是迈向CI/CD快速向客户发布新软件能力的关键一步,包括基础设施配置的自动化、新系统的构建、软件部署和从功能到安全合规性一系列的测试。通过自动化所有这些步骤,可以比以往更快、更安全、更可靠地部署软件。
Joseph Bironas,负责Google数据中心集群上线流程的SRE,有力地提出:“如果我们持续产生不可自动化的流程和解决方案,我们就继续需要人来进行系统维护。如果我们要雇佣人来做这项工作,就像是在用人类的鲜血、汗水和眼泪养活机器。这就像是一个没有特效但是充满了愤怒的系统管理员的Matrix世界。”
节省时间经常被用来解释自动化的价值,尽管我们经常以此证明自动化的重要性,但是在很多时候这还不是最重要的,更为重要的是可以更快地交付和更快地迭代,以帮助你更快地实现功能。此外一个很容易忽略的事实是,一旦你用自动化封装了某个任务,任何人都可以执行它们。时间的节省适用于执行该自动化的所有人,其更大的意义是将某个操作与具体操作的人进行解耦。
自动化意味着:
生产力:员工可以花更多时间对业务产生更大的影响,将重复事务留给工具。
可靠性:通过减少人工干预的数量,会更少的发生疏忽和问题。所有相同的事情都以相同的方式发生——每一次都是如此。你可以准确地知道流程、测试、更新、工作流何时发生,需要多长时间,并且可以信任其执行结果。
可控性:代码化一切意味着更好的控制力,更多的人工参与意味着更多的信息不对等,无法预知涉及什么或谁。
一致性:任何一个人或者一群人执行数百次动作时,不可能保证每次都用同样的方式进行。这种不可避免的不一致性会导致错误、疏漏、数据质量的问题和可靠性问题。通过自动化可以规避上述问题。
平台性:通过正确地设计和实现,自动化的系统可以提供一个可以扩展的、广泛适用的,甚至可能带来额外收益的平台。
4
对基础设施的要求:更快的响应速度,更加灵活的使用,安全可靠可信赖。基础设施即代码的目标就是通过可重用的代码来实现IT环境变更的自动化,并通过可信的研发流程来保证一致性和安全性。
基础设施即代码,Infrastructure as Code,坚持IaC,是用代码、脚本或配置文件来声明应用系统所需使用的基础设施资源,从图中能够看到,基础设施包括应用堆栈底层的计算、存储、网络资源,以及虚拟化能力。一旦采用了环境定义脚本,实现对环境的控制后,需要将环境定义脚本纳入版本管理中,并且之后所有的环境变更都应该先修改环境定义脚本,由环境定义脚本触发。
Chef、Puppet、SaltStack、Ansible、Terraform等,是我们经常用到的IaC工具,我们以Ansible为例来描述基础设施即代码工具的使用。
Ansible是一款开源的轻量级的自动化运维部署工具,可以使用它来自动化任务部署应用程序,实现IT基础架构。Ansible可以用来自动化日常任务,比如服务器的初始化、配置、安全基线配置、更新和打补丁系统安装软件包等。
相比起其他几款工具,Ansible更轻量级,是无客户端的,仅需通过SSH连接客户机执行任务即可。
Ansible有控制节点和受控节点,控制节点即安装了Ansible的主机,也叫Ansible服务器端管理,主要用于发布运行任务执行控制命令,Ansible的程序都安装在控制节点上。受控节点,也叫客户机,就是用Ansible执行任务的客户服务器模块。
Ansible的架构如下:
Ansible:核心引擎。
Connection plugins:Ansible基于连接插件连接到各个主机上。
Host inventory:定义可管控的主机列表。
Playbooks:按照所设定编排的顺序执行完成安排任务。
Core Modules:自带模块。
Custom Modules:自定义模块。
Plugins:完成模块功能的补充。
Ansible现在默认自带450多个模块,Playbook剧本是利用Yaml标记语言编写的可重复执行的任务的列表,Playbook的优势包括:可读性好,和脚本语言的交互性,脚本模块化,配置灵活,每个步骤都配有名称,方便查看结果,易于实现。
基础设施即代码是DevOps最核心的实践之一,也是一切皆代码理念的源头,我们将有单独的章节来详细描述,在此不做赘述。
5
Dockerfile 容器镜像构建
基础设施的计算、存储、网络,还不能构成应用运行的环境,在基础设施之上,还需要操作系统OS、中间件、数据库以及运行时所需的其他依赖资源。环境即代码就是在IaC之上进一步构建应用所需运行环境的实践,以往通常采用虚机,云原生时代当然是Docker。关于Docker的由来,以及为什么Docker会成为主流,我们在云原生架构部分已经阐述。
Dockerfile就是容器镜像构建文件,也即是环境描述性脚本。Dockerfile是包含若干指令的文本文件,可以通过这些指令创建出dokcerimage。Dockerfile文件指令集,描述如何自动创建Docker镜像,DockerFile中的指令执行后,会创建一个个新的镜像层。
Dockerfile一般由4部分组成:基础镜像信息,维护者信息,镜像操作指令,容器启动指令。
Dockerfile常见参数有:
FROM或者FROM:基于哪个镜像,首选本地是否存在,如果不存在则会从公共仓库下载。
WORKDIR:切换目录用,可以多次切换(相当于cd命令),对RUN,CMD,ENTRYPOINT生效。
RUN:执行指令。
EXPOSE:EXPOSE指令告诉容器在运行时要监听的端口,但是这个端口是用于多个容器之间通信用的(links),外面的host是访问不到的。要把端口暴露给外面的主机,在启动容器时使用-p选项。
VOLUME:指定挂载点/data。
CMD:用于容器启动时指定的服务。
6
通过Kubernetesmanifest文件可以用YAML形式来描述在Kubernetes中以Pod的形式运行的应用容器,以及要运行多少个应用的副本。
K8s的原理及使用我们在云原生架构中有所阐述,在此不再介绍。
7
Terraform多云资源管理代码化
“Multi-Cloud”多云即企业将多个应用部署在多个云平台上,比如华为云、AWS、Azure、OpenStack或其他云平台。如何对不同云平台的资源进行统一管理?
Terraform 是一个 IT 基础架构自动化编排工具,它的口号是 "Write, Plan, and create Infrastructure as Code"。Terraform 要解决的就是在云上那些硬件资源分配管理的问题。相比较 Chef, Puppet, Ansible 这些软件配置工具,Terraform 提供的是软件配置之前,软硬件(基础)资源构建的问题。
我们可以用Terraform管理多层次的资源,从上层的软件配置到底层的网络、系统配置。通过一致的模板形态定义基础设施的创建/更新/销毁的全生命周期。
Terraform使用云供应商所提供的API来配置基础架构,使用云提供商提供的身份验证机制,构建及访问您的服务器。API的对外开放,也是对云计算供应商的基础性要求,是考察其开放性、互通性和可操作性的关键因素。(关于API的开放与设计,我们也将单独描述。)
Terraform提供了对资源和提供者的灵活抽象,允许表示从物理硬件、虚拟机和容器到电子邮件和DNS提供者的所有内容。Terraform与其他系统并不互相排斥,它可以用于管理小到单个应用程序或大到整个数据中心的不同对象。
下面以Terraform使用华为云的样例来释放其使用。Terraform的模板形态大体一致:定义resource,填写不同的参数,比如数量、镜像、实例类型,对于Multi-Cloud的多平台基础设施管理将大幅度降低学习成本。
Terraform与容器技术的结合极大降低了云产品的使用难度。而且一套符合标准的基础设施即代码文档是可以被分发及复用的,这有助于打破云厂商之间的产品界限,促进云计算技术的革新与发展。
8
文档即代码是很有意思的实践,编写文档是开发人员最深恶痛绝的任务之一。敏捷宣言强调个体和互动胜过面面俱到的文档,文档必不可缺,只是无需面面俱到。如何保持轻量级的文档编写,核心是JIT,即非不要不编写。文档的目的是沟通和知识留存,如果可以通过其他更有效的方式进行,例如面对面的沟通,就没必要文档满天飞。
话归正传,Markdown是编写软件文档的最广泛的形式,它是一种轻量级的标记语言,可以轻松转换为HTML或其他格式。
Markdown成为首选的原因之一是我们几乎可以使用任何纯文本编辑器来创建Markdown文件,我们可以通过Markdown桌面文本编辑器、Markdown浏览器在线编辑器来编辑文档。通过git版本控制系统像管理代码一样管理Markdown文件,实现文档及代码。通过文档自动生成工具(例如LaTex)来发布以Markdown格式编写的文档。
例如IDCF.org.cn官网的内容,就是在github上采用Markdown的方式协同编写,并通过流水线发布到IDCF官网。
9
流水线是CI/CD的核心组件,如果我们把基础设施等都代码化,没理由不把流水线也代码化。
团队在使用流水线时,通常会按不同的存储库不同的集成阶段设置不同的流水线,图形模板化的流水线初次容易上手,但在复制和重建时会造成过多工作量,因此流水线即代码和需要提上议事日程。
Jenkins是事实上的流水线标准工具,它允许我们在项目的特定目录下放置一个Jenkinsfile文件,Jenkinsfile是Jenkins核心特性pipeline的脚本,由groovy语言实现。Jenkinsfile一般放在项目根目录,随项目一起受源代码管理软件控制。流水线即代码也就是通过对Jenkinsfile的管理来实现的,示例如下图。
通过Jenkinsfile实现Pipeline as Code的好处是:可以实现流水线上的代码评审、迭代;允许对流水线进行审计跟踪;作为流水线的单一可信数据源,能够被项目的多个成员查看和编辑。
node为流水线分配了一个执行者和工作区,没有node流水线就无法工作,便于控制;Stage代表阶段,一个pipeline可以划分成若干个stage,每个stage代表一组操作。
10
通过上述的步骤,逐步将应用技术栈逐层代码化并集成到持续交付流水线中,进而可以进一步贴近一切皆代码 Everything as Code的目标。
通过Jenkins触发自动集成流水线,自动触发容器镜像生成,并通过Jenkins触发Terraform,可以打破云厂商之间的产品界限,实现容器应用部署至Kubernetes中。自动化流程促进了持续交付,促进计算技术的革新与发展。
1. 应用程序源代码变更。
2. 代码提交到GitHub/CodeHub。
3. Jenkins/构建服务 持续集成触发器。
4. Jenkins触发容器镜像生成。
5. Jenkins触发 Terraform,使用镜像构建的容器集群。
6. 云上收集并分析日志。
7. 监控应用程序并进行改进。
一切皆代码是一种思想,通过可重用的代码来实现IT 环境变更的自动化。
一切皆代码的好处在于,一旦代码化就可以版本化,将其纳入版本管理系统。
一切皆代码实际讨论的就是自动化,利用自动化来处理繁琐的工作,从而让“痛苦的事情反复做”。
自动化意味着生产力、可靠性、可控性、一致性、平台性的提升和确立。
一切皆代码逐步将应用技术栈逐层代码化,并最终通过持续交付流水线进行调度和执行,将应用与环境解耦,将部署与人员解耦,进一步解放人力,实现效能最大化。
参考资料:
https://www.redhat.com/en/topics/automation
https://www.terraform.io/docs/
乔梁老师开课啦~视频课程《持续部署训练营(Python版)》,原价1699元, 限时特价699元
你的软件开发效率够高吗?质量够好吗?你的团队多长时间才能向用户实时推送一个生产变更?你的软件在发布时,你是否因担心软件交付质量而感到压力倍增?你是否遇到过部署失败,甚至导致停机的情况?持续部署可以帮助你消除软件交付的痛苦,让你能专注于为客户高价值的需求,而不会因为这些交付执行类问题而花太多精力。本课程通过学练结合,理论结合实战,让你体验如何使用构建-测试-部署管道,进行持续部署。并练习如何在有效监控部署的同时,逐步发布功能特性,并作数据库结构变化。
(扫码订阅)