Helm 2 以來的變更

Helm 2 以來的變更

以下是 Helm 3 中引入的所有主要變更的詳盡列表。

移除 Tiller

在 Helm 2 的開發週期中,我們引入了 Tiller。Tiller 在團隊在共享叢集上工作時扮演了重要的角色 - 它使多個不同的操作員能夠與同一組版本互動。

由於 Kubernetes 1.6 中預設啟用了基於角色的存取控制 (RBAC),因此在生產環境中鎖定 Tiller 以供使用變得更加難以管理。由於可能的安全策略數量眾多,我們的立場是提供允許的預設配置。這允許初次使用者開始試驗 Helm 和 Kubernetes,而無需深入研究安全控制。不幸的是,這種允許的配置可能會授予使用者超出預期範圍的廣泛權限。DevOps 和 SRE 在將 Tiller 安裝到多租戶叢集中時必須學習額外的操作步驟。

在聽取社群成員如何在某些情況下使用 Helm 後,我們發現 Tiller 的版本管理系統不需要依賴叢集內操作員來維護狀態或充當 Helm 版本資訊的中央樞紐。相反,我們可以簡單地從 Kubernetes API 伺服器擷取資訊,在用戶端呈現圖表,並在 Kubernetes 中儲存安裝記錄。

Tiller 的主要目標可以在沒有 Tiller 的情況下完成,因此我們關於 Helm 3 的首批決定之一是完全移除 Tiller。

隨著 Tiller 的消失,Helm 的安全模型得到了極大的簡化。Helm 3 現在支援現代 Kubernetes 的所有現代安全、身分識別和授權功能。Helm 的權限使用您的 kubeconfig 檔案 進行評估。叢集管理員可以根據他們認為合適的粒度限制使用者權限。版本仍會記錄在叢集中,Helm 的其餘功能將保留。

改進的升級策略:三向策略合併修補程式

Helm 2 使用雙向策略合併修補程式。在升級期間,它會將最新圖表的資訊清單與建議圖表的資訊清單(在 helm upgrade 期間提供的資訊清單)進行比較。它比較了這兩個圖表之間的差異,以確定需要對 Kubernetes 中的資源應用哪些變更。如果對叢集進行了帶外變更(例如在 kubectl edit 期間),則不會考慮這些變更。這導致資源無法回滾到其先前的狀態:因為 Helm 僅將最後應用的圖表資訊清單視為其當前狀態,所以如果圖表狀態沒有變更,則實際狀態將保持不變。

在 Helm 3 中,我們現在使用三向策略合併修補程式。Helm 在產生修補程式時會考慮舊資訊清單、其實際狀態和新資訊清單。

範例

讓我們通過幾個常見的範例來了解此變更的影響。

在實際狀態已變更的情況下回滾

您的團隊剛剛使用 Helm 將他們的應用程式部署到 Kubernetes 上的生產環境。該圖表包含一個部署物件,其中副本數設定為三個

$ helm install myapp ./myapp

一位新的開發人員加入了團隊。在他們觀察生產叢集的第一天,發生了一起可怕的咖啡灑在鍵盤上的事故,他們使用 kubectl scale 將生產部署從三個副本縮減到零。

$ kubectl scale --replicas=0 deployment/myapp

您團隊中的另一位開發人員注意到生產網站已關閉,並決定將版本回滾到其先前的狀態

$ helm rollback myapp

會發生什麼?

在 Helm 2 中,它會產生一個修補程式,將舊資訊清單與新資訊清單進行比較。因為這次回滾,所以它是同一個資訊清單。Helm 會確定沒有任何要變更的內容,因為舊資訊清單和新資訊清單之間沒有差異。副本數繼續保持為零。恐慌隨之而來。

在 Helm 3 中,修補程式是使用舊資訊清單、實際狀態和新資訊清單產生的。Helm 認識到舊狀態為三個,實際狀態為零,並且新資訊清單希望將其更改回三個,因此它會產生一個修補程式以將狀態更改回三個。

實際狀態已變更的升級

許多服務網格和其他基於控制器的應用程式會將資料注入 Kubernetes 物件。這可以是邊車、標籤或其他資訊。以前,如果您有從圖表渲染的給定資訊清單

containers:
- name: server
  image: nginx:2.0.0

並且實際狀態已被另一個應用程式修改為

containers:
- name: server
  image: nginx:2.0.0
- name: my-injected-sidecar
  image: my-cool-mesh:1.0.0

現在,您想要將 nginx 影像標籤升級到 2.1.0。因此,您升級到具有給定資訊清單的圖表

containers:
- name: server
  image: nginx:2.1.0

會發生什麼?

在 Helm 2 中,Helm 會在舊資訊清單和新資訊清單之間產生 containers 物件的修補程式。在修補程式產生期間不會考慮叢集的實際狀態。

叢集的實際狀態被修改為如下所示

containers:
- name: server
  image: nginx:2.1.0

邊車 pod 已從實際狀態中移除。更多的恐慌隨之而來。

在 Helm 3 中,Helm 會在舊資訊清單、實際狀態和新資訊清單之間產生 containers 物件的修補程式。它注意到新資訊清單將影像標籤更改為 2.1.0,但實際狀態包含邊車容器。

叢集的實際狀態被修改為如下所示

containers:
- name: server
  image: nginx:2.1.0
- name: my-injected-sidecar
  image: my-cool-mesh:1.0.0

版本名稱現在的範圍限定為命名空間

隨著 Tiller 的移除,每個版本的資訊都必須存放在某個地方。在 Helm 2 中,這儲存在與 Tiller 相同的命名空間中。實際上,這意味著一旦版本使用了名稱,則其他版本就不能使用相同的名稱,即使它部署在不同的命名空間中。

在 Helm 3 中,有關特定版本的資訊現在儲存在與版本本身相同的命名空間中。這意味著使用者現在可以在兩個不同的命名空間中 helm install wordpress stable/wordpress,並且可以通過更改當前命名空間上下文(例如 helm list --namespace foo)使用 helm list 引用每個命名空間。

通過與原生叢集命名空間的這種更緊密的對齊,helm list 命令不再預設列出所有版本。相反,它只會列出您當前 kubernetes 上下文命名空間中的版本(即執行 kubectl config view --minify 時顯示的命名空間)。這也意味著您必須向 helm list 提供 --all-namespaces 旗標才能獲得與 Helm 2 類似的行為。

Secrets 作為預設儲存驅動程式

在 Helm 3 中,Secrets 現在被用作 預設儲存驅動程式。Helm 2 預設使用 ConfigMaps 來儲存版本資訊。在 Helm 2.7.0 中,實現了一個新的儲存後端,它使用 Secrets 來儲存版本資訊,並且它現在是 Helm 3 中的預設儲存後端。

將 Secrets 更改為 Helm 3 預設值允許在 Kubernetes 中釋出 Secret 加密功能的同時,在保護圖表方面提供額外的安全性。

靜態加密 Secrets 在 Kubernetes 1.7 中作為 alpha 功能提供,並在 Kubernetes 1.13 中變得穩定。這允許使用者靜態加密 Helm 版本中繼資料,因此這是一個很好的起點,以後可以擴展到使用 Vault 之類的東西。

Go 導入路徑變更

在 Helm 3 中,Helm 將 Go 導入路徑從 k8s.io/helm 切換到 helm.sh/helm/v3。如果您打算升級到 Helm 3 Go 用戶端程式庫,請確保更改您的導入路徑。

功能

在渲染階段可用的 .Capabilities 內建物件已被簡化。

內建物件

使用 JSONSchema 驗證圖表值

現在可以將 JSON Schema 強加於圖表值。這確保使用者提供的數值遵循圖表維護者佈局的架構,從而在使用者為圖表提供不正確的數值集時提供更好的錯誤報告。

當呼叫以下任何命令時,會發生驗證

  • helm install
  • helm upgrade
  • helm template
  • helm lint

有關更多資訊,請參閱 Schema 檔案 上的文件。

requirements.yaml 合併到 Chart.yaml

圖表依賴關係管理系統從 requirements.yaml 和 requirements.lock 移至 Chart.yaml 和 Chart.lock。我們建議適用於 Helm 3 的新圖表使用新格式。但是,Helm 3 仍然了解圖表 API 版本 1 (v1) 並且將載入現有的 requirements.yaml 檔案

在 Helm 2 中,requirements.yaml 的樣子如下:

dependencies:
- name: mariadb
  version: 5.x.x
  repository: https://charts.helm.sh/stable
  condition: mariadb.enabled
  tags:
    - database

在 Helm 3 中,依賴關係的表達方式相同,但現在是在 Chart.yaml 中表達:

dependencies:
- name: mariadb
  version: 5.x.x
  repository: https://charts.helm.sh/stable
  condition: mariadb.enabled
  tags:
    - database

圖表仍然會被下載並放置在 charts/ 目錄中,因此被供應到 charts/ 目錄中的子圖表將繼續運作,無需修改。

安裝時現在需要名稱(或 --generate-name)

在 Helm 2 中,如果沒有提供名稱,則會給予自動產生的名稱。在生產環境中,這被證明是一個麻煩而不是一個有用的功能。在 Helm 3 中,如果在 helm install 中沒有提供名稱,Helm 將會拋出錯誤。

對於仍然希望自動產生名稱的使用者,可以使用 --generate-name 旗標來建立一個名稱。

將圖表推送到 OCI 註冊表

這是 Helm 3 中引入的實驗性功能。要使用此功能,請設定環境變數 HELM_EXPERIMENTAL_OCI=1

在高層次上,圖表儲存庫是一個可以儲存和共享圖表的位置。Helm 客戶端將 Helm 圖表打包並傳送到圖表儲存庫。簡單來說,圖表儲存庫是一個基本的 HTTP 伺服器,它存放一個 index.yaml 檔案和一些打包的圖表。

雖然圖表儲存庫 API 滿足最基本的儲存需求有很多好處,但一些缺點也開始顯現出來

  • 圖表儲存庫很難抽象化生產環境中所需的大部分安全性實作。在生產情境中,擁有用於身份驗證和授權的標準 API 非常重要。
  • Helm 的圖表來源工具用於簽署和驗證圖表的完整性和來源,它是圖表發佈過程中的一個可選部分。
  • 在多租戶情境中,相同的圖表可以由另一個租戶上傳,導致儲存相同內容的儲存成本增加一倍。更聰明的圖表儲存庫已被設計用於處理這個問題,但它不是正式規範的一部分。
  • 使用單個索引檔案進行搜尋、元數據資訊和提取圖表,使得在安全的多租戶實作中設計變得困難或笨拙。

Docker 的 Distribution 專案(也稱為 Docker Registry v2)是 Docker Registry 專案的繼任者。許多主要的雲端供應商都提供 Distribution 專案的產品,而由於有這麼多供應商提供相同的產品,Distribution 專案受益於多年的強化、安全性最佳實務和實戰測試。

請查看 helm help charthelm help registry 以獲取有關如何打包圖表並將其推送到 Docker 註冊表的更多資訊。

如需更多資訊,請參閱此頁面

移除 helm serve

helm serve 在您的機器上運行一個本地圖表儲存庫,用於開發目的。然而,它作為一個開發工具並沒有得到廣泛的採用,並且其設計存在許多問題。最終,我們決定將其移除並將其作為一個插件拆分出來。

若要獲得與 helm serve 類似的體驗,請查看ChartMuseum 中的本地檔案系統儲存選項和servecm 插件

程式庫圖表支援

Helm 3 支援一種稱為「程式庫圖表」的圖表類別。這是一種由其他圖表共享的圖表,但它本身不會建立任何發行成品。程式庫圖表的模板只能聲明 define 元素。全域範圍的非 define 內容將被忽略。這允許使用者重複使用和共享可以在許多圖表中重複使用的程式碼片段,避免冗餘並保持圖表DRY(不要重複自己)。

程式庫圖表在 Chart.yaml 的 dependencies 指令中聲明,並且像任何其他圖表一樣安裝和管理。

dependencies:
  - name: mylib
    version: 1.x.x
    repository: quay.io

我們非常期待看到這個功能為圖表開發者帶來新的用例,以及使用程式庫圖表產生的任何最佳實務。

Chart.yaml apiVersion 提升

隨著程式庫圖表支援的引入以及 requirements.yaml 合併到 Chart.yaml 中,瞭解 Helm 2 套件格式的客戶端將無法理解這些新功能。因此,我們將 Chart.yaml 中的 apiVersion 從 v1 提升到 v2

helm create 現在使用這種新格式建立圖表,因此預設的 apiVersion 也在那裡提升了。

希望支援兩個版本的 Helm 圖表的客戶端應該檢查 Chart.yaml 中的 apiVersion 欄位,以瞭解如何解析套件格式。

XDG 基礎目錄支援

XDG 基礎目錄規範 是一個可移植的標準,定義了配置、數據和快取檔案應儲存在檔案系統中的位置。

在 Helm 2 中,Helm 將所有這些資訊儲存在 ~/.helm 中(昵稱為 helm home),這可以通過設定 $HELM_HOME 環境變數或使用全域旗標 --home 來更改。

在 Helm 3 中,Helm 現在根據 XDG 基礎目錄規範遵循以下環境變數

  • $XDG_CACHE_HOME
  • $XDG_CONFIG_HOME
  • $XDG_DATA_HOME

Helm 插件仍然會傳遞 $HELM_HOME 作為 $XDG_DATA_HOME 的別名,以便與希望使用 $HELM_HOME 作為臨時環境的插件向後相容。

為了適應這種變化,插件的環境中還會傳遞幾個新的環境變數

  • $HELM_PATH_CACHE 表示快取路徑
  • $HELM_PATH_CONFIG 表示配置路徑
  • $HELM_PATH_DATA 表示數據路徑

希望支援 Helm 3 的 Helm 插件應該考慮使用這些新的環境變數。

CLI 命令重新命名

為了更好地與其他套件管理器的用語保持一致,helm delete 已重新命名為 helm uninstallhelm delete 仍然保留作為 helm uninstall 的別名,因此可以兩種形式使用。

在 Helm 2 中,為了清除發行分類帳,必須提供 --purge 旗標。此功能現在預設啟用。要保留先前的行為,請使用 helm uninstall --keep-history

此外,為了遵循相同的慣例,其他幾個命令也已重新命名

  • helm inspect -> helm show
  • helm fetch -> helm pull

這些命令也保留了它們舊的動詞作為別名,因此您可以繼續以任何一種形式使用它們。

自動建立命名空間

在不存在的命名空間中建立發行時,Helm 2 會建立該命名空間。Helm 3 遵循其他 Kubernetes 工具的行為,如果命名空間不存在,則會返回錯誤。如果您明確指定 --create-namespace 旗標,Helm 3 將會建立命名空間。

.Chart.ApiVersion 發生了什麼變化?

Helm 遵循駝峰式大小寫的典型慣例,即將首字母縮寫詞大寫。我們在程式碼的其他地方也這樣做了,例如 .Capabilities.APIVersions.Has。在 Helm v3 中,我們修正了 .Chart.ApiVersion 以遵循這種模式,將其重新命名為 .Chart.APIVersion