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 に関する最初の決定事項の 1 つは、Tiller を完全に削除することでした。

Tiller がなくなったことで、Helm のセキュリティモデルが大幅に簡素化されました。Helm 3 は、最新の Kubernetes のすべての最新のセキュリティ、ID、および認証機能をサポートするようになりました。Helm のアクセス許可は、kubeconfig ファイルを使用して評価されます。クラスター管理者は、ユーザーのアクセス許可を必要に応じて細かく制限できます。リリースはクラスター内で引き続き記録され、Helm のその他の機能はそのまま残ります。

改善されたアップグレード戦略:3 方向戦略的マージパッチ

Helm 2 では、双方向の戦略的マージパッチを使用していました。アップグレード中、最新のチャートのマニフェストを、提案されたチャートのマニフェスト(helm upgrade 中に提供されたもの)と比較しました。これらの 2 つのチャート間の違いを比較して、Kubernetes のリソースに適用する必要がある変更を判断しました。変更が(kubectl edit 中など)帯域外でクラスターに適用された場合、それらの変更は考慮されませんでした。これにより、リソースが以前の状態にロールバックできなくなりました。Helm は最後に適用されたチャートのマニフェストのみを現在の状態として考慮していたため、チャートの状態に変更がない場合、ライブ状態は変更されずに残されました。

Helm 3 では、3 方向戦略的マージパッチを使用するようになりました。Helm は、パッチを生成するときに、古いマニフェスト、ライブ状態、および新しいマニフェストを考慮します。

この変更がどのような影響を与えるかについて、いくつかの一般的な例を見ていきましょう。

ライブ状態が変更された場合のロールバック

あなたのチームは、Helm を使用して Kubernetes 上の本番環境にアプリケーションをデプロイしたばかりです。チャートには、レプリカの数が 3 に設定されている Deployment オブジェクトが含まれています。

$ helm install myapp ./myapp

新しい開発者がチームに加わりました。最初の日に本番環境のクラスターを観察している最中、恐ろしいコーヒーをキーボードにこぼす事故が発生し、本番環境のデプロイメントのレプリカを 3 から 0 に kubectl scale しました。

$ kubectl scale --replicas=0 deployment/myapp

チームの別の開発者が、本番サイトがダウンしていることに気づき、リリースを以前の状態にロールバックすることにしました。

$ helm rollback myapp

何が起こるでしょうか?

Helm 2 では、古いマニフェストと新しいマニフェストを比較してパッチが生成されます。これはロールバックであるため、同じマニフェストです。Helm は、古いマニフェストと新しいマニフェストの間に違いがないため、変更するものは何もないと判断します。レプリカ数は 0 のままです。パニックが発生します。

Helm 3 では、古いマニフェスト、ライブ状態、および新しいマニフェストを使用してパッチが生成されます。Helm は、古い状態が 3 であり、ライブ状態が 0 であり、新しいマニフェストがそれを 3 に戻すことを望んでいることを認識するため、状態を 3 に戻すためのパッチを生成します。

ライブ状態が変更された場合のアップグレード

多くのサービスメッシュやその他のコントローラーベースのアプリケーションは、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

サイドカーポッドがライブ状態から削除されます。さらにパニックが発生します。

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 では、特定のリリースに関する情報が、リリース自体と同じ名前空間に保存されるようになりました。これは、ユーザーが 2 つの異なる名前空間で helm install wordpress stable/wordpress を実行でき、現在の名前空間コンテキストを変更することで、それぞれを helm list で参照できることを意味します(例:helm list --namespace foo)。

ネイティブクラスターの名前空間への整合性が高まったため、helm list コマンドはデフォルトですべてのリリースをリストしなくなりました。代わりに、現在の Kubernetes コンテキストの名前空間(つまり、kubectl config view --minify を実行したときに表示される名前空間)にあるリリースのみをリストします。また、Helm 2 と同様の動作を得るには、--all-namespaces フラグを helm list に指定する必要があることも意味します。

デフォルトのストレージドライバとしての Secrets

Helm 3 では、Secrets が デフォルトのストレージドライバとして使用されるようになりました。Helm 2 では、リリース情報を格納するためにデフォルトで ConfigMaps を使用していました。Helm 2.7.0 では、リリース情報を格納するために Secrets を使用する新しいストレージバックエンドが実装され、Helm 3 以降ではこれがデフォルトになりました。

Helm 3 のデフォルトとして Secrets に変更することで、Kubernetes での Secrets 暗号化のリリースと組み合わせて、チャートを保護する際のセキュリティが強化されます。

保存時の Secrets の暗号化は、Kubernetes 1.7 でアルファ機能として利用可能になり、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

詳細については、スキーマファイルのドキュメントを参照してください。

requirements.yamlChart.yaml に統合

チャート依存関係管理システムが requirements.yaml および requirements.lock から Chart.yaml および Chart.lock に移行しました。Helm 3 用の新しいチャートには、新しい形式を使用することをお勧めします。ただし、Helm 3 は引き続き Chart 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 チャートをパックしてチャートリポジトリに送信します。簡単に言えば、チャートリポジトリは index.yaml ファイルといくつかのパッケージ化されたチャートを格納する基本的な HTTP サーバーです。

チャートリポジトリ API が最も基本的なストレージ要件を満たすことにはいくつかの利点がありますが、いくつかの欠点も現れ始めています。

  • チャートリポジトリは、本番環境で必要なほとんどのセキュリティ実装を抽象化するのが非常に困難です。本番環境のシナリオでは、認証と認可のための標準 API を持つことが非常に重要です。
  • チャートの完全性と起源の署名と検証に使用される Helm のチャートプロベナンスツールは、チャート公開プロセスのオプションの要素です。
  • マルチテナントのシナリオでは、同じチャートを別のテナントがアップロードできるため、同じコンテンツを保存するためのストレージコストが 2 倍になります。よりスマートなチャートリポジトリはこれを処理するように設計されていますが、正式な仕様の一部ではありません。
  • 検索、メタデータ情報、チャートのフェッチに単一のインデックスファイルを使用すると、安全なマルチテナント実装で設計することが困難または面倒になっています。

Docker の Distribution プロジェクト (Docker Registry v2 とも呼ばれる) は、Docker Registry プロジェクトの後継です。多くの主要なクラウドベンダーが Distribution プロジェクトの製品を提供しており、多くのベンダーが同じ製品を提供しているため、Distribution プロジェクトは長年にわたる強化、セキュリティのベストプラクティス、および実戦テストの恩恵を受けています。

チャートをパッケージ化して Docker レジストリにプッシュする方法の詳細については、helm help chart および helm help registry を参照してください。

詳細については、このページをご覧ください。

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 Base Directory サポート

XDG Base Directory Specification は、構成、データ、キャッシュファイルをファイルシステムに保存する場所を定義する移植可能な標準です。

Helm 2 では、Helm はこのすべての情報を ~/.helm (親しみを込めて helm home と呼ばれる) に保存し、$HELM_HOME 環境変数を設定するか、グローバルフラグ --home を使用して変更できました。

Helm 3 では、Helm は XDG Base Directory Specification に従って、以下の環境変数を尊重するようになりました。

  • $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 deletehelm uninstall に名前変更されました。helm deletehelm 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 に名前を変更しました。