當前位置:
首頁 > 最新 > Terraform,自動化配置與編排必備利器

Terraform,自動化配置與編排必備利器

「文末高能」

編輯 | 哈比


什麼是 Terraform

Terraform 是一個安全、高效地部署、更改、版本化基礎設施和應用程序的工具,可以用來管理多層次的資源。從上層的軟體配置到底層的網路、系統配置都可以使用 Terraform 統一進行管理。

Terraform 用配置文件來描述一個應用。 Terraform 會將配置文件與當前環境對比後,生成一個執行計劃,這個計劃會列出為了達到配置文件中定義的狀態所需要執行的操作,然後執行計劃以達到期望的狀態。

Terraform 通過插件機制管理不同的資源提供者,以此來接入各種資源,如虛擬機,存儲,網路和各種應用服務。


Infrastructure as Code

將基礎架構使用配置語法進行描述,這可以讓數據中心的構建計劃可以像其他代碼一樣進行版本化和追蹤。

Execution Plans

Terraform 有一個規劃步驟,它生成一個執行計劃。執行計劃顯示當您調用應用程序時 Terraform 將執行的操作。使用這個功能可以保證操作基礎設施時不發生意外

Resource Graph

Terraform 創建了一個所有資源的視圖。這使得 Terraform 可以並行化沒有依賴的創建與修改。

因此,Terraform 可以高效地構建基礎架構。操作人員也能更加了解環境的結構。

Change Automation

Terraform 會自動的分析什麼是需要修改的,從而避免了許多可能的人為錯誤。

與 Terraform 類似的 Infrastructure as Code 工具大概有下面幾種:

Chef:https://www.chef.io

Puppet:https://puppet.com

Ansible:https://www.ansible.com

SaltStack:https://saltstack.com

CloudFormation:https://aws.amazon.com/cn/cloudformation

下面將從幾個方面來說明 Terraform 與其他工具對比的優勢。

配置管理工具與編排工具

Chef、Puppet、Ansible、SaltStack 都可以稱為配置管理工具,這些工具的主要目標是在已經存在的機器上安裝和管理軟體。

而 Terraform 和 CloudFormation 可以稱為編排工具,更注重於數據中心以及相關服務的高級抽象。他們的工作重點是創建資源並且引導進行初始化。

而且在現在的環境下,大家使用容器等服務,鏡像已經包括了軟體的安裝與配置。一旦你有了鏡像,你需要的是一些伺服器去運行它。

對於提供伺服器這種需求,編排工具會比配置管理工具更適合做此類工作。

編程式語言與聲明式語言

Chef 和 Ansible 希望你去一步步編寫程序以達到最終所期望的狀態。

Terraform、CloudFormation、SaltStack、Puppet 希望你去聲明最終想要的資源與資源的狀態,工具本身會自動分析達到想要的狀態需要進行怎樣的操作。

在使用編程式語言時,工具不會獲取歷史的狀態,所以我們需要考慮的更多以達到與之前版本的兼容。

並且使用編程式語言會導致代碼庫變得越來越龐大,不利於人們理解與代碼的復用。不過聲明式的語言的表達能力是較為欠缺的,例如我們需要基礎設施的滾動升級時,聲明式的語言是很難滿足要求的。

為此 Terraform 提供了一些基礎服務,例如輸入變數,輸出變數,在銷毀之前創建等。

客戶端伺服器架構與客戶端架構

Chef、Puppet、SaltStack 在默認情況下都使用了客戶端伺服器架構。客戶端(可能是 Web UI 或 CLI 工具)是用來發出命令(例如 「deploy X」)的東西。

這些命令到達一個伺服器,它負責執行你的命令並存儲系統的狀態。要執行這些命令,伺服器會與 agent 進行通信,agent 必須在要配置的每個伺服器上運行,這有幾個缺點:

您必須在每台伺服器上安裝並運行額外的軟體。

為了配置管理,您必須部署額外的伺服器(甚至是一組伺服器以實現高可用性)。

由於客戶端,伺服器和代理都需要通過網路進行通信,因此您必須為其打開額外的埠,並配置相互驗證。

這些配置會引入大量不同類型的故障,當收到錯誤警告時,必須要弄清楚是哪一部分出現了故障。

CloudFormation 也是客戶端 / 伺服器架構,但 AWS 透明地處理所有的伺服器細節,作為最終用戶,您只需要考慮客戶端代碼。Ansible 客戶端則通過 SSH 直接連接到您的伺服器。

Terraform 使用雲提供商 API 來配置基礎架構,因此除了您已經使用雲提供商之外,沒有新的身份驗證機制,並且不需要直接訪問您的伺服器。

比較表格


應用場景 1

某應用使用了 Loadbalancer 進行 Instance 間的流量均衡處理,以增大吞吐率、擴大並發數、縮短延遲。

操作步驟:新建安全組、添加安全組規則、申請彈性公網 IP、創建負載均衡器、創建 Instance、在負載均衡器中添加負載均衡器監聽器、配置會話保持、添加健康檢查、在負載均衡器監聽器中添加後端……

應用場景 2

某應用需要隔離的網路環境,需要將應用搭建在 VPC 網路當中,架構如下:

操作步驟:創建安全組、配置安全組、申請彈性公網 IP、創建 VPC、創建 vxnet、創建負載均衡器、配置負載均衡器、創建 Instance 等配置操作。

應用場景 3

隨著業務調整和業務量增大,需要增加更多的節點和集群以承載更多的請求,此時需要對已有的資源進行擴容:

應用場景 4

隨著應用的不斷迭代,應用部署和發布的成本也在增加,如何實現應用的快速部署和發布:

上述場景的共性

操作流程配置固定;

手工操作效率低、時間長;

手工操作可能導致錯誤;

手工操作過程沒有歷史記錄;

手工操作過程不能審計;

手工操作隨著業務的複雜而不斷增大。

解決方法:使用 Terraform 自動化一切

針對場景一、二:創建基礎設施

使用 Terraform,我們可以對基礎設施進行編碼,利用代碼來進行資源的增刪查改。

針對場景三、四:擴容和部署

修改資源代碼以改變基礎設施,並利用 privisioner 幫助運行部署腳本,完成擴容和部署。


快速和安全

利用代碼進行創建資源的速度可以是人工點擊的幾倍甚至幾十倍。

任何人都可以隨時建立起一個環境

只要擁有基礎設施代碼的訪問許可權,就可以自己完成環境的創建,而不需要其他團隊的幫助。

避免雪花伺服器

人工配置環境可能會導致出現雪花伺服器,而使用 Terraform 自動配置則不容易出現。

所有的環境使用類似的代碼

使用 Terraform 你可以輕鬆的控制副本的數量,方便創建一個小的開發 / 測試環境,或者一個大的生產環境

像對待應用代碼一樣對待基礎設施

方便不斷的改進基礎設施的代碼。享受版本管理工具的歷史查看、回滾、備份存儲等功能。

在部署之前驗證架構

對基礎設施代碼做靜態分析,可以大大降低出錯的可能性。

追蹤基礎設施的變化

如果在部署當中發生了錯誤,可以快速恢復到上一個版本,審計人員也可以通過歷史記錄進行審計。

快樂

這是一個非常重要但是經常被忽視的優點。手動部署代碼和管理基礎架構是重複和乏味的。開發人員和系統管理員對這種工作感到不滿,因為它不涉及創造力,沒有挑戰,也沒有認可。

除非你部署失敗了,不然沒有人會關注你。

這造成了一個壓力和不愉快的環境。Terraform 提供了一個更好的選擇,允許計算機做他們最擅長的(自動化執行)和開發人員來做他們最擅長的(編碼)。


1.Terraform 及 terraform-provider-qingcloud 安裝安裝 Terraform

我們首先安裝 Terraform,我們需要進到 Terraform 的官網找到適合的軟體包進行下載:https://www.terraform.io/downloads.html。

下載 Terraform 後,解壓壓縮包。壓縮包中有一個名為 Terraform 的文件,我們只需要這個二進位文件就可以使用 Terraform 了。

最後一步是設置 Terraform 的 PATH。如何在 Linux 和 Mac 中設置 PATH 可以參考 https://goo.gl/3qGa7P, 如何在 Windows 當中設置 PATH 可以參考 https://goo.gl/qynU6S。

驗證 Terraform 安裝

在安裝完 Terraform 之後,我們可以打開一個新的終端來驗證 Terraform 安裝成功了。

執行 terraform -v 可以看到類似下面的輸出:

$ terraform -vTerraform v0.11.1

安裝 terraform-provider-qingcloud

terraform-provider-qingcloud 同樣是以二進位文件進行發布,我們可以到 Github 上找到適合的軟體包下載:https://github.com/yunify/terraform-provider-qingcloud/releases。

下載並解壓以後會有一個二進位文件。

在 Linux 以及 Mac 當中我們需要將這個二進位文件放到 ~/.terraform.d/plugins/ 當中。在 Windows 當中把這個二進位文件放到用戶的 「Application Data」 目錄下的 terraform.d/plugins/ 當中。

2.Terraform 使用-以 wordpress 為例

下面我們以 wordpress 為例演示如何使用 Terraform 在青雲中從零開始部署一整套環境。部署下圖中所示的基礎設施及軟體資源。

例子源碼:https://goo.gl/Em3H4S。

注意:使用 terraform apply 會創建實際的資源,可能會產生一些費用。

理解配置文件

Terraform 所有的配置文件以 tf 作為後綴名。在執行相關命令時,Terraform 會自動載入當前目錄下的 *.tf 文件。Terraform 的配置文件是 HashiCorp 公司的 HCL 語言(https://github.com/hashicorp/hcl)。

Terraform init

與 git 類似,我們需要在 Terraform 項目的根目錄運行 terraform init 去初始化項目。

在初始化項目的時候,Terraform 會解析目錄下的 *.tf 文件並載入相關的 provider 插件。在 wordpress 文件夾下運行 terraform init 會看到類似下面的輸出:

$ terraform initInitializing modules...- module.qingcloud- module.wordpressInitializing provider plugins...The following providers do not have any version constraints in configuration,so the latest version was installed.To prevent automatic upgrades to new major versions that may contain breakingchanges, it is recommended to add version = "..." constraints to thecorresponding provider blocks in configuration, with the constraint stringssuggested below.* provider.null: version = "~> 1.0"Terraform has been successfully initialized!You may now begin working with Terraform. Try running "terraform plan" to seeany changes that are required for your infrastructure. All Terraform commandsshould now work.If you ever set or change modules or backend configuration for Terraform,rerun this command to reinitialize your working directory. If you forget, othercommands will detect it and remind you to do so if necessary.

驗證 Terraform init

在 wordpress 文件夾下運行 terraform -v 會得到類似下面的輸出:

$ terraform -vTerraform v0.11.1+ provider.null v1.0.0+ provider.qingcloud (v1.1.0)

指定 Provider

在 ./provider.tf 文件我們指定了 Provider,QingCloud 的 Provider 需要與進行調用 API,key 可以在 QingCloud Web 控制台進行申請。

zone 指定了資源會在哪個區中進行創建,默認為 Pek3a 區。

理解 Resource

HCL 語言是一種聲明式語言,即在 *.tf 文件中聲明了我們所期望的資源狀態。

我們在 ./modules/qingcloud/qingcloud.tf 文件當中指定了我們想要的資源以及他們的狀態。

在定義的資源的時候我們可以在一個資源當中引用其他資源的欄位,Terraform 會自動解析這些引用並且按順序進行創建。

resource "qingcloud_security_group_rule" "ssh-wordpress-in" { security_group_id = "$" // 引用別名為 foo 的 qingcloud_security_group 的 id protocol = "tcp" priority = 0 action = "accept" direction = 0 from_port = 22 to_port = 22}

在上面的這一小段代碼當中, 為資源的名稱,需要 Provider 支持特定的資源。

ssh-wordpress-in 為資源的別名,是在這個項目當中唯一的。

上面我們創建了一個類型為的資源,也就是一個防火牆規則資源。

在這個資源中我們指定了防火牆的 ID,以及規則的協議、優先順序、動作、方向以及埠範圍。

注意:在創建資源的時候我們是上傳用戶的>~/.ssh/id_rsa.pub 文件,

這個公鑰需要用戶自己去生成,具體生成方法可以參考文檔。同樣我們在使用 provisioner 安裝軟體環境時使用了~/.ssh/id_rsa 作為私鑰進行了遠程連接,如果需要修改的話請自行修改配置文件。

在整個例子的源碼當中,我們分別創建了下列資源:

qingcloud_eip.foo:創建一個帶寬為 2 的彈性公網 IP

:使用~/.ssh/id_rsa.pub 的文件內容創建一個 SSH key

:創建一個名稱為 first_sg 的防火牆

:為防火牆添加一條接收 80 埠 TCP 請求的規則

:為防火牆添加一條接收 22 埠 TCP 請求的規則

:為防火牆添加一條接收 2222 埠 TCP 請求的規則

:創建一個 vpc 網路,並且綁定了防火牆與彈性公網 IP,VPC 的子網範圍為 192.168.0.0/16

qingcloud_vxnet:創建一個受管的 vxnet,並且加入 VPC 當中,子網範圍是 192.168.0.0/24

qingcloud_instance.wordpress:創建一個實例,綁定了上面創建的 SSH key,並且加入到了 vxnet 當中

qingcloud_instance.mysql:創建一個實例,綁定了上面創建的 SSH key,並且加入到了 vxnet 當中

:為 VPC 添加一條埠轉發規則,將 80 埠的請求轉發到 instance 的 80 埠當中

:為 VPC 添加一條埠轉發規則,將 22 埠的請求轉發到 qingcloud_instance.wordpress 的 22 埠當中

qingcloud_vpc_static.ssh-mysql:為 VPC 添加一條埠轉發規則,將 2222 埠的請求轉發到 qingcloud_instance.mysql 的 22 埠當中

如果需要獲取更多有關 terraform 基本操作的信息,可以參考官方文檔的 Getting Started 部分。

獲取更多資源的使用信息,可以查看 terraform-qingcloud-provider 的 文檔

利用 Built-in Functions 避免手工操作

在創建的時候,我們使用了 Terraform 的內置函數去幫助獲取文件~/.ssh/id_rsa.pub 的內容。從而避免了我們手工複製粘貼。

~/.ssh/id_rsa.pub 的文件內容resource "qingcloud_keypair" "foo" { public_key = "$"}

Terraform 內置了許多函數幫助用戶解決一些常見操作,如果需要獲取更多的信息,請參考官方文檔:https://www.terraform.io/docs/configuration/interpolation.html#built-in-functions。

使用 Provisioners 進行環境配置

Provisioners 可以在資源創建 / 銷毀時在本地 / 遠程執行腳本。

Provisioners 通常用來引導一個資源,在銷毀資源前完成清理工作,進行配置管理等。

Provisioners 擁有多種類型可以滿足多種需求,如:文件傳輸(file),本地執行(local-exec),遠程執行(remote-exec)等 Provisioners 可以添加在任何的 resource 當中:

resource "qingcloud_instance" "foo" { # ... provisioner "local-exec" { command = "echo $ > file.txt" }}

在 example 當中,我們使用了和 provisioner 完成了上安裝 docker 並啟動 wordpress 與 mysql。

在當中,我們指定了 depends_on 參數,保證了在 mysql 已經啟動成功後再啟動 wordpress。

執行 Terraform plan 查看 Terraform 計劃

Terraform plan 命令用於輸出執行計劃。除非明確禁用,Terraform 會調用 refresh 方法重新查詢當前資源的狀態。

完成狀態刷新後,Terraform 會自動分析要進行的操作以達到配置文件中所需要的狀態,並把分析的結果輸出出來。

在文件夾下執行 Terraform plan 會得到類似下面的結果:

$ terraform planRefreshing Terraform state in-memory prior to plan...The refreshed state will be used to calculate this plan, but will not bepersisted to local or remote state storage.------------------------------------------------------------------------An execution plan has been generated and is shown below.Resource actions are indicated with the following symbols: + createTerraform will perform the following actions: + module.qingcloud.qingcloud_eip.foo id: addr: bandwidth: "2" billing_mode: "bandwidth" need_icp: "0" resource.%: tag_names.#: + module.qingcloud.qingcloud_instance.mysql id: cpu: "1" image_id: "centos73x64" instance_class: "0" keypair_ids.#: managed_vxnet_id: "$" memory: "1024" private_ip: public_ip: security_group_id: tag_names.#: ......Plan: 15 to add, 0 to change, 0 to destroy.------------------------------------------------------------------------Note: You didn"t specify an "-out" parameter to save this plan, so Terraformcan"t guarantee that exactly these actions will be performed if"terraform apply" is subsequently run.

使用 module 進行代碼的組織管理

Terraform 中的模塊是以組的形式管理不同的 Terraform 配置。

模塊用於在 Terraform 中創建可重用組件,以及用於基本代碼組織。每一個 module 都可以定義自己的 input 與 output,方便代碼進行模塊化組織。

在例子當中我們將配置文件分成了兩個 module 進行處理:module qingcloud 負責在 qingcloud 創建所需要的基礎設施資源。module wordpress 負責在創建好的虛機當中安裝 docker 並且啟動 wordpress 與 mysql。

其中需要安裝 wordpress 的機器信息是通過 input 傳入進來的,而傳入進來的 input 實際上是 module qingcloud 的 output。

通過 input 與 output,我們將兩個模塊連接到了一起。在 ./module.tf 當中,我們調用了兩個 module 指定了兩個 module 的參數傳遞關係。

使用 Terraform apply 提交資源創建及配置

Terraform apply 命令用於應用所需的更改以達到所需的配置狀態。為了更加方便的得到我們所關注的輸出結果,可以使用 output 單獨輸出部分欄位。

如在 ./module.tf 當中,我們單獨獲取了 module.wordpress 的 public_ip:

output "wordpress_public_ip" { value = "$"}

填寫 provider.tf 中的 與 後,我們使用 terraform apply 可以完成資源的創建與配置。

注意:在 example 中是根據文件來獲取 SSH key,在您機器上可能不存在此文件,請您自行創建 SSH key。

我們會在輸出的結尾獲取到類似下圖的輸出:

打開瀏覽器,輸入 output 的 IP,可以看到 wordpress 已經正常運行:


多層應用的部署

一般來講應用都是分為 N 層架構的,而我們的例子是一個非常典型的二層應用,分別是業務邏輯層的 wordpress 和數據層的 mysql。

Terraform 確保資料庫層在 Web 伺服器啟動前可用。這得益於 Terraform 可以自動的去解析資源之間的關係,保證了有依賴關係的各層可以按順序進行創建。

多雲環境的部署

人們通常將基礎架構分布在多個雲中以提高容錯性。通過僅使用單個區域或雲提供商,容錯受限於該提供商的可用性。進行多雲部署可以更好地恢復地區或整個提供商的損失。

Terraform 是與雲無關的,我們可以使用不同的 provider 實現多雲環境的部署。並且可以將一個項目拆分為多個 module 實現代碼的復用。

前面的例子當中,我們分為了兩個 module,其中 module wordpress 是不依賴於雲環境的 module,我們可以在不同雲提供商中復用這個 module。

在同一個項目中同樣可以使用多個提供者,甚至還能處理多個雲當中的依賴關係。這可以幫助用戶創建大型的雲基礎架構。

軟體定義網路的配置

軟體定義網路(SDN)在數據中心中越來越流行,它為用戶提供了更多的控制權,同時也帶來了人為管理負擔。 一般來講 SDN 分為控制層與轉發層。

Terraform 可以編寫 SDN 的配置文件,這些配置可以由 Terraform 自動調用控制層的介面生效。這些配置文件是可以進行版本化的。

例如,QingCloud VPC 是一種非常典型的 SDN,這種資源我們是可以利用 Terraform 進行管理,完成控制層的配置。

一次性測試環境

使用 Terraform 測試環境是可以被編碼的,這些配置文件可以在 QA、開發等團隊中進行分享,可以極大減少開發測試團隊重複準備環境的負擔,減少人為錯誤,提高工作效率。

並且 Terraform 可以一鍵的進行資源的創建與刪除,這可以幫助我們快速的創建測試環境,完成使用後可以進行及時的刪除。

PS: QingCloud 作為全球首家實現資源秒級響應並按秒計量的基礎雲服務商,使用 terraform-qingcloud 可以讓用戶的成本最大限度的貼合實際的資源使用情況。


Terraform 官網:https://www.terraform.io

Terraform 青雲官方 Github:https://github.com/yunify/terraform-provider-qingcloud

Why we use Terraform:https://goo.gl/zW8J68


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 GitChat技術雜談 的精彩文章:

如何搭建 Redis 集群

TAG:GitChat技術雜談 |