伺服器太多了不好管?UCloud基於Terraform的資源編排工具詳解
背景
隨著使用者在 UCloud 上資源用量的指數增長,傳統 API/SDK 手動編寫指令碼的資源管理方式已經無法滿足其需要。為此,UCloud 研發團隊基於 Terraform 編寫了一套自己的資源編排工具,幫助使用者降低雲上資源的管理成本,為其提供安全可靠、高度一致的產品使用體驗,儘可能消除遷移上雲時的風險。
Terraform 代表了業界前沿的技術和標準,我們基於此,並配合 UCloud CLI 等工具,編寫了新一代 UCloud 資源編排工具,進一步拓展 Terraform 的功能,實現基礎設施可程式設計。在一個通過 ULB 解除安裝流量至雲主機的案例中,相比於傳統方式,新方案下的構建時間從原先的 3 分 20 秒縮短至 43 秒,編排的效率、穩定性和可描述性都得到了顯著提升。
Terraform是什麼?
Terraform 是 Hashicorp 公司開源的一種多雲資源編排工具,目前已經形成完整生態,並與多家主流雲廠商建立合作。
使用者通過一種特定的配置語言(HCL, Hashicorp Configuration Language)來描述基礎設施,由 Terraform 工具統一解析,構建資源之間的關係,生成執行計劃,並通過呼叫 UCloud 公有云 API 來完成整個基礎設施生命週期的管理。
相對於其它的雲上資源管理方式,Terraform 的主要特點有:
-
有廣泛的相容性,目前海內外累計已有超過 40 家公有云廠商支援,其中包括 UCloud 在內的 4 家國內雲廠商,另有 200 多個軟體服務商為其提供支援。
-
基於 IaC(基礎設施即程式碼,Infrastructure as Code)的設計,可以將基礎設施以一種領域特定語言描述出來,消除了在基礎設施自動化時描述語義上的歧義,同時減輕人為因素造成的不確定影響。
-
Terraform 在執行編排動作前,會生成一份可讀性良好的執行計劃,關鍵基礎設施的變更可以得到充分審查,保證了基礎設施的可靠性。
-
基於 DAG(有向無環圖,Directed Acyclic Graph)描述資源與資源之間的關係,由於 DAG 良好的拓撲性質,當資源屬性與資源關係發生改變時,變更動作將被充分並行地執行。
(圖片來源於Terraform)
下圖是一張資源編排與傳統資源管理方式的對比表:
表格1:資源編排與傳統資源管理方式對比
可以看出,在自動化 DevOps 環境下,資源編排相對傳統資源管理方式具有明顯優勢,目前已覆蓋了 IaaS 層的核心產品,但隨著時間的推移,將來 UCloud 資源編排會支援更多的產品。
應用場景
使用者可以很容易的從Terraform受益,因為初始化雲服務時若缺少資源編排工具,將投入大量的時間成本,而且對於雲上資源的變更,往往需要很複雜的變更邏輯以保證基礎設施的安全性。
UCloud 資源編排工具能夠很好地解決如下常見的問題:
– CI/CD 自動化資源管理
– 高峰期應用縮擴容
– 部署複雜資源拓撲(例如兩地三中心的應用架構)
例如,驛氪作為一家SaaS解決方案提供商,已經將UCloud Terraform編排系統接入自身業務。
下圖是驛氪業務架構的示意圖。它同時使用了多家雲服務,需要統一的資源管理平臺進行多雲管理,而獨立研發一套資源管理平臺,需要對接各雲廠商介面,同時還要研發人員深入瞭解各家雲服務的產品細節,這無疑會加重企業的研發成本和運營成本。
而在應對SaaS 業務時,Terraform可以靈活的動態調整資源,使用者只需要調整部分引數,就可以利用模板進行非常快速的資源管理,相較於自建管理平臺,UCloud Terraform可以極大節省使用者的運營成本和效率。
生命週期
以首次執行 Terraform 建立 UCloud 雲上資源為例,這一資源編排動作的生命週期如下圖所示:
圖:Terraform 生命週期
圖中立方體所示分別為:
– Terraform 核心程序:負責資源定義檔案,構建有向無環圖,管理狀態儲存;
– Provider 程序:即提供資源編排能力的程序,包括由雲廠商實現的能力(比如 UCloud 的資源編排實現),和應用程式提供的能力(比如 TLS 自簽名證書)等;
– Provisioner 程序:即提供資源編排後處理操作的程序,比如執行 Shell 命令,上傳檔案等。
以中央的有向無環圖為分界線,左側的部分是 Terraform 本身提供的能力,右側是由雲廠商提供的能力。
Terraform 核心的良好抽象,保證了資源編排的安全和穩定,為 UCloud 資源編排提供了堅實的工程基礎。
UCloud資源編排實踐
在一個生產環境的資源編排系統中,往往要依賴數目龐大的雲資源後臺管理服務。資源編排的工程實現中,以下幾個方面的根本訴求需要首先得到保障:
– 保障資源編排在複雜終端環境下的成功率。這個是最基本也是最核心的訴求。
– 保障產品的一致性。使使用者可以平滑遷移,變更無感知。
– 保障產品的工程質量。資源編排作為關鍵基礎設施的接入方式,本身需要足夠穩定可靠。
下文,我們將詳細分享 UCloud 在基於 Terraform 的資源編排工具研發中,在容錯能力、接入能力和工程能力優化上的一些實踐。
容錯能力優化
容錯能力是衡量系統可用性的一個重要維度,資源編排作為 UCloud 服務的入口,本身必須足夠穩定,具有對故障可以做出合理應對的能力,包括對上游服務異常的容錯能力,以及對於輸入異常的糾錯能力。
首先,Terraform 的殺手級特性是執行計劃與過程分離,使用者在執行真正的資源編排動作變更現網基礎設施之前,可以先生成執行計劃,比較資源定義檔案和當前資源狀態的差異,檢查關鍵基礎設施的變更。
UCloud 在實現資源編排的過程中,藉助 Terraform 執行計劃的 CustomDiff 特性,自定義了部分資源的 Diff 過程。比如,兩個地域之間僅能存在一條高速通道(UDPN),如果執行編排動作前已經存在了一條高速通道(UDPN),將會把所有的編排動作阻止在執行計劃階段,提高終端使用者的使用效率。
圖:自定義 Diff 以在執行計劃中檢查輸入
對於錯誤的處理,UCloud 編排工具通過梳理整個編排工作流的生命週期,將錯誤資訊嚴格壓縮在(動詞、附加動作、資源名、ID)這個形式化的四元組中,轉化為人類可讀的描述資訊反饋給使用者,對於輸入異常可以在提供一定的互動糾錯能力的前提下,精確定位到原始碼行。
圖:錯誤資訊四元組的自然語言表示樣例
其次, UCloud 通過下文介紹的 API 一致性工程,識別出了所有操作的冪等性質(即該操作是否存在副作用,導致真正的資源建立),並對所有冪等(無副作用的)操作執行自動重試,大幅提升了編排工具的容錯能力,同時保證了自動重試機制是真正安全的。對於非冪等操作,得益於 Terraform 的狀態管理機制,可以簡單地重新執行編排計劃,僅重試失敗的建立過程。
UCloud 編排工具還提供對於非同步操作的同步封裝,使用 Terraform 內建的等待機制,建立資源後,將會輪詢等待資源完成可以查詢方才返回成功,保證操作的原子性和資源狀態的一致性。
最後, 對於上述的重試或等待機制,使用指數級增長的間隔(Exponential Backoff),以及優雅退出(Gracefully Shutdown)的方案,進一步提升資源編排的容錯能力。
接入能力優化
基於 Terraform 的資源編排有一定固有的侷限性,比如其本身更適合基礎設施的構建,不適合 adhoc 的臨時日常工作,比如列表查詢和開關機這樣的操作。
如要批量重啟主機,使用 Terraform 的做法是使用 data source 查詢出對應的資料,定義輸出變數,再將輸出變數值作為引數傳遞給外部的指令碼。在這樣的即席查詢場景下,相對於 Ansible 等配置管理工具並沒有明顯的優勢。
因此 UCloud 在資源編排之外,開發了 UCloud CLI 工具來擴充套件資源編排的能力。例如,使用 CLI 來查詢和重啟通過 UCloud 編排工具建立的資源:
UCloud 實現了資源編排與 UCloud CLI 的整合,資源編排工具可以直接使用 CLI的許可權配置資訊。也可以通過編排工具的特性,呼叫 UCloud CLI 進行額外的資源管理操作。
圖:Terraform 與 CLI 整合用法示例
打通資源編排與 UCloud CLI 之後,資源編排可以複用 CLI 即席查詢的能力,而CLI 可以複用資源編排所持有的資源拓撲資訊,例如主機列表,網路 CIDR 資訊等,極大拓展了雙方的的產品接入能力。
工程能力優化
UCloud 資源編排從立項之初,就將終端使用者使用上的一致性和可用性作為核心訴求。要滿足這些訴求,在工程上必須攻破幾個關鍵的技術難關:
-
儘可能使使用者實現跨版本、跨雲的平滑遷移。
-
同時對資源編排工具所依賴的基礎 API 的實現自動化管理,從源頭上提高編排工具的可用性。
-
資源編排作為關鍵基礎設施的接入方式,本身需要足夠的質量保障措施。
平滑遷移
首先,對於資源編排工具的升級,UCloud 嚴格按照 Terraform 的 Schema 變更策略,每當資源的屬性有破壞性的變更,都會隨之提供版本遷移的實現,使終端使用者在升級工具時,自動將其資源狀態平滑遷移至新版本。
其次,對於雲平臺之間的遷移,UCloud 實現了通用的風格轉換函式,通過將 UCloud 介面的大寫駝峰(Camel)命名,統一對映成 Terraform 常用的小寫下劃線(Snake)風格,並使用 Terraform 建議的產品命名法,降低使用者的跨雲遷移成本。終端使用者只需要少量改動模板,即可通過資源編排工具平滑接入 UCloud。
變更自動化
資源編排作為 UCloud 重要的產品接入方式,對於 UCloud 全線產品都有很強的依賴,介面變更對接時的一點微小錯誤,都可能導致破壞性的後果。
所以一致性工程的重要目標是,快速響應產品新特性的變更,同時儘可能降低人工成本,使變更自動化,減少錯誤的發生。
為了使 API 能夠得到統一管理,同時防止產品間豎井式的資訊隔離,UCloud 很早以前就打造了公共、統一的 API 管理平臺,將所有現網 API 的定義收斂至統一的 API 註冊中心上,使用自定義的格式來形式化地描述 API Schema。API 管理平臺將 API 的場景抽象成測試集(Test Set),一次 API 的呼叫抽象成測試用例(Test Case),並使用自定義的表示式語法構造隨機的引數注入到用例中執行。
圖:API 管理平臺示意圖
基於 API 管理平臺,UCloud 資源編排團隊編寫了 API SDK 的自動化生成程式,通過嚴格形式化的 API 定義,轉譯成 Go SDK 程式碼。同時通過編寫一個遞迴下降的表示式解析器,將測試用例中表達式語法,轉譯成等價的 Go 程式碼。實現了 API 定義和 Go 程式碼的直接對映,低成本同步上游變更。
圖:通過編寫 API 建模工具轉譯 API SDK 程式碼
此外在這個過程中,UCloud 通過在 API 管理平臺與 SDK 之間編寫 API 建模工具,用以抽象出一箇中間層,在該層統一標註出 API 的冪等性質,為資源編排工具提供了真正安全的重試機制。
這樣就完成了整個呼叫鏈路上的介面一致性工程建設,實現了從 API 管理平臺到 SDK 到 Terraform 的完整語義對映,降低了 SDK 的開發和維護成本,同時消除了人為變更帶來的不確定影響。
質量工程建設
資源編排作為大規模雲上資源管理的推薦方式,涉及到關鍵基礎設施的操作與管理,編排工具本身的質量十分關鍵。
表格2:資源編排持續整合檢查表
如表2所示,作為一個開源專案,UCloud 資源編排工具共有三個質量週期,
– 開源協作週期,使用 Travis CI 進行程式碼風格檢查和單元測試,不會發起真正的 API 請求;
– 合併主分支週期,UCloud 使用 Gitlab CI on Kubernetes 進行風格檢查、單元測試和整合測試,其中整合測試會呼叫現網 API 操作真正的雲上資源,並在每天凌晨進行 Daily Regression;
– 釋出正式 Release 到 Terraform 官方倉庫週期,合作方 Hashicorp 使用 TeamCity 進行全量驗收測試,當所有測試完成後,釋出新版本。
為了保證程式碼不會隨時間腐化,提前清除一些隱患,比如拼寫錯誤、安全金鑰洩露、抽象不合理等等,UCloud 接入產品團隊選取了三種不同維度的靜態檢查工具來量化程式碼質量,其中包括:
– GoReportCard,用來做最基本的風格檢查
– SonarCloud,發現程式碼的 Bug 和安全問題
– Gocyclo,計算函式的圈複雜度(圈複雜度是用來衡量一個函式複雜程度的指標,和控制流的複雜程度相關)
並通過週期性的程式碼優化,將程式碼質量的量化指標始終維持在 ** A+ 評級。**
寫在最後
經過長時間的發展,Terraform 已經成為一個業內通用的資源編排工具,且近年來海內外的友商也陸續開始支援基於 Terraform 的資源編排系統,證明了業內對通用資源編排系統的強需求。
UCloud 深入研究了 Terraform 的內部機理,並基於此為 UCloud 下一代資源編排系統進行了深度的探索,在研發過程中多次優化,打通整個鏈路上的基礎工程建設,最後通過充分的質量工程實踐,為資源編排的可靠性與穩定性保駕護航。UCloud Terraform 的具體使用細節和樣例請點選閱讀原文至 UCloud 資源編排官方文件查閱。
歡迎新增小助手微信rocsun,加入UCloud Terraform群,和我們一起暢談關於Terraform的各種需求、