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

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

標準ラベルをライブラリチャート一か所にまとめる

TT Labで続きを見る

目標

type: libraryチャートを作って、2つのアプリケーションチャートが同じDeploymentテンプレートとラベルのルールを共有して使うようにし、同じ名前を親が再定義したとき、何が勝つのかを、レンダリングで確認します。

なぜ重要なのか

チャートが増えると、最初に散らばるのが標準ラベルです。同じ会社のチャートなのに、あるものはapp.kubernetes.io/instanceを付け、あるものはreleaseを付けます。監視ダッシュボードとネットワークポリシーがラベルで対象を選ぶので、この不一致は、あとで「なぜこのPodだけメトリクスが取れないのか」として戻ってきます。ライブラリチャートは、このルールを1か所に固定する仕組みです。自分1つでは、インストールもレンダリングもできず、defineだけを収めるので、ひたすら他人に使われるためにだけ存在することが、種類の名前に現れています。ここで一緒に学ぶことが、あと2つあります。tplでvalues内の文字列をテンプレートとしてもう一度回す方法と、テンプレート名がチャート全体で1つの名前空間なので、名前が重なると黙って上書きされるという事実です。

ステップ

  1. /root/hc-library/platform-libに、type: libraryのチャート(名前platform-lib、バージョン0.1.0)を作成してください。/root/hc-library/platform-lib/templates/_helpers.tplに、platform-lib.fullnameとplatform-lib.labelsの2つをdefineで定義します。labelsは、app.kubernetes.io/name、app.kubernetes.io/instance、app.kubernetes.io/managed-by、platform.labhub.io/tierの4行を出力します。templatesの下には、アンダースコアで始まるファイルだけを置いてください。
  2. helm install liblab /root/hc-library/platform-lib --dry-runとhelm template liblab /root/hc-library/platform-libを順に実行して、2つの出力(エラーを含む)を、すべて/root/hc-library/out/library-error.txtに入れてください。Helmがどんな言葉で拒否するかが、このステップの答えです。
  3. /root/hc-library/platform-lib/templates/_deployment.tplに、platform-lib.deploymentを定義してください。このテンプレートはDeploymentを出力し、名前はplatform-lib.fullname、metadata.labelsはplatform-lib.labelsをnindent 4で差し込んで作ります。spec.replicasは.Values.replicas(デフォルトは1)、コンテナ名は.Chart.Name、イメージは.Values.imageを引用符で囲んで使います。selectorとPodのラベルは、name・instanceの2行だけを使います。
  4. /root/hc-library/billingアプリケーションチャート(バージョン0.1.0、appVersion "1.4.2")を作成し、platform-lib 0.1.0をfile://../platform-libリポジトリで依存関係として宣言してから、確定してください。values.yamlは、replicas: 1、image: "registry.local/billing:1.4.2"、tier: core、そしてnote: "{{ .Release.Name }} in {{ .Release.Namespace }}"の4つの値を入れ、templates/deployment.yamlは、platform-lib.deploymentをincludeする1行だけを置きます。helm template shop /root/hc-library/billingの結果を/root/hc-library/out/billing.yamlに保存してください。
  5. /root/hc-library/reportingチャート(バージョン0.1.0、appVersion "0.9.0")を、同じ方法で作成しますが、replicas: 3、image: "registry.local/reporting:0.9.0"、tier: batch、note: "{{ .Chart.Name }} {{ .Chart.Version }}"にして、依存関係を確定してください。helm template insight /root/hc-library/reportingの結果を/root/hc-library/out/reporting.yamlに保存します。2つのレンダリング結果のラベルのキーの一覧が同じで、値だけが違うかを確認してください。
  6. ライブラリにplatform-lib.configmapを追加してください(/root/hc-library/platform-lib/templates/_configmap.tpl)。名前は<fullname>-note、data.noteは.Values.noteをtplでもう一度レンダリングして、引用符で囲みます。2つのチャートにtemplates/configmap.yaml(includeの1行)を追加してください。noteの値は、ステップ4・5ですでにvalues.yamlに入れてあります。波括弧が入ったまま、そのままにしてください。ライブラリを直したので、2つのチャートで依存関係を取得し直す必要があります。2つのレンダリングファイルを、もう一度保存してください。
  7. /root/hc-library/billing/templates/_override.tplに、同じ名前のplatform-lib.deploymentを再定義してください。内容はライブラリのものと同じですが、metadata.annotationsにplatform.labhub.io/overridden-by: billingを1行加えます。2つのチャートをもう一度レンダリングして保存し、billingにだけそのアノテーションが付くかを確認してください。
  8. /root/hc-library/out/report.jsonに、このラボの結果をまとめてください。キーは、library(ライブラリチャートの名前)、type(チャートの種類)、installable(ブール値)、consumers(利用側チャートの名前の配列)、billing_replicas、reporting_replicas(各レンダリングの実際のreplicasの数値)、shared_label_keys(ライブラリのヘルパーが作るラベルのキーの数)、override_winner(同じ名前を再定義して勝ったチャートの名前)の8つです。

参考

何もレンダリングしないチャートを作る

/root/hc-library/platform-libに、type: libraryのチャート(名前platform-lib、バージョン0.1.0)を作成してください。/root/hc-library/platform-lib/templates/_helpers.tplに、platform-lib.fullnameとplatform-lib.labelsの2つをdefineで定義します。labelsは、app.kubernetes.io/name、app.kubernetes.io/instance、app.kubernetes.io/managed-by、platform.labhub.io/tierの4行を出力します。templatesの下には、アンダースコアで始まるファイルだけを置いてください。

ライブラリチャートには、レンダリングされるテンプレートがありません。Helmは_で始まるファイルを「出力しない断片」として扱うので、すべての内容が_*.tplの中のdefineブロックに入ります。tierは値がないこともあるので、defaultを掛けて、quoteで囲んでください。

ライブラリチャートをインストールしてみる

helm install liblab /root/hc-library/platform-lib --dry-runとhelm template liblab /root/hc-library/platform-libを順に実行して、2つの出力(エラーを含む)を、すべて/root/hc-library/out/library-error.txtに入れてください。Helmがどんな言葉で拒否するかが、このステップの答えです。

2つのコマンドとも失敗します。エラーは標準エラー出力に出るので、2>&1で一緒に受け取らないと、ファイルに入りません。2つ目のコマンドは、最初の出力を消さないように、追記(>>)で書いてください。インストールが止められる理由を、考えてみてください。このチャートには、レンダリングされるものが1つもありません。

Deployment一式をまるごとライブラリに入れる

/root/hc-library/platform-lib/templates/_deployment.tplに、platform-lib.deploymentを定義してください。このテンプレートはDeploymentを出力し、名前はplatform-lib.fullname、metadata.labelsはplatform-lib.labelsをnindent 4で差し込んで作ります。spec.replicasは.Values.replicas(デフォルトは1)、コンテナ名は.Chart.Name、イメージは.Values.imageを引用符で囲んで使います。selectorとPodのラベルは、name・instanceの2行だけを使います。

includeは、別のdefineの結果を文字列として受け取ってくるので、パイプでインデントを掛けられます。nindent 4は、改行を先に入れて、4スペース分インデントします。labels:のすぐ下の行で使うのに向いています。採点ツールは、この定義を一時的なチャートに入れて、直接レンダリングしてみます。

アプリケーションチャートがライブラリを依存関係として掛ける

/root/hc-library/billingアプリケーションチャート(バージョン0.1.0、appVersion "1.4.2")を作成し、platform-lib 0.1.0をfile://../platform-libリポジトリで依存関係として宣言してから、確定してください。values.yamlは、replicas: 1、image: "registry.local/billing:1.4.2"、tier: core、そしてnote: "{{ .Release.Name }} in {{ .Release.Namespace }}"の4つの値を入れ、templates/deployment.yamlは、platform-lib.deploymentをincludeする1行だけを置きます。helm template shop /root/hc-library/billingの結果を/root/hc-library/out/billing.yamlに保存してください。

ライブラリはインストールできませんが、依存関係としては掛けられます。file://は、リポジトリの登録にはできませんが、依存関係のrepositoryとしては動作します。確定すると、Chart.lockとcharts/platform-lib-0.1.0.tgzができます。release名をshopにすると、オブジェクト名がshop-billingになります。

2つ目のチャートが、同じテンプレートを別の値で使う

/root/hc-library/reportingチャート(バージョン0.1.0、appVersion "0.9.0")を、同じ方法で作成しますが、replicas: 3、image: "registry.local/reporting:0.9.0"、tier: batch、note: "{{ .Chart.Name }} {{ .Chart.Version }}"にして、依存関係を確定してください。helm template insight /root/hc-library/reportingの結果を/root/hc-library/out/reporting.yamlに保存します。2つのレンダリング結果のラベルのキーの一覧が同じで、値だけが違うかを確認してください。

ライブラリが価値を発揮する点が、まさにここです。ラベルを付けるルールは1か所にだけあり、チャートごとに違うのは、valuesだけです。ラベルのキーだけを抜き出して比べるには、yq '.metadata.labels | keys'を2つのファイルに対して実行してみてください。

valuesに入ったテンプレート文字列を、もう一度レンダリングする

ライブラリにplatform-lib.configmapを追加してください(/root/hc-library/platform-lib/templates/_configmap.tpl)。名前は<fullname>-note、data.noteは.Values.noteをtplでもう一度レンダリングして、引用符で囲みます。2つのチャートにtemplates/configmap.yaml(includeの1行)を追加してください。noteの値は、ステップ4・5ですでにvalues.yamlに入れてあります。波括弧が入ったまま、そのままにしてください。ライブラリを直したので、2つのチャートで依存関係を取得し直す必要があります。2つのレンダリングファイルを、もう一度保存してください。

tpl <문자열> <컨텍스트>(プレースホルダーは順に文字列とコンテキストです)は、文字列をその場でテンプレートとして解釈します。valuesに書かれた波括弧は、ただの文字なので、この関数を通さないと、そのまま出力されます。helm dependency updateは、その時点のライブラリをtgzとして取り出して、charts/に入れます。ライブラリを直したあと、取得し直さないと、古いコピーが使われ続けます。

親が同じ名前を再定義すると、何が勝つのか

/root/hc-library/billing/templates/_override.tplに、同じ名前のplatform-lib.deploymentを再定義してください。内容はライブラリのものと同じですが、metadata.annotationsにplatform.labhub.io/overridden-by: billingを1行加えます。2つのチャートをもう一度レンダリングして保存し、billingにだけそのアノテーションが付くかを確認してください。

Helmのテンプレート名は、チャート全体で1つのテンプレート名の名前空間を使います。同じ名前が2つあれば、あとに読まれたものが勝ち、親チャートのテンプレートが、サブチャートよりあとに読まれます。そのため、名前の前にチャート名を付ける慣例ができました。偶然の衝突を防ぐためです。

ライブラリが何を消したかを数字で書く

/root/hc-library/out/report.jsonに、このラボの結果をまとめてください。キーは、library(ライブラリチャートの名前)、type(チャートの種類)、installable(ブール値)、consumers(利用側チャートの名前の配列)、billing_replicas、reporting_replicas(各レンダリングの実際のreplicasの数値)、shared_label_keys(ライブラリのヘルパーが作るラベルのキーの数)、override_winner(同じ名前を再定義して勝ったチャートの名前)の8つです。

数字は作り上げずに、レンダリング結果から読み取ってください。yq '. | select(.kind=="Deployment") | .spec.replicas' out/billing.yamlのように抜き出せます。installableは、引用符のないブール値である必要があります。