天天看點

Kubernetes 系列(三十六)了解 Helm upgrade 一些重要參數

作者:回首不堪的流年

Kubernetes 系列(三十六)了解 Helm upgrade 一些重要參數

在運作 helm upgrade 時,您需要時不時地使用 --reset-values 和--reuse-values标志。讓我們深入了解它們的實際工作原理,并看看 chart 的 values 在更新之間發生了變化時的一個問題。

以下是表格中可視化的不同場景:

Kubernetes 系列(三十六)了解 Helm upgrade 一些重要參數

介紹

Helm 的要點在于,您可以自定義 Chart 的參數(在Helm的行話中,參數被稱為 values)。

例如,作為loki-stack Chart 的一部分,你可以通過--set設定一個值來啟用和禁用堆棧的元件:

helm install example-loki grafana/loki-stack --set grafana.enabled=true
           

這同樣适用于更新現有 release 。您可以更改一個值,chart 将根據您的自定義重新配置:

helm upgrade example-loki grafana/loki-stack --set grafana.enabled=false
           

注意到,即使您隻是想使用已經安裝的相同 Chart 更新值,也必須指定 chart 名稱?這是因為upgrade-指令還能夠将釋出版本更新到 Chart 的不同版本(技術上也可以更新到任何其他 Chart,盡管這聽起來不像一個常見的用例)。一個常見的工作流程是從遠端回購更新 Chart,然後将釋出版本更新到最新版本:

helm repo update
helm upgrade ...
           

也可以設定一個特定版本的 chart 來更新:

helm upgrade example-loki grafana/loki-stack --version 1.2.3
           

事實上,你可以重新配置和更新 Chart 是Helm的全部目的。我敢肯定,如果你之前使用過Helm,你對上面所有的東西都很熟悉。

但是配置更改合并在一起的方式可能會讓您猝不及防。upgrade-指令包含一些内部邏輯,可能看起來不一緻。如果要更新的 Chart 的值與最初的Chart 版本相比發生了變化,那麼情況可能會更加混亂。我個人不得不逐個測試不同的變體,以完全了解所有的内容。

第一個潛在的驚喜是合并行為的差異實際上是由這個決定的:您也在更新期間設定值嗎?

如果你是,helm 含蓄地使用了“reset values”政策。

如果你不是,helm 含蓄地使用“reuse values”政策。

這兩種政策都可以通過CLI标志來實作,我們将在下面介紹。

最後,當 Chart 中的值模式發生更改時,還有一個與重用值有關的重要問題需要了解。最後我也會講到這個。

預設行為

讓我們以例子的形式來複習一下。

當你簡單地将 chart 更新到一個新版本時,你之前的值将保持有效:

Kubernetes 系列(三十六)了解 Helm upgrade 一些重要參數

這就是我之前提到的“reuse values”政策。

但是如果您在更新期間也設定了一些值,那麼您以前的值實際上會被删除!

Kubernetes 系列(三十六)了解 Helm upgrade 一些重要參數

這就是我之前提到的“reset values”政策。值将重置為新 chart 版本的預設值,您在CLI上指定的任何新值都将在此基礎上合并。

這是相當令人驚訝的!您需要小心,不要不小心撤銷一些定制。

顯式指定行為

您可以通過CLI标志來控制使用哪種政策。

如果你沒有設定新的值,但想重置為 chart 預設值,你可以通過 --reset-values來實作:

Kubernetes 系列(三十六)了解 Helm upgrade 一些重要參數

在相反的情況下,如果你正在設定新的值,但想要将它們合并到以前的值,你可以使用 --reuse-values:

Kubernetes 系列(三十六)了解 Helm upgrade 一些重要參數

很簡單,對吧?

隻要新 chart 版本中的值模式沒有改變,這就可以工作。是以,大部分情況下,一切正常!但如果模式改變了呢?

使用—reuse-values 以及 模式改變

有時更新後的 chart 的values.yaml值會發生變化。例如,可能添加了一些部分,或者對現有的部分做了一些更改。您希望這些更改合并到您的新版本中,對嗎?

他們就是這樣!但隻有在不使用--reuse-values的情況下。這是令人困惑的,因為它使标志的行為不同于我們的第一個例子,它的工作方式幾乎是--reuse-values,但也合并來自 chart 的更改。

是以,澄清一下。當你進行一個簡單的更新而不設定任何值或标志時,更新的values.yaml從新的Chart 版本被合并到你的版本中,正如預期的那樣:

Kubernetes 系列(三十六)了解 Helm upgrade 一些重要參數

但當你想同時更新之前設定的值時,你自然會使用--reuse-values 以及 --set,對吧?在本例中,--reuse-values有一個意想不到的效果。這導緻Helm從你之前的版本中“reuse values”作為基礎,而忽略了新 chart 版本中可能發生的任何變化:

Kubernetes 系列(三十六)了解 Helm upgrade 一些重要參數

這不是你想的邏輯,對吧?當然,您确實顯式地要求重用值,但是為什麼不希望它們首先與圖表中的(更新的)預設值合并呢?特别是因為這是更新的常見行為。

至少對我來說,這是非常不直覺的,因為我希望包管理器使用 chart 值作為基礎,然後在其上合并我以前的釋出值,最後合并我在更新中提供的任何附加值。

當這種情況發生時,您的更新可能會失敗,因為模闆可能會因過時的值結構而失敗。例如,如果一個新的配置部分被添加到 chart 中,但你的釋出值實際上缺少整個部分,你肯定會遇到一些nil指針錯誤。

為什麼是這樣的?引用GitHub的一位維護者的話:“設計目标是防止新 chart 版本的值的更改被自動應用。”意思是,這是有意的(不是bug),這些标志的行為不會被改變。

這仍然非常令人困惑,因為這些看似相似的指令之間的行為非常不直覺,可能導緻更新中斷。

至于替代方案,GitHub從2020年5月開始有一個活躍的問題,讨論了變通方案和新功能的可能性。一個新的标志,如--reset-then-reuse-values可能是未來添加到 helm 澄清這個問題。

同時,如果你想在 chart 值可能發生變化時獲得預期的--reuse-values行為,你應該先将舊值轉儲到一個檔案中,然後使用它作為沒有--reuse-values的基礎:

helm get values example-loki > prev-values.yaml
helm upgrade example-loki -f prev-values.yaml --set grafana.enabled=true
           

通過這種方式,您以前的值将被合并到更新的 chart 值中,最後來自CLI的任何附加值都将在此基礎上合并。

總結

了解這些标志是如何工作的肯定會幫助您在運作 helm 更新時減少調試時間。我希望這篇文章在說明它們之間的差別方面對您有所幫助。

我試着把這些資訊揉進這個表格:

Kubernetes 系列(三十六)了解 Helm upgrade 一些重要參數

If you ever need to figure out a specific scenario, I recommend creating two local charts via helm create test-chart-1 and helm create test-chart-2 and upgrading between them, e.g. helm install test test-chart-1 --set foo=bar && helm upgrade test test-chart-2 --reset-values && helm get values --all test.

如果你需要想出一個特定的場景,我建議通過helm create test-chart-1和helm create test-chart-2建立兩個本地 chart,并在它們之間更新,例如 helm install test test-chart-1 --set foo=bar && helm upgrade test test-chart-2 --reset-values && helm get values --all test.

我還将這篇文章中的所有資訊圖表收集到一個大的圖像中,是以如果這有助于注意到差異,你可以在它周圍平移和縮放:

Kubernetes 系列(三十六)了解 Helm upgrade 一些重要參數