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

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

チャートをパッケージ化してプライベートリポジトリに公開し、取得し直す

TT Labで続きを見る

目標

チャートのディレクトリをtgzにパッケージ化し、インデックスを作って、プライベートなHTTPリポジトリにアップロードし、そのリポジトリからバージョンを選んで取得し、別のチャートの依存関係としてロックする一連の流れを、手で回します。

なぜ重要なのか

チャートが自分のディレクトリを離れた瞬間に残るのは、tgzとindex.yamlの2つだけです。チャートリポジトリは、その2つを配る静的なHTTPサーバー以上のものではなく、そのため、社内リポジトリを立てる作業は、思ったより小さいものです。その代わり、小さいからこそ起きる事故があります。インデックスは自動では更新されないので、新しいバージョンをアップロードするときに--mergeを忘れると、古いバージョンが一覧からまるごと消えます。受け取る側では、versionとappVersionを混同して、「アプリケーションはそのままなのに、なぜバージョンが上がったのか」という質問が繰り返されます。最後に、依存関係は、buildとupdateのどちらを使うかによって、CIが再現可能なビルドをすることも、毎回異なるバージョンを取ってくることもあります。この3つを1回ずつ自分で起こしてみれば、次からは目に見えるようになります。

ステップ

  1. /root/hc-packageでhelm create catalogでチャートを作成し、/root/hc-package/catalog/Chart.yamlのversionを1.0.0、appVersionを"2.4.0"、descriptionを상품 목록 서비스(韓国語の文は「商品一覧サービス」という意味です)に変更してください。この2つのバージョンが別々のものを指しているという事実が、このラボの間ずっと判定の基準です。
  2. /root/hc-package/repoディレクトリに、catalogを2回パッケージ化してください。1回目はチャートのバージョン1.0.0・appVersion 2.4.0、2回目はチャートのバージョン1.1.0・appVersion 2.5.0です。Chart.yamlをもう一度直さず、helm packageのオプションで上書きしてください。結果のファイル名が何で決まるかを確認してください。
  3. helm repo indexで/root/hc-package/repo/index.yamlを作成してください。インデックスにcatalogの項目が2つのバージョンとも入っていて、各バージョンにdigestとurlsがある必要があります。インデックスを開いて、appVersionがバージョンごとに違って書かれていることを確認してください。
  4. /root/hc-package/repoをpython3 -m http.server 8971 --bind 127.0.0.1でサーブしたあと、helm repo add hclocal http://127.0.0.1:8971で登録し、helm repo update hclocalを実行してください。チャートリポジトリが静的なHTTPサーバー以上のものではないということを、ここで確認します。
  5. helm search repo hclocal/catalogを、すべてのバージョンが出るように実行して、結果をJSONで/root/hc-package/out/search.jsonに保存してください。何もオプションを付けずに検索すると、いくつ出るかも、先に見てください。
  6. リポジトリから1.0.0バージョンを選んで、/root/hc-package/pulledの下に展開して取得してください(/root/hc-package/pulled/catalog/Chart.yamlができている必要があります)。続けて、1.1.0バージョンのChart.yamlを/root/hc-package/out/show-1.1.0.txtに、デフォルト値を/root/hc-package/out/show-values.yamlに保存してください。取得して展開しなくても、内容を見られるというのが要点です。
  7. /root/hc-package/stageに、チャートのバージョン1.2.0・appVersion 2.6.0をパッケージ化したあと、既存のインデックスをマージして/root/hc-package/stage/index.yamlを作成してください。マージしたインデックスには、3つのバージョンがすべてある必要があります。そのあと、stageのtgzとindex.yamlを/root/hc-package/repoへ移し、helm repo update hclocalを実行して、3つのバージョンが検索されるかを確認してください。
  8. /root/hc-package/storefrontチャートを作成し、catalog 1.1.0をリポジトリ(http://127.0.0.1:8971)から取得するように宣言して、依存関係を確定してください。そのあと、宣言を1.2.0に上げて、まずhelm dependency buildを実行して、その出力を/root/hc-package/out/dep-build-error.txtに保存してから、適切なコマンドでもう一度確定してください。終わったら、Chart.lockが1.2.0で、/root/hc-package/storefront/charts/catalog-1.2.0.tgzがある必要があります。

参考

パッケージ化するチャートに、先に身分を書く

/root/hc-packageでhelm create catalogでチャートを作成し、/root/hc-package/catalog/Chart.yamlのversionを1.0.0、appVersionを"2.4.0"、descriptionを상품 목록 서비스(韓国語の文は「商品一覧サービス」という意味です)に変更してください。この2つのバージョンが別々のものを指しているという事実が、このラボの間ずっと判定の基準です。

versionはチャート自身のバージョン番号で、appVersionはそのチャートが運ぶソフトウェアのバージョン番号です。2つは別々に動きます。テンプレートだけを直せばversionだけが上がり、アプリケーションだけを上げればappVersionだけが上がります。appVersionは、1.10のような値が数値として解釈されないように、引用符で囲むのが慣例です。

2つのバージョンをパッケージ化してtgzを作る

/root/hc-package/repoディレクトリに、catalogを2回パッケージ化してください。1回目はチャートのバージョン1.0.0・appVersion 2.4.0、2回目はチャートのバージョン1.1.0・appVersion 2.5.0です。Chart.yamlをもう一度直さず、helm packageのオプションで上書きしてください。結果のファイル名が何で決まるかを確認してください。

helm package <차트> --version <v> --app-version <a> -d <디렉터리>(プレースホルダーは順にチャート、バージョン、アプリのバージョン、ディレクトリです)です。tgzの名前は<이름>-<차트버전>.tgz(プレースホルダーは名前とチャートのバージョンです)で決まり、appVersionは名前に現れません。そのため、同じappVersionを含むチャートのバージョンが複数ありえます。パッケージ化したtgzの中をtar -tzfで見てみてください。

リポジトリのインデックスを作る

helm repo indexで/root/hc-package/repo/index.yamlを作成してください。インデックスにcatalogの項目が2つのバージョンとも入っていて、各バージョンにdigestとurlsがある必要があります。インデックスを開いて、appVersionがバージョンごとに違って書かれていることを確認してください。

helm repo index <디렉터리>(プレースホルダーはディレクトリです)は、そのディレクトリのtgzをすべて読んで、index.yamlを新しく書きます。インデックスはリポジトリの一覧にすぎず、実際のチャートはtgzの中にあります。digestはtgzのsha256なので、ファイルが変われば、インデックスも作り直す必要があります。

リポジトリを立ち上げてhelmに登録する

/root/hc-package/repoをpython3 -m http.server 8971 --bind 127.0.0.1でサーブしたあと、helm repo add hclocal http://127.0.0.1:8971で登録し、helm repo update hclocalを実行してください。チャートリポジトリが静的なHTTPサーバー以上のものではないということを、ここで確認します。

サーバーはバックグラウンドで立ち上げます(&)。Helm 3はfile://をリポジトリのプロトコルとして受け付けません。自分でやってみると、could not find protocol handler for: fileが出ます。登録が終わると、$HOME/.config/helm/repositories.yamlにアドレスが書かれ、$HOME/.cache/helm/repository/の下にインデックスのコピーが降りてきます。

すべてのバージョンが見えるように検索する

helm search repo hclocal/catalogを、すべてのバージョンが出るように実行して、結果をJSONで/root/hc-package/out/search.jsonに保存してください。何もオプションを付けずに検索すると、いくつ出るかも、先に見てください。

デフォルトの検索は、リポジトリごとに最も高いバージョン1つだけを見せます。すべてのバージョンを見るには、オプションがもう1つ必要です。出力形式は-o jsonに変えます。JSONの項目のキーは、name・version・app_version・descriptionです。

古いバージョンを選んで取得して展開してみる

リポジトリから1.0.0バージョンを選んで、/root/hc-package/pulledの下に展開して取得してください(/root/hc-package/pulled/catalog/Chart.yamlができている必要があります)。続けて、1.1.0バージョンのChart.yamlを/root/hc-package/out/show-1.1.0.txtに、デフォルト値を/root/hc-package/out/show-values.yamlに保存してください。取得して展開しなくても、内容を見られるというのが要点です。

helm pull <저장소>/<차트> --version <v> --untar -d <디렉터리>(プレースホルダーは順にリポジトリ、チャート、バージョン、ディレクトリです)は、tgzを取得して、その場で展開します。helm show chartとhelm show valuesは、取得せずにリポジトリから直接読んで、標準出力へ出力します。helm show readmeも同じ方式です。

新しいバージョンをアップロードしながら、古いバージョンを消さない

/root/hc-package/stageに、チャートのバージョン1.2.0・appVersion 2.6.0をパッケージ化したあと、既存のインデックスをマージして/root/hc-package/stage/index.yamlを作成してください。マージしたインデックスには、3つのバージョンがすべてある必要があります。そのあと、stageのtgzとindex.yamlを/root/hc-package/repoへ移し、helm repo update hclocalを実行して、3つのバージョンが検索されるかを確認してください。

helm repo indexは、デフォルトではそのディレクトリにあるtgzだけを見て、インデックスを新しく書きます。stageには1.2.0の1つしかないので、そのままアップロードすると、前の2つのバージョンが一覧から消えます。古いインデックスをマージするオプションが別にあります(helm repo index --help)。実務で、これを忘れてデプロイパイプラインが古いバージョンをまるごと消してしまう事故が、よく起きます。

リポジトリから依存関係をロックして、ロックをずらす

/root/hc-package/storefrontチャートを作成し、catalog 1.1.0をリポジトリ(http://127.0.0.1:8971)から取得するように宣言して、依存関係を確定してください。そのあと、宣言を1.2.0に上げて、まずhelm dependency buildを実行して、その出力を/root/hc-package/out/dep-build-error.txtに保存してから、適切なコマンドでもう一度確定してください。終わったら、Chart.lockが1.2.0で、/root/hc-package/storefront/charts/catalog-1.2.0.tgzがある必要があります。

buildはChart.lockをそのまま信じて、そのバージョンを取得します。そのため、CIで使うコマンドです。updateは、Chart.yamlを読み直して範囲を解決し、lockを新しく書きます。宣言を直してからbuildを実行すると、2つがずれているというエラーが出ます。出力をファイルに残すには、2>&1でエラーも一緒に受け取ってください。