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

使用 Terraform 和 Kubernetes

維護 Kubestack,一個用於 Kubernetes 的開放原始碼 Terraform GitOps 框架,我不意外地花費大量時間使用 Terraform 和 Kubernetes。Kubestack 使用 Terraform 佈建託管的 Kubernetes 服務,例如 AKS、EKS 和 GKE,同時也將來自 Kustomize 基底的叢集服務整合到 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.namekubernetes_secret.example.metadata.0.name

然而,從好的方面來說,擁有 Terraform 綱要意味著 Kubernetes 和其他 Terraform 資源之間的完全整合。例如,像 範例 一樣,使用 Terraform 建立類型為 LoadBalancer 的 Kubernetes 服務,然後在 Route53 記錄中使用傳回的 ELB 主機名稱來設定 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 issue 以幫助維護者修復它。