Seal AppManager如何基于Terraform簡化基礎設施管理

作者簡介
陳燦,數澈軟件Seal 后端研發(fā)工程師,曾在騰訊負責敏捷研發(fā)體系建設以及 DevOps 解決方案的敏捷實踐。在敏捷研發(fā)和產品效能提升有著豐富的經驗,致力于構建一站式研發(fā)友好的平臺工程解決方案?,F在是 Seal 平臺工程團隊核心研發(fā)人員。
?
平臺工程(Platform Engineering)是近幾年大火的技術概念,指專注于通過減少現代軟件交付的復雜性和不確定性來提高開發(fā)人員的生產力的一種軟件工程方法。內部開發(fā)平臺則是平臺工程的具體實現之一。本文將結合平臺工程的理念介紹 Terraform 的基本概念和使用方法,包括在使用 Terraform 的過程中所面臨的一些挑戰(zhàn)以及 Seal AppManager 是如何解決這些問題的。
?
什么是內部開發(fā)者平臺(IDP)
內部開發(fā)平臺, Internal Development Platform(IDP),是建立在工程團隊現有技術工具之上的一個自助服務層。IDP 是一個由平臺團隊開發(fā)的平臺,使開發(fā)人員能夠輕松地配置、部署和啟動應用基礎設施,無需依賴運維團隊。IDP 有助于進一步自動化運維工作流程,并通過簡化應用程序配置和基礎設施管理來彌補和提升工作效率。同時,IDP 讓開發(fā)人員擁有更多的自主權,使開發(fā)人員從編寫代碼到軟件交付,都能夠處理自如。
?
在傳統(tǒng)的基礎設施部署和管理中,通常會使用手動配置和管理的方式。這意味著管理員需要手動操作服務器、網絡設備和存儲等基礎設施組件,安裝和配置軟件,以及處理各種依賴關系和環(huán)境變化。這種方式需要花費大量的時間和精力,并且容易出現配置錯誤和不一致性。
?

?
平臺工程的首要任務之一是降低開發(fā)人員使用基礎設施的難度。因為絕大多數的開發(fā)人員并不關心底層服務的復雜概念和創(chuàng)建方式,比如開發(fā)需要用存儲服務,但不關心它們是如何創(chuàng)建的,再如一些專有名詞如對象存儲、磁盤陣列等,也不屬于開發(fā)人員的關心范疇。
?
在大多數的業(yè)務場景中,開發(fā)人員只關注如何使用這些服務、數據是否可以持久化地保存在指定目錄中。因此,平臺工程完全可以提供一個適應大多數場景的存儲服務,開發(fā)人員只需要選擇自己所需要的服務類型,利用平臺工程的能力創(chuàng)建服務,獲取服務的地址,即可使用該服務。
?
平臺工程通過抽象定義,在服務的基礎上抽象出應用這一概念,多個應用可以組合成一個業(yè)務場景,應用之間存在顯式或者隱式的關系。彼此之間通過這種關系有機地組合成一個完整的業(yè)務整體,并對外提供服務。
?

?
什么是 Terraform
Terraform 是一個基礎設施即代碼(IaC)工具,它允許你安全、高效地構建、改變和更新基礎設施。這包括低級別的組件,如計算實例、存儲和網絡,以及高級別的組件,如 DNS 條目、SaaS 功能等。
?
在 Terraform 誕生之前,基礎設施的管理是一個非常繁瑣的工作,需要人工操作,而且易出錯,而 Terraform 的出現,讓基礎設施的管理變得簡單、高效、可靠。Terraform 特別適合云環(huán)境:AWS、GCP、Azure、阿里云等, 通過豐富的 Provider 管理不同類型的資源,一切都像插件一樣,可以輕松地擴展。
?
Terraform 采用 HCL 代碼管理和維護基礎設施資源,并且在運行之前可以通過terraform plan命令可以看到資源的變化,而這些變化是通過 Terraform 的狀態(tài)文件來管理的。
?
Terraform 的 State(狀態(tài))是一個關鍵概念,用于記錄當前基礎設施的狀態(tài)和配置。使用 Terraform 進行部署時,它會跟蹤已創(chuàng)建的資源和其配置狀態(tài),并將其存儲在本地的.tfstate文件中或使用遠程存儲(如AWS S3、Azure Blob存儲)進行管理。
?
State 文件記錄了資源的狀態(tài),當資源發(fā)生變化時,配置狀態(tài)也會變化。因此,Terraform 支持在部署前預覽資源變化而不需要真正的執(zhí)行。Terrafrom 的配置狀態(tài)文件可以保存在本地,也支持保存在遠程的存儲中,如:S3、Consul、gcs、kubernetes 或者其他自定義的 HTTP Backend 中。
?

?
安裝 Terraform
?
macOS
?
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
?
Linux Ubuntu
?
wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpgecho "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
sudo apt update && sudo apt install terraform
?
Linux CentOS
?
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.reposudo yum -y install terraform
?
Linux 二進制安裝
?
Linux 用戶也可以通過二進制的方式安裝 Terraform,從官方下載對應的版本。
https://www.terraform.io/downloads.html
?
通過二進制安裝 1.4.6 版本的 Terraform:
?
curl -sfL https://releases.hashicorp.com/terraform/1.4.6/terraform_1.4.6_linux_amd64.zip -o /tmp/terraform.zip
unzip /tmp/terraform.zip -d /usr/bin/rm -f /tmp/terraform.zip
?
Windows
?
windows 用戶可以通過 Chocolatey 來安裝 Terraform, Chocolatey 是一個 Windows 的包管理器,類似于 Linux 的 yum 或者 apt-get,它可以幫助你快速的安裝和卸載軟件。
?
choco install terraform
?
或者去 Terraform 官網下載對應的版本,然后解壓后配置 PATH 環(huán)境變量。最后,通過terraform version
命令來驗證是否安裝成功。
?
Terraform 管理 Kubernetes 資源示例
配置 Kubernetes Provider,通過后~/.kube/config文件來管理 Kubernetes 資源,這里也可以使用其他的 kubeconfig 文件。
?
provider "kubernetes" {
?config_path = "~/.kube/config"}
?
創(chuàng)建一個 Kubernetes Deployment
?
resource "kubernetes_deployment" "nginx" { ?metadata {
? ?name = "nginx"
? ?labels = {
? ? ?app = "nginx"
? ?}
?} ?spec {
? ?replicas = 1
? ?selector {
? ? ?match_labels = {
? ? ? ?app = "nginx"
? ? ?}
? ?} ? ?template { ? ? ?metadata {
? ? ? ?labels = {
? ? ? ? ?app = "nginx"
? ? ? ?}
? ? ?} ? ? ?spec { ? ? ? ?container {
? ? ? ? ?image = "nginx:latest"
? ? ? ? ?name = "nginx"
? ? ? ? ?port {
? ? ? ? ? ?container_port = 80
? ? ? ? ?}
? ? ? ?}
? ? ?}
? ?}
?}
}
?
Kubernetes Deployment 服務
?
resource "kubernetes_service" "nginx" { ?metadata {
? ?name = "nginx"
?} ?spec {
? ?selector = {
? ? ?app = kubernetes_deployment.nginx.metadata[0].labels.app
? ?} ? ?type = "NodePort"
? ?port {
? ? ?port = 80
? ? ?target_port = 80
? ? ?node_port = 30080
? ?}
?}
}
?
將上面的配置復制并在目標目錄如~/terraform-demo
?
mkdir ~/terraform-demo && cd ~/terraform-demo
?
創(chuàng)建 main.tf 文件,將上述配置復制到 main.tf 并保存,完整的文件配置如下:
?

?
打開終端,進入到目標目錄,初始化 Terraform 環(huán)境
cd ~/terraform-demo && terraform init
?

?
執(zhí)行terraform plan
來預覽資源的變化
?

?
執(zhí)行terraform apply
來創(chuàng)建資源
?

?
最后在瀏覽器中訪問http://localhost:30080
即可看到 nginx 的歡迎頁面。
?

?
如果想要刪除資源,可以執(zhí)行terraform destroy
命令來刪除資源。
?
通過上述例子,我們可以看到 Terraform 的管理 Kubernetes 資源非常簡單,只需要通過 HCL 語言來描述資源的配置,然后通過terraform apply
來創(chuàng)建資源。此外 Terraform 還支持通過terraform import
來導入已經存在的資源,這樣就可以將已經存在的資源納入到 Terraform 的中進行管理。
?
Terraform 狀態(tài)管理
Terraform 通過 HCL 描繪了資源的配置,但它如何知道資源是否已經被創(chuàng)建了呢?資源的新增、修改和刪除是如何決定的?它怎樣管理資源之間的依賴關系呢?要了解這些問題,就得依賴 Terraform 的狀態(tài)管理機制了。
?
Terraform 將每次執(zhí)行基礎設施變更操作時的狀態(tài)信息保存在一個狀態(tài)(State)文件中,默認情況下會保存在當前工作目錄下的terraform.tfstate
文件里,依托于狀態(tài)文件來決定執(zhí)行資源的變更方式。
?
在上述示例中,可以看到生成的狀態(tài)(State) 文件中包含所創(chuàng)建的資源,如kubernetes_deployment
和kubernetes_service
,這與我們編寫 HCL 文件的資源也是相對應的,我們所創(chuàng)建的 resource 和 data 資源都會被記錄到這個文件。
?
狀態(tài)(State) 文件中還包含了一些元數據信息,如資源的 ID、資源的屬性值等,這些信息都是 Terraform 用來管理資源的重要依據。
?

?
我們知道獲取云資源狀態(tài)常見的方式之一是通過各個平臺自身提供的 API 服務來獲取,比較 API 資源和配置文件資源的異同來決定創(chuàng)建或者刪除資源,而 Terraform 卻選擇狀態(tài)(State)文件來管理映射云平臺的資源,而不是API 的方式來檢查資源是否已經被創(chuàng)建,原因是什么呢?
?
Terraform 采取狀態(tài)(State)文件的方式的好處有:
?
Terraform 可以直接通過該文件獲取創(chuàng)建的云資源狀態(tài)。對于小型基礎設施,Terraform 可以查詢并同步所有資源的最新屬性,這樣在每次 apply 的時候只需要檢查資源和狀態(tài)文件的配置是否一致。如果一致則不需要做任何操作,如果不一致則需要創(chuàng)建、更新或者刪除資源。
通過狀態(tài)文件可以記錄不同資源之間的關系,Terraform 可以通過依賴關系來管理創(chuàng)建或者銷毀的順序。
另外,對于大型基礎設施,查詢每個資源的耗時會較長。許多云提供商不提供同時查詢多個資源的 API,每個資源的往返時間為數百毫秒。除此之外,云提供商幾乎總是有 API 速率限制,因此 Terraform 在一段時間內只能請求一定數量的資源,通過 state 狀態(tài)管理可以大大提升性能。
遠端的 Backend 可以管理狀態(tài)文件,這樣可以實現多人協(xié)作,多人共享同一個狀態(tài)文件。
?
然而,采用這種方式管理資源并非十全十美,當執(zhí)行terraform apply
時,Terraform 會直接讀取 State 文件來判斷是否需要創(chuàng)建、更新或者刪除資源。如果我們手動刪除這個文件,再次執(zhí)行terraform apply
時,Terraform 會認為這是一個全新的環(huán)境,從而會重新創(chuàng)建所有的資源,進而導致資源的管控混亂——原先創(chuàng)建的資源就再也沒法通過terraform destroy
來刪除了。因此妥善保管好這個狀態(tài)文件非常重要,任何時候都不要手動修改或者刪除這個文件。
?
細心的你可能會發(fā)現,狀態(tài)(State)文件中的所有信息都是明文的,這意味著如果這個文件泄露,里面包含密碼等關鍵信息都會被泄露,這將會對你的基礎設施造成巨大的安全風險。除此之外,如果因設備損壞或者其他因素導致文件損壞,那么 tfstate 所記錄的資源信息也會丟失,這樣也會導致資源的泄露、管控混亂。
?
因此,Terraform 還提供了一種 Backend 的狀態(tài)管理方案。這樣就可以將狀態(tài)文件保存在遠程的存儲中,比如 AWS S3、GCS、HTTP 等,這樣就可以避免狀態(tài)文件被泄露的風險。團隊成員之間可以利用 Backend 解決文件存儲和共享的問題。
?
使用 Terraform 所面臨的挑戰(zhàn)
通過上面的示例,我們可以看到 Terraform 管理 Kubernetes 資源非常簡單,但是正如前文中提到過的 Terraform 也存在一些問題,這些問題可能會影響到我們對資源管理的使用體驗。比如:
?
使用 HCL 語言來描述資源的配置,意味著開發(fā)人員需要學習一門新的語言,而且如果想要使用 Terraform 來管理其他資源,比如 AWS、GCP 等,那么就需要學習這些資源的 Provider 的配置,導致學習成本增加。另外一些語法問題也會增加使用的難度。
狀態(tài)管理問題,Terraform 通過狀態(tài)文件來管理資源,而狀態(tài)文件所記錄的資源都是明文的。如果狀態(tài)文件遭受泄露、損壞等情況,會對資源的管控造成巨大的風險。
基礎設施資源管理者需要擁有對資源的知識經驗,這樣才能夠正確的配置資源,否則就會導致資源的配置錯誤導致資源的創(chuàng)建失敗,或者資源的配置不符合預期。
大量的資源管控需要編寫大量的 HCL 文件,資源的使用者需要花費大量的時間來查找資源和配置文件,管理資源的成本也會隨著資源的增加而增加。
資源的狀態(tài)不能實時獲取,如 Kubernetes 的資源狀態(tài),查看日志和執(zhí)行終端等等,這些需要通過其他的方式管理。
?
利用 Seal AppManager 降低管理基礎設施難度
Seal AppManager 是一款基于平臺工程理念的應用部署管理平臺,底層基于 Terraform 技術構建,上周剛剛發(fā)布新版本。它可以幫助開發(fā)人員和運維快速地搭建一個生產或者測試環(huán)境,同時也可以幫助運維人員快速地管理這些環(huán)境,通過平臺工程的能力解決上述問題。
?
Seal AppManager 可以將資源抽象成服務,利用應用來控制這些服務,進而將資源的底層配置和實際使用分離開,簡化基礎設施的管理。
?
通過管理多個環(huán)境和配置的方法,確保開發(fā)、測試和生產環(huán)境的一致性,降低錯誤和不一致的風險,并確保應用程序始終準確運行。
?
由于平臺提供控制和治理功能,開發(fā)人員還可以確保所使用的環(huán)境是安全的,并且符合最佳實踐和安全標準。資源的使用者只需要關注資源的使用,而不需要關注資源的底層原理及配置。
?

?
通過定義的資源模版,開發(fā)人員無需再關注 HCL 語言的語法,Terraform Provider 參數該如何配置以及基礎設施的底層實現是什么原理,只需要通過平臺提供的 UI 界面,通過定義好的模塊填寫參數就可以自助使用資源。這大大降低了開發(fā)人員使用資源的難度,提升了整體的開發(fā)效率。
?
除此之外,Terraform 的狀態(tài)管理的不便之處也得到了解決。Seal AppManager 平臺通過將狀態(tài)文件保存在 HTTP Backend 遠端,這樣就可以避免狀態(tài)文件被泄露的風險。不同的服務之間會自動管理所屬的狀態(tài),這樣團隊成員之間可以利用 Backend 解決狀態(tài)存儲和共享的問題。
?