HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

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:0814862

评论

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

Adobe Photoshop 2024 v25.5最新中文破解版 附安装教程

iMac小白

Mac电脑图像编辑软件:Pixelmator Pro中文直装激活

iMac小白

这波操作看麻了!十亿行数据,从71s到1.7s的优化之路。

不在线第一只蜗牛

数据结构 数据 数据优化 比赛

云手机海外社交媒体监测:洞悉舆论,把握商机

Ogcloud

云手机 海外云手机 云手机海外版 国外云手机

MySQL学习笔记

秃头小帅oi

Navicat for MySQL Mac版(数据库管理开发工具)v16.3.6中文特别版

iMac小白

企业需要知道的数据安全管理产品-堡垒机

行云管家

数据安全 堡垒机 运维审计

开发者手机开源代码编译指导

Laval小助手

Bridge 2024 for Mac(BR)v14.0.2激活版

iMac小白

Web3.0区块链技术开发方案:区块链数字钱包软件开发

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 NFT开发 公链开发

通义千问1.5(Qwen1.5)大语言模型在PAI-QuickStart的微调与部署实践

阿里云大数据AI技术

阿里云 人工智能’ 通义千问 机器学习PAI 大语言模型

AI加速引擎PAI-TorchAcc:整体介绍与性能概述

阿里云大数据AI技术

模型训练 大模型 #人工智能 机器学习PAI

使用OpenTelemetry进行监控

快乐非自愿限量之名

.net 优化 开发语言 项目开发

电商卖家如何利用API提升客户满意度

技术冰糖葫芦

API 接口

QLab Pro for Mac(音频剪辑软件)v5.3.6激活版

iMac小白

风险评估是什么意思?与等保测评有什么区别?

行云管家

等保 等保测评 风险评估

鸿蒙Harmony 时代的跨端方案

FN0

小程序 鸿蒙 鸿蒙开发

用云手机进行舆情监测有什么作用?

Ogcloud

云手机 海外云手机 云手机海外版 国外云手机

云手机的境外舆情监控应用——助力品牌公关

Ogcloud

云手机 海外云手机 云手机海外版 国外云手机 舆情监控

阿里巴巴1688商品详情API:如何高效地获取商品信息?

技术冰糖葫芦

API 接口

Navicat Charts Viewer for Mac(Navicat图表查看器) v1.2.16激活版

iMac小白

Navicat Charts Creator for Mac(Navicat图表创建器)v1.2.16激活版

iMac小白

Navicat for SQLite 16 for Mac(强大数据库管理及开发工具)v16.3.6中文版

iMac小白

使用C++界面框架ImGUI开发一个简单程序

EquatorCoco

c++ UI API 开发语言

洞悉市场趋势,把握增长先机:商品企划系统助力品牌飞跃式增长

第七在线

友盟+Hologres:千亿级多维分析平台建设实践

阿里云大数据AI技术

友盟 数据分析、 数据查询 hologres

什么是HTTP状态码,常见状态码有哪些

德迅云安全杨德俊

AI加速引擎PAI-TorchAcc:OLMo训练加速最佳实践

阿里云大数据AI技术

模型训练 大模型 机器学习PAI

30分钟开发Vue 3插入客制化脚本插件

星辰编程理财

Vue 前端 vite AST 前端客制化

一端开发、多端部署,如何利用移动开发利器

Geek_2305a8

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