本文發表於一年多前。舊文章可能包含過時內容。請檢查頁面中的資訊自發布以來是否已變得不正確。

使用 Terraform 和 Kubernetes

作為開源 Kubernetes Terraform GitOps 框架 Kubestack 的維護者,我理所當然地花了很多時間使用 Terraform 和 Kubernetes。Kubestack 使用 Terraform 供應 AKS、EKS 和 GKE 等託管 Kubernetes 服務,還將 Kustomize base 中的叢集服務整合到 GitOps 工作流中。叢集服務是指在部署應用程式工作負載之前,Kubernetes 叢集上所需的一切。

Hashicorp 最近宣佈了 Terraform 和 Kubernetes 之間更好的整合。我藉此機會概述了當前如何將 Terraform 與 Kubernetes 結合使用以及需要注意的事項。

然而,在這篇文章中,我將只關注使用 Terraform 供應 Kubernetes API 資源,而不是 Kubernetes 叢集。

Terraform 是一種流行的基礎設施即程式碼解決方案,因此我在這裡只做簡要介紹。簡而言之,Terraform 允許將資源的所需狀態宣告為程式碼,並將確定並執行一個計劃,將基礎設施從當前狀態轉換為所需狀態。

為了支援不同的資源,Terraform 需要整合相應 API 的提供程式。因此,要建立 Kubernetes 資源,我們需要一個 Kubernetes 提供程式。以下是我們的選擇:

Terraform `kubernetes` 提供程式(官方)

首先是官方 Kubernetes 提供程式。這個提供程式無疑是三者中最成熟的。然而,它有一個很大的注意事項,這可能是使用 Terraform 維護 Kubernetes 資源並非流行選擇的主要原因。

Terraform 要求每個資源都有一個模式,這意味著維護者必須將每個 Kubernetes 資源的模式轉換為 Terraform 模式。這需要大量精力,也是為什麼長期以來支援的資源非常有限的原因。雖然這種情況隨著時間的推移有所改善,但仍然不是所有資源都支援。特別是自定義資源無法以這種方式支援。

這種模式轉換還會導致一些需要注意的邊緣情況。例如,Terraform 模式中的 `metadata` 是一個對映列表。這意味著您必須在 Terraform 中像這樣引用 Kubernetes 資源的 `metadata.name`:`kubernetes_secret.example.metadata.0.name`。

然而,從積極的方面來看,擁有 Terraform 模式意味著 Kubernetes 和其他 Terraform 資源之間可以完全整合。例如,例如,使用 Terraform 建立一個型別為 `LoadBalancer` 的 Kubernetes 服務,然後使用返回的 ELB 主機名在 Route53 記錄中配置 DNS。

使用 Terraform 維護 Kubernetes 資源的最大好處是整合到 Terraform 的計劃/應用生命週期中。因此,您可以在應用更改之前檢視計劃的更改。此外,在沒有人工干預的情況下,使用 `kubectl` 從叢集中清除資源並不容易。Terraform 可以可靠地完成此操作。

Terraform `kubernetes-alpha` 提供程式

其次是新的 alpha Kubernetes 提供程式。為了解決當前 Kubernetes 提供程式的侷限性,Hashicorp 團隊最近釋出了一個新提供程式的 alpha 版本。

此提供程式使用動態資源型別和伺服器端應用來支援所有 Kubernetes 資源。我個人認為這個提供程式有潛力成為遊戲規則改變者——即使在 HCL 中管理 Kubernetes 資源可能仍然不適合所有人。也許下面的 Kustomize 提供程式會有所幫助。

唯一的缺點是,明確不鼓勵將其用於除測試之外的任何用途。但是,測試的人越多,它就越快準備好投入使用。所以我鼓勵大家嘗試一下。

Terraform `kustomize` 提供程式

最後,我們有`kustomize` 提供程式。Kustomize 提供了一種使用繼承而不是模板來定製 Kubernetes 資源的方法。它旨在將結果輸出到 `stdout`,然後您可以使用 `kubectl` 應用更改。這種方法意味著 `kubectl` 的邊緣情況,例如無法清除或更改不可變屬性,仍然使完全自動化變得困難。

Kustomize 是一種流行的定製處理方式。但我正在尋找一種更可靠的方法來自動化應用更改。由於這正是 Terraform 的強項,因此 Kustomize 提供程式應運而生。

這裡不贅述太多細節,但從 Terraform 的角度來看,此提供程式將每個 Kubernetes 資源視為 JSON 字串。這樣,它可以處理 Kustomize 構建產生的任何 Kubernetes 資源。但它有一個很大的缺點,即 Kubernetes 資源無法輕易與其他 Terraform 資源整合。請記住上面提到的負載均衡器示例。

在底層,類似於新的 Kubernetes alpha 提供程式,Kustomize 提供程式也使用動態 Kubernetes 客戶端和伺服器端應用。未來,我計劃棄用 Kustomize 提供程式中與新 Kubernetes 提供程式重疊的部分,並僅保留 Kustomize 整合。

結論

對於已經投入 Terraform 的團隊,或者正在尋找替代 `kubectl` 進行自動化的團隊來說,Terraform 的計劃/應用生命週期一直是一個很有前途的選擇,可以自動化對 Kubernetes 資源的更改。然而,官方 Kubernetes 提供程式的侷限性導致其未能得到廣泛採用。

新的 alpha 提供程式消除了這些限制,並有潛力使 Terraform 成為自動化 Kubernetes 資源更改的首選。

對於已經採用 Kustomize 的團隊來說,使用 Kustomize 提供程式將 Kustomize 和 Terraform 整合可能比使用 `kubectl` 更有益,因為它避免了常見的邊緣情況。即使在這種設定中,Terraform 也只能輕鬆用於計劃和應用更改,而不能用於調整 Kubernetes 資源。未來,這個問題可能透過結合 Kustomize 提供程式和新的 Kubernetes 提供程式來解決。

如果您對這三種選擇有任何疑問,請隨時透過 Kubernetes Slack 在 #kubestack#kustomize 頻道與我聯絡。如果您嘗試使用任何提供程式並遇到問題,請提交 GitHub 問題以幫助維護者解決。