作者簡介
陳燦,數澈軟體Seal 後端研發工程師,曾在騰訊負責靈活研發體系建設以及 DevOps 解決方案的靈活實踐。在靈活研發和産品效能提升有着豐富的經驗,緻力于建構一站式研發友好的平台工程解決方案。現在是 Seal 平台工程團隊核心研發人員。
平台工程(Platform Engineering)是近幾年大火的技術概念,指專注于通過減少現代軟體傳遞的複雜性和不确定性來提高開發人員的生産力的一種軟體工程方法。内部開發平台則是平台工程的具體實作之一。本文将結合平台工程的理念介紹 Terraform 的基本概念和使用方法,包括在使用 Terraform 的過程中所面臨的一些挑戰以及 Seal AppManager 是如何解決這些問題的。
什麼是内部開發者平台(IDP)
内部開發平台, Internal Development Platform(IDP),是建立在工程團隊現有技術工具之上的一個自助服務層。IDP 是一個由平台團隊開發的平台,使開發人員能夠輕松地配置、部署和啟動應用基礎設施,無需依賴運維團隊。IDP 有助于進一步自動化運維工作流程,并通過簡化應用程式配置和基礎設施管理來彌補和提升工作效率。同時,IDP 讓開發人員擁有更多的自主權,使開發人員從編寫代碼到軟體傳遞,都能夠處理自如。
在傳統的基礎設施部署和管理中,通常會使用手動配置和管理的方式。這意味着管理者需要手動操作伺服器、網絡裝置和存儲等基礎設施元件,安裝和配置軟體,以及處理各種依賴關系和環境變化。這種方式需要花費大量的時間和精力,并且容易出現配置錯誤和不一緻性。
平台工程的首要任務之一是降低開發人員使用基礎設施的難度。因為絕大多數的開發人員并不關心底層服務的複雜概念和建立方式,比如開發需要用存儲服務,但不關心它們是如何建立的,再如一些專有名詞如對象存儲、磁盤陣列等,也不屬于開發人員的關心範疇。
在大多數的業務場景中,開發人員隻關注如何使用這些服務、資料是否可以持久化地儲存在指定目錄中。是以,平台工程完全可以提供一個适應大多數場景的存儲服務,開發人員隻需要選擇自己所需要的服務類型,利用平台工程的能力建立服務,擷取服務的位址,即可使用該服務。
平台工程通過抽象定義,在服務的基礎上抽象出應用這一概念,多個應用可以組合成一個業務場景,應用之間存在顯式或者隐式的關系。彼此之間通過這種關系有機地組合成一個完整的業務整體,并對外提供服務。
什麼是 Terraform
Terraform 是一個基礎設施即代碼(IaC)工具,它允許你安全、高效地建構、改變和更新基礎設施。這包括低級别的元件,如計算執行個體、存儲和網絡,以及進階别的元件,如 DNS 條目、SaaS 功能等。
在 Terraform 誕生之前,基礎設施的管理是一個非常繁瑣的工作,需要人工操作,而且易出錯,而 Terraform 的出現,讓基礎設施的管理變得簡單、高效、可靠。Terraform 特别适合雲環境:AWS、GCP、Azure、阿裡雲等, 通過豐富的 Provider 管理不同類型的資源,一切都像插件一樣,可以輕松地擴充。
Terraform 采用 HCL 代碼管理和維護基礎設施資源,并且在運作之前可以通過terraform plan指令可以看到資源的變化,而這些變化是通過 Terraform 的狀态檔案來管理的。
Terraform 的 State(狀态)是一個關鍵概念,用于記錄目前基礎設施的狀态和配置。使用 Terraform 進行部署時,它會跟蹤已建立的資源和其配置狀态,并将其存儲在本地的.tfstate檔案中或使用遠端存儲(如AWS S3、Azure Blob存儲)進行管理。
State 檔案記錄了資源的狀态,當資源發生變化時,配置狀态也會變化。是以,Terraform 支援在部署前預覽資源變化而不需要真正的執行。Terrafrom 的配置狀态檔案可以儲存在本地,也支援儲存在遠端的存儲中,如: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.gpg
echo "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.repo
sudo 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 環境變量。最後,通過terraform version指令來驗證是否安裝成功。
Terraform 管理 Kubernetes 資源示例
配置 Kubernetes Provider,通過後~/.kube/config檔案來管理 Kubernetes 資源,這裡也可以使用其他的 kubeconfig 檔案。
provider "kubernetes" {
config_path = "~/.kube/config"
}
建立一個 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
建立 main.tf 檔案,将上述配置複制到 main.tf 并儲存,完整的檔案配置如下:
打開終端,進入到目标目錄,初始化 Terraform 環境
cd ~/terraform-demo && terraform init
執行terraform plan來預覽資源的變化
執行terraform apply來建立資源
最後在浏覽器中通路http://localhost:30080即可看到 nginx 的歡迎頁面。
如果想要删除資源,可以執行terraform destroy指令來删除資源。
通過上述例子,我們可以看到 Terraform 的管理 Kubernetes 資源非常簡單,隻需要通過 HCL 語言來描述資源的配置,然後通過terraform apply來建立資源。此外 Terraform 還支援通過terraform import來導入已經存在的資源,這樣就可以将已經存在的資源納入到 Terraform 的中進行管理。
Terraform 狀态管理
Terraform 通過 HCL 描繪了資源的配置,但它如何知道資源是否已經被建立了呢?資源的新增、修改和删除是如何決定的?它怎樣管理資源之間的依賴關系呢?要了解這些問題,就得依賴 Terraform 的狀态管理機制了。
Terraform 将每次執行基礎設施變更操作時的狀态資訊儲存在一個狀态(State)檔案中,預設情況下會儲存在目前工作目錄下的terraform.tfstate檔案裡,依托于狀态檔案來決定執行資源的變更方式。
在上述示例中,可以看到生成的狀态(State) 檔案中包含所建立的資源,如kubernetes_deployment和kubernetes_service,這與我們編寫 HCL 檔案的資源也是相對應的,我們所建立的 resource 和 data 資源都會被記錄到這個檔案。
狀态(State) 檔案中還包含了一些中繼資料資訊,如資源的 ID、資源的屬性值等,這些資訊都是 Terraform 用來管理資源的重要依據。
我們知道擷取雲資源狀态常見的方式之一是通過各個平台自身提供的 API 服務來擷取,比較 API 資源和配置檔案資源的異同來決定建立或者删除資源,而 Terraform 卻選擇狀态(State)檔案來管理映射雲平台的資源,而不是API 的方式來檢查資源是否已經被建立,原因是什麼呢?
Terraform 采取狀态(State)檔案的方式的好處有:
- Terraform 可以直接通過該檔案擷取建立的雲資源狀态。對于小型基礎設施,Terraform 可以查詢并同步所有資源的最新屬性,這樣在每次 apply 的時候隻需要檢查資源和狀态檔案的配置是否一緻。如果一緻則不需要做任何操作,如果不一緻則需要建立、更新或者删除資源。
- 通過狀态檔案可以記錄不同資源之間的關系,Terraform 可以通過依賴關系來管理建立或者銷毀的順序。
- 另外,對于大型基礎設施,查詢每個資源的耗時會較長。許多雲提供商不提供同時查詢多個資源的 API,每個資源的往返時間為數百毫秒。除此之外,雲提供商幾乎總是有 API 速率限制,是以 Terraform 在一段時間内隻能請求一定數量的資源,通過 state 狀态管理可以大大提升性能。
- 遠端的 Backend 可以管理狀态檔案,這樣可以實作多人協作,多人共享同一個狀态檔案。
然而,采用這種方式管理資源并非十全十美,當執行terraform apply時,Terraform 會直接讀取 State 檔案來判斷是否需要建立、更新或者删除資源。如果我們手動删除這個檔案,再次執行terraform apply時,Terraform 會認為這是一個全新的環境,進而會重新建立所有的資源,進而導緻資源的管控混亂——原先建立的資源就再也沒法通過terraform destroy來删除了。是以妥善保管好這個狀态檔案非常重要,任何時候都不要手動修改或者删除這個檔案。
細心的你可能會發現,狀态(State)檔案中的所有資訊都是明文的,這意味着如果這個檔案洩露,裡面包含密碼等關鍵資訊都會被洩露,這将會對你的基礎設施造成巨大的安全風險。除此之外,如果因裝置損壞或者其他因素導緻檔案損壞,那麼 tfstate 所記錄的資源資訊也會丢失,這樣也會導緻資源的洩露、管控混亂。
是以,Terraform 還提供了一種 Backend 的狀态管理方案。這樣就可以将狀态檔案儲存在遠端的存儲中,比如 AWS S3、GCS、HTTP 等,這樣就可以避免狀态檔案被洩露的風險。團隊成員之間可以利用 Backend 解決檔案存儲和共享的問題。
使用 Terraform 所面臨的挑戰
通過上面的示例,我們可以看到 Terraform 管理 Kubernetes 資源非常簡單,但是正如前文中提到過的 Terraform 也存在一些問題,這些問題可能會影響到我們對資源管理的使用體驗。比如:
- 使用 HCL 語言來描述資源的配置,意味着開發人員需要學習一門新的語言,而且如果想要使用 Terraform 來管理其他資源,比如 AWS、GCP 等,那麼就需要學習這些資源的 Provider 的配置,導緻學習成本增加。另外一些文法問題也會增加使用的難度。
- 狀态管理問題,Terraform 通過狀态檔案來管理資源,而狀态檔案所記錄的資源都是明文的。如果狀态檔案遭受洩露、損壞等情況,會對資源的管控造成巨大的風險。
- 基礎設施資源管理者需要擁有對資源的知識經驗,這樣才能夠正确的配置資源,否則就會導緻資源的配置錯誤導緻資源的建立失敗,或者資源的配置不符合預期。
- 大量的資源管控需要編寫大量的 HCL 檔案,資源的使用者需要花費大量的時間來查找資源和配置檔案,管理資源的成本也會随着資源的增加而增加。
- 資源的狀态不能實時擷取,如 Kubernetes 的資源狀态,檢視日志和執行終端等等,這些需要通過其他的方式管理。
利用 Seal AppManager 降低管理基礎設施難度
Seal AppManager 是一款基于平台工程理念的應用部署管理平台,底層基于 Terraform 技術建構,上周剛剛釋出新版本。它可以幫助開發人員和運維快速地搭建一個生産或者測試環境,同時也可以幫助運維人員快速地管理這些環境,通過平台工程的能力解決上述問題。
Seal AppManager 可以将資源抽象成服務,利用應用來控制這些服務,進而将資源的底層配置和實際使用分離開,簡化基礎設施的管理。
通過管理多個環境和配置的方法,確定開發、測試和生産環境的一緻性,降低錯誤和不一緻的風險,并確定應用程式始終準确運作。
由于平台提供控制和治理功能,開發人員還可以確定所使用的環境是安全的,并且符合最佳實踐和安全标準。資源的使用者隻需要關注資源的使用,而不需要關注資源的底層原理及配置。
通過定義的資源模版,開發人員無需再關注 HCL 語言的文法,Terraform Provider 參數該如何配置以及基礎設施的底層實作是什麼原理,隻需要通過平台提供的 UI 界面,通過定義好的子產品填寫參數就可以自助使用資源。這大大降低了開發人員使用資源的難度,提升了整體的開發效率。
除此之外,Terraform 的狀态管理的不便之處也得到了解決。Seal AppManager 平台通過将狀态檔案儲存在 HTTP Backend 遠端,這樣就可以避免狀态檔案被洩露的風險。不同的服務之間會自動管理所屬的狀态,這樣團隊成員之間可以利用 Backend 解決狀态存儲和共享的問題。