TT Lab
はじめる
学ぶ 学習パス コース

Helmチャートの作成とデプロイ

サブチャートを付けフックで順序を作る

TT Labで続きを見る

目標

独立した2つのチャートを、親とサブチャートとして組み立て、値の受け渡し・条件付きの有効化・グローバルな値・フックまで、依存関係管理の4つの軸をすべて手で作ります。

なぜ重要なのか

プラットフォームのチャートを作っていると、必ず「このコンポーネントを同じチャートに入れるか、別に切り出すか」という問いに出会います。依存関係は、その間の答えです。子は単独でもインストールできる独立したチャートとして残り、親はそれを宣言で引き込んで使いながら、値を上書きします。このときの規則は1つだけです。親のvaluesで、サブチャート名と同じキーの下に書いたものが、子の.Valuesの最上位になります。親と子の両方に届く必要がある値だけを、globalの下に置きます。そして、この環境はインターネットがないので、リポジトリは必ずfile://のローカルパスでなければなりません。これは制約ではなく、実務でもよくある構成です。1つのリポジトリに複数のチャートを置いて、互いに参照するときに使う、まさにその方式です。最後に、フックはデプロイの中に順序を作る唯一の手段ですが、フックのリソースはreleaseが所有しないので、削除ポリシーを書かないと、デプロイのたびに積み上がります。

ステップ

  1. /root/helm/deps/cacheに名前がcacheのチャートを、/root/helm/deps/platformに親になるチャートを、それぞれ作成してください。両方のチャートとも、Chart.yaml、values.yaml、templates/を備えている必要があります。/root/helm/deps/cache/values.yamlのreplicaCountは1にします。出力物のディレクトリ/root/helm/deps/outも、あらかじめ作っておいてください。
  2. /root/helm/deps/platform/Chart.yamlのdependenciesの最初の項目に、name: cache、repository: "file://../cache"、versionはcacheチャートのversionと同じ値(例: 0.1.0)、condition: cache.enabledを書いてください。インターネットがないので、リモートのリポジトリURLは動作しません。
  3. helm dependency update /root/helm/deps/platformを実行してください。/root/helm/deps/platform/Chart.lockが作られ、その中の最初の依存関係の名前がcache、digestがsha256:で始まり、/root/helm/deps/platform/charts/の中にcacheのパッケージが置かれている必要があります。
  4. /root/helm/deps/platform/values.yamlにcache.enabled: trueとcache.replicaCount: 3を書き、helm template platform /root/helm/deps/platform > /root/helm/deps/out/rendered.yamlでレンダリングしてください。名前にcacheが入ったDeploymentのspec.replicasが3である必要があります。このとき、/root/helm/deps/cache/values.yamlのreplicaCountは、必ず1のままにしておいてください。親が上書きすることを確認するステップです。
  5. helm template platform /root/helm/deps/platform --set cache.enabled=false > /root/helm/deps/out/disabled.yamlを保存してください。このファイルには、cacheという文字列が1か所もなく、親チャートのオブジェクトはそのまま残っている必要があります(オブジェクトが1つ以上)。親チャート自身のリソース名や内容に、cacheという単語を使わないでください。
  6. /root/helm/deps/platform/values.yamlにglobal.environment: stageを置き、親とサブチャートの両方のテンプレートのmetadata.labelsに、labhub.io/environment: {{ .Values.global.environment }}を付けてください。もう一度レンダリングした/root/helm/deps/out/rendered.yamlに、labhub.io/environment: stageの行が2つ以上あり、名前にcacheが入ったオブジェクトにも、そのラベルがある必要があります。
  7. /root/helm/deps/platform/templates/に、フックのJobを1つ追加してください。名前は{{ .Release.Name }}-db-migrateのように付け(名前にcacheを入れないでください)、アノテーションでhelm.sh/hook: pre-install,pre-upgrade、helm.sh/hook-weight: "-5"、helm.sh/hook-delete-policy: before-hook-creation,hook-succeededを付けます。フックを含むレンダリングを/root/helm/deps/out/hooks.yamlに保存してください(helm templateは、デフォルトでフックも一緒に出力します)。
  8. /root/helm/deps/out/deps-report.jsonを作成してください。キーは4つです。object_countは/root/helm/deps/out/rendered.yamlでkind:で始まる行の数、subchartsは["cache"]、lock_digestは/root/helm/deps/platform/Chart.lockのdigestの値そのまま、hooksはフックのリソース名を入れた配列(1つ以上)です。また、レンダリングされたDeploymentの名前のうち1つには、release名platformが入っている必要があります。

参考

サブチャートと親チャートを準備する

/root/helm/deps/cacheに名前がcacheのチャートを、/root/helm/deps/platformに親になるチャートを、それぞれ作成してください。両方のチャートとも、Chart.yaml、values.yaml、templates/を備えている必要があります。/root/helm/deps/cache/values.yamlのreplicaCountは1にします。出力物のディレクトリ/root/helm/deps/outも、あらかじめ作っておいてください。

独立した2つのチャートが必要です。子のチャートも、それ自体で完結した構造(メタデータ・デフォルト値・テンプレート)を持っていないと、あとでパッケージングされません。

親のChart.yamlに依存関係を宣言する

/root/helm/deps/platform/Chart.yamlのdependenciesの最初の項目に、name: cache、repository: "file://../cache"、versionはcacheチャートのversionと同じ値(例: 0.1.0)、condition: cache.enabledを書いてください。インターネットがないので、リモートのリポジトリURLは動作しません。

この環境はインターネットがありません。リモートのリポジトリURLの代わりに、親チャートを基準にした相対パスを使う方式を探してみてください。オンオフできるようにするフィールドも、一緒に書く必要があります。

依存関係を確定してcharts/を埋める

helm dependency update /root/helm/deps/platformを実行してください。/root/helm/deps/platform/Chart.lockが作られ、その中の最初の依存関係の名前がcache、digestがsha256:で始まり、/root/helm/deps/platform/charts/の中にcacheのパッケージが置かれている必要があります。

依存関係を確定すると、ロックファイルが作られ、charts/にパッケージが置かれます。宣言したバージョンと子のチャートのバージョンが違うと、ここで失敗します。

親からサブチャートの値を上書きする

/root/helm/deps/platform/values.yamlにcache.enabled: trueとcache.replicaCount: 3を書き、helm template platform /root/helm/deps/platform > /root/helm/deps/out/rendered.yamlでレンダリングしてください。名前にcacheが入ったDeploymentのspec.replicasが3である必要があります。このとき、/root/helm/deps/cache/values.yamlのreplicaCountは、必ず1のままにしておいてください。親が上書きすることを確認するステップです。

子のチャートのデフォルト値のファイルには、触れないでください。親のvaluesで、サブチャート名と同じキーの下に値を書くと、それが子の最上位の値になります。

conditionでサブチャートをオフにする

helm template platform /root/helm/deps/platform --set cache.enabled=false > /root/helm/deps/out/disabled.yamlを保存してください。このファイルには、cacheという文字列が1か所もなく、親チャートのオブジェクトはそのまま残っている必要があります(オブジェクトが1つ以上)。親チャート自身のリソース名や内容に、cacheという単語を使わないでください。

条件は子のチャートだけをオフにします。オフにしたのに結果に子の名前が見えるなら、親のテンプレートがそのリソースを直接作っているのです。

globalの値をサブチャートまで渡す

/root/helm/deps/platform/values.yamlにglobal.environment: stageを置き、親とサブチャートの両方のテンプレートのmetadata.labelsに、labhub.io/environment: {{ .Values.global.environment }}を付けてください。もう一度レンダリングした/root/helm/deps/out/rendered.yamlに、labhub.io/environment: stageの行が2つ以上あり、名前にcacheが入ったオブジェクトにも、そのラベルがある必要があります。

親と子の両方に届く必要がある値を置く場所は、別にあります。両方のテンプレートで同じラベルを付けて、実際に渡されているかを、目で確認してください。

インストールのフックを付ける

/root/helm/deps/platform/templates/に、フックのJobを1つ追加してください。名前は{{ .Release.Name }}-db-migrateのように付け(名前にcacheを入れないでください)、アノテーションでhelm.sh/hook: pre-install,pre-upgrade、helm.sh/hook-weight: "-5"、helm.sh/hook-delete-policy: before-hook-creation,hook-succeededを付けます。フックを含むレンダリングを/root/helm/deps/out/hooks.yamlに保存してください(helm templateは、デフォルトでフックも一緒に出力します)。

フックは3つのアノテーションで定義します。いつ動くか、複数あるときに順序がどうなるか、そして終わったあとに誰が片づけるかを、それぞれ書く必要があります。

アンブレラのレンダリングレポートを作る

/root/helm/deps/out/deps-report.jsonを作成してください。キーは4つです。object_countは/root/helm/deps/out/rendered.yamlでkind:で始まる行の数、subchartsは["cache"]、lock_digestは/root/helm/deps/platform/Chart.lockのdigestの値そのまま、hooksはフックのリソース名を入れた配列(1つ以上)です。また、レンダリングされたDeploymentの名前のうち1つには、release名platformが入っている必要があります。

レンダリング結果とロックファイルから、数字を直接抜き出して、JSONにまとめます。オブジェクトの数とダイジェストは、手で書かずに、ファイルから読み取って入れてください。