“AI 技术+人才”如何成为企业增长新引擎?戳此了解>>> 了解详情
写点什么

IaC 自动化配置与编排神器 - Terraform 深度解析

  • 2019-05-17
  • 本文字数:4343 字

    阅读完需:约 14 分钟

IaC 自动化配置与编排神器 - Terraform 深度解析

前言

Terraform 是 Hashicorp 公司开源的一种多云资源编排工具。使用者通过一种特定的配置语言(HCL, Hashicorp Configuration Language)来描述基础设施,由 Terraform 工具统一解析,构建资源之间的关系,生成执行计划,并通过调用各家云厂商的具体实现来完成整个基础设施生命周期的管理。


相对于其它的云上资源管理方式,Terraform 的主要特点有:


  • 基于 IaC(基础设施即代码,Infrastructure as Code)的设计,可以将基础设施以一种领域特定语言描述出来,消除了在基础设施自动化时描述语义上的歧义,同时减轻了人为因素造成的不确影响。

  • Terraform 在执行编排动作前,会生成一份可读性良好的执行计划,关键基础设施的变更可以得到充分审查,保证了基础设施的可靠性。

  • 基于 DAG(有向无环图,Directed Acyclic Graph)描述资源与资源之间的关系,由于 DAG 良好的拓扑性质,当资源属性与资源关系发生改变时,变更动作将被充分并行地执行。


在 UCloud,我们最终选择了 Terraform 来编写 UCloud 基础设施代码,并配合 UCloud CLI、Ansible 等工具,进一步拓展了 Terraform 的功能,实现基础设施可编程。


本文将详细阐述 Terraform 的整个生命周期,从 Provider 开发者的视角,介绍 Terraform 在安全、效率和状态一致性三个方面的内部机理与具体实现。

技术实现解析

生命周期

以首次执行 Terraform 创建 UCloud 云上资源为例,这一资源编排动作的生命周期如下图所示:



图表 1 Terraform 生命周期


图中立方体所示分别为:


  • Terraform 核心进程:负责资源定义文件,构建有向无环图,管理状态存储;

  • Provider 进程:即提供资源编排能力的进程,包括由云厂商实现的能力(比如 UCloud),和应用程序提供的能力(比如 TLS)等;

  • Provisioner 进程:即提供资源编排后处理操作的进程,比如执行 Shell 命令,上传文件等;


以中央的有向无环图为分界线,左侧的部分是 Terraform 本身提供的能力,右侧是由云厂商提供的能力。


当执行 Terraform 命令首次编排云上资源时:


  1. Terraform 首先唤醒核心进程,初始化 Backend(即状态管理组件);

  2. 解析用户编写的资源定义文件,同步最新的资源状态,并与当前的资源定义作对比;

  3. 初次构建 DAG 时,资源尚未被初始化,所以资源状态为空,用户的资源实例都将作为 DAG 中新增的节点被创建。


在并行构建资源时:


  1. 并行遍历 DAG;

  2. 当遇到 Provider 节点时,Terraform 核心进程唤醒 UCloud Provider 进程;

  3. 将所有的编排动作依次发给 UCloud Provider;

  4. Provider 调用 UCloud OpenAPI 管理云上资源;

  5. 返回的结果由 Terraform 核心进程写回状态存储。

进程管理

随着云计算的普及,以及人们对于数据安全性和可用性上的考量,越来越多的企业开始意识到,不能把鸡蛋放在一个篮子里,基础设施的中立和非绑定是云服务商十分关键的属性。


Terraform 中每一个云厂商的实现(Provider)都是一个独立的进程,进程间使用 RPC 通信的方式下发指令和交换数据,这样设计有什么好处呢?


  • 安全性:多云环境下,进程隔离云厂商的实现,防止共享内存带来的安全性问题。

  • 扩展性:插件式的设计使得特性的增加更加容易,而官方插件仓库使得特性的质量更有保障。

  • 稳定性:核心与插件分离,保证了核心简单可靠,测试充分。单一插件的 Bug 不会扩散到全局。


而从使用者的角度来看,Terraform 多进程模型的重中之重,是多云环境下厂商隔离带来的安全性问题。安全性是多云编排的基石,如果无法保证云厂商之间的隔离性和安全性,多云编排则无从谈起。


Terraform 使用插件(Plugin = Provider + Provisioner)来抽象出各个云厂商之间的差异,并相互隔离。



图表 2 Terraform 多云插件管理


在一次编排任务的生命周期中,Provider 将会基于 Terraform 提供的能力,完成静态检查(Validate)、资源状态同步(Read/Refresh)、生成执行计划(Plan)、执行编排(Apply)等操作。

依赖管理

软件工程的实践表明,高层次的抽象,可以简化问题,让复杂的问题变得可以测试。而对于依赖关系的抽象,业界最通行的做法即使用有向无环图(DAG,Directed Acyclic Graph)来描述事务间的依赖关系。有向无环图上的点即事物本身,边则是事物与事物之间的联系。


业界对于 DAG 的使用极为广泛,比较典型的是各种大数据工作流引擎,比如 Oozie,Airflow 等。在这些引擎中,批处理任务作为 DAG 上的节点,而任务间的依赖作为 DAG 上的边。



图表 3 业界常见的 DAG 应用


Terraform 将所有的资源构建为一张有向无环图(DAG),计算它们的依赖关系,并行地去创建和修改相互间没有依赖的那些资源。因此整个基础设施的构建过程是高效且严格有序的。


下面我们将举例介绍它的内部原理和实现。


注意:文中的图与描述为了呈现效果,分别有所简略,仅供参考

图构建

假设一个场景,一台主机与一个公网弹性 IP 绑定,且客户使用自有的第三方 DNS 服务,通过 A 记录指向该主机的公网 IP。



图表 4 构建云上资源拓扑


这个场景展现了 Terraform 对于资源拓扑关系的描述能力,以及对于外部服务的集成能力。它背后的工作原理是什么样的呢?


所有云上资源,都抽象为 DAG 的一个节点,而资源与资源之间的关系,则有两种抽象方式:


  • 一种是抽象为边,将两个资源节点连接在一起,例如从 dnssimple_record 到 ucloud_eip 的箭头表示将 DNS 指向弹性 IP(eip);

  • 另一种是抽象为一个单独的资源,例如 eip_association 资源将弹性 IP(eip)和云主机(instance)绑定在一起。

图变换


图表 5 有向无环图变换


在图构建的过程中,Terraform 需要对 DAG 进行若干次变换(Transform)操作,如:


  • 添加辅助节点,如 Config、Variable、Local、Provider Node、Root Node 等;

  • 附加辅助信息到 Resource Node;

  • 添加清理操作节点,作为图遍历过程中末端的节点,例如 CloseProvider/Provisioner;

  • 进行图化简操作,例如做 transitive reduction 简化多余的边,减少编排成本。

图遍历

最后对整张图进行遍历,对每一个资源节点分别执行资源编排操作,比如读取、创建、更新和删除等。



图表 6 并行遍历,执行资源动作


从根节点开始,Terraform 并行地去编排整个资源拓扑,遍历整个有向无环图,直到所有资源都被成功编排,并执行清理操作。


可以看出,由于有向无环图出色的拓扑性质,整个遍历过程,存在着充分的局部并行化,编排时间跟基础设施复杂度有显著关系,而同构基础设施的规模则对编排时间影响较小,保证了 Terraform 在大规模水平扩展时拥有较好的性能。

状态管理

Terraform 引入了面向资源的设计,将资源的状态描述为一个状态的集合,并支持若干种不同类型的状态存储。


默认情况下,在 Terraform 的执行目录下,会存储一个本地的资源状态文件,并在每次编排开始时,从远程同步状态到本地,比较该状态与用户定义的资源之间的差异,从而生成编排计划。

定义

在这一抽象中,Terraform 官方给出了几个基本的定义:



从上文中的定义可以看出,执行计划(Plan)本质上就是 Diff 格式化输出的结果,而执行编排就是应用这个 Diff 的过程。

Backend

Terraform 将对资源状态的管理抽象出了一个统一的状态管理层(Backend),使得基于 Terraform 的资源编排系统可以保持基础设施的一致性。


想象一个场景,如果 A 同学在操作基础设施的变更,B 同学此时也想执行变更,这个变更会执行么?



图表 7 同时操作云上资源


答案显然是不会的,任何一个成熟的系统都应该对这样的问题提出解决方案。


Terraform Backend 通过对状态加锁来解决资源的竞态问题。A 在操作资源的时候状态会被锁定,此时 B 执行的任何变更行为都将被拒绝。


其中,consul、etcd 和 http 是比较推荐的扩展:


  • consul、etcd 提供了锁机制,且基于 Raft 协议保证了数据的强一致性;

  • http 适用于自行研发的,可扩展的状态存储,如云服务商提供的状态托管服务,可选支持锁机制。


Terraform 对 Backend 的抽象增强了状态存储的可扩展性,同时提供了可选的锁机制扩展,基于此云厂商可以定义自己的远程状态存储,用于托管用户的资源状态,并为用户提供可靠的并发安全保障。

时效性

Terraform 的杀手级特性之一 —— 执行计划,允许导出执行计划,延后执行,提供了在 CI/CD 环境下人工审查执行计划的可能,对关键基础设施变更的安全性提供了保障。所以,导出的执行计划是否过期是生产环境中最常见的问题。


Terraform 如何保证已经失效的执行计划不再被执行?Terraform 使用多版本快照(Multi-Version Snapshot)的方式来实现。可以类比于常规的 MVCC(多版本并发控制)来理解,下图是一个最小化的 MVCC 实现:



图表 8 常规的多版本 MVCC 实现


进程 P1 和 P2 依次读到了序号为 1 的数据,并且都想进行写操作,P1 先修改数据,自增序号为 2 并写入成功,此时 P2 进行写操作时,由于修改后的序号同样为 2,此时应抛出写失败,P2 需要主动重新读取最新的数据再次修改,才能成功写入。


由于 Terraform 可以执行一个已导出的执行计划,一个事务的时间被极大延长了,所以版本冲突的可能被无限放大。


基于此,Terraform 同样选择该方式,通过一个序号来标识状态的版本,当执行计划的状态序号小于当前状态的序号时,直接丢弃过时的执行计划:



图表 9 Terraform 的执行计划过期实现


基于这样的原理,Terraform 保证了导出的执行计划是有时效性的。例如一个用户导出了一份执行计划,将云主机从 1 台水平扩容到 3 台,但在该执行计划审查通过之前,另一个用户已经扩容到 5 台云主机,此时这份执行计划执行时会 Abort,而不会从 5 台降为 3 台,从而保证关键基础设施的变更是安全的。

状态升级

在软件构建或产品设计中,不可避免的会出现一些破坏性的变更,而这些破坏性的变更又不可避免地会影响资源状态。



图表 10 状态迁移的痛点


常见的在线服务(比如 HTTP API)设计中,通常在 HTTP Header 甚至 URL 加一个版本号来区分新老版本。但 Terraform 作为一个二进制分发的软件,且在用户的本地存储有一份资源状态,如果进行破坏性的升级,则必须同时考虑存量用户的正常使用,以及旧版状态文件的原地升级。


Terraform 的解决方案是标定资源的 Schema Version,默认 Version 为 0,当资源的 Schema 有破坏性的更改时,作为 Provider 的云厂商必须为此提供一个原地升级函数。



图 11 资源状态平滑升级


假设 UCloud 的 EIP 共有 3 个版本,0,1,2,则须提供 2 个升级函数。


当一个使用版本 0 的用户升级到最近版本 2 执行编排的时候,他的状态文件将会依次经过两个升级函数,将资源状态原地升级至最新版本的状态,而无需任何额外操作。

总结

总体而言,Terraform 是一个安全的,可扩展的,有扎实的理论基础,也有渐进式工程实践的资源编排工具。Terraform 的关键特性:基础设施即代码、多云编排、执行计划与过程分离、统一的资源状态管理,是我们在新一代资源编排系统实践中的重要保障。




作者简介


李宇飞,UCloud 后台研发工程师,参与资源编排等接入产品项目研发,专注于云计算,DevOps,分布式系统等领域。


2019-05-17 12:0814371

评论

发布
暂无评论
发现更多内容

As Const:一个被低估的 TypeScript 特性

树上有只程序猿

typescript as const

基于HarmonyOS的HTTPS请求过程开发示例(ArkTS)

HarmonyOS开发者

HarmonyOS

.NET 8 IEndpointRouteBuilder详解

不在线第一只蜗牛

.net 编程语言

【开源三方库】Easyui:基于OpenAtom OpenHarmony ArkUI深度定制的组件框架

OpenHarmony开发者

OpenHarmony

选择 REST ,还是 GraphQL

高端章鱼哥

Rest graphql

WebGL+H5智慧海上风场可视化远程运维平台

2D3D前端可视化开发

物联网 数字孪生 三维可视化 智慧海上风电

利用Java的反射机制实现代码自动生成

这我可不懂

Java 反射机制 代码自动生成

Path Finder for Mac中文破解版

iMac小白

Path Finder Path Finder破解 Path Finder下载

Glyphs 2 for Mac(字体设计编辑软件) v2.6.6(1350)永久激活版

mac

windows 苹果mac 字体设计软件 Glyphs 2

Spring 微服务:数据压缩技术

互联网工科生

spring 微服务 云原生 数据压缩

十月 Web3 游戏行业报告:市值增长背后的用户获取挑战

Footprint Analytics

gamefi NFT链游 Web3 游戏

Infuse for Mac(强大的音视频播放器)

iMac小白

Infuse下载 Mac版Infuse下载 Infuse 中文 Infuse播放器

万千企业,数智世界,一触即达

脑极体

数智化

统一运维的定义以及优点说明-行云管家

行云管家

运维 IT运维 运维软件 统一运维

sublime text 4 Mac版 秘钥激活 好用的代码编辑器

影影绰绰一往直前

Sublime Text 4 破解版 Sublime Text 4下载 Sublime Text 4注册版

软件测试/测试开发/人工智能丨 利用ChatGPT编写测试用例

测试人

人工智能 软件测试 测试用例 ChatGPT

探秘亚马逊云科技海外服务器 | 解析跨境云计算的前沿技术与应用

-亦世凡华、

服务器 经验分享 海外服务器 亚马逊服务器

开发一条公链多少钱

西安链酷科技

区块链 去中心化 节点 公链

10款市场分析工具大盘点:哪款是你的首选?

彭宏豪95

效率工具 科技 在线白板 竞品分析 市场分析

Paste for Mac(剪切板管理工具) v4.1.2免激活版

iMac小白

Paste for Mac Paste下载 Paste中文版

迈向全球,从选择海外高防服务器开始,为您的业务提供坚实保障

一只扑棱蛾子

海外高防服务器

面对瓶颈期,中国ToB SaaS如何实现全面突围?

ToB行业头条

Spring 缓存注解这样用,太香了!

越长大越悲伤

Java redis spring 缓存 springboot

WeChatTweak for Mac(多开和防撤回工具) macOS微信插件

影影绰绰一往直前

微信多开和防撤回工具 微信小助手 微信多开助手 微信多开

mac电脑capture one pro 2023 中文破解版下载

影影绰绰一往直前

Capture One Pro 23 Capture One Pro下载 Capture One Pro破解版

Capture One 23 Enterprise for Mac中文激活版

iMac小白

Capture One 23Enterprise Capture One 23

情感语音识别技术在人机交互中的应用与挑战

来自四九城儿

云图说|什么是可信智能计算服务TICS

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 华为云云图说

OmniOutliner Pro mac 中文专业版下载

iMac小白

OmniOutliner Pro下载 OmniOutliner Pro破解 OmniOutliner Pro激活

HarmonyOS NEXT调优工具Smart Perf Host高效使用指南

新消费日报

基于深度学习的情感语音识别模型优化策略

来自四九城儿

IaC 自动化配置与编排神器 - Terraform 深度解析_云原生_李宇飞_InfoQ精选文章