チャートをパッケージ化してプライベートリポジトリに公開し、取得し直す
目標
チャートのディレクトリをtgzにパッケージ化し、インデックスを作って、プライベートなHTTPリポジトリにアップロードし、そのリポジトリからバージョンを選んで取得し、別のチャートの依存関係としてロックする一連の流れを、手で回します。
なぜ重要なのか
チャートが自分のディレクトリを離れた瞬間に残るのは、tgzとindex.yamlの2つだけです。チャートリポジトリは、その2つを配る静的なHTTPサーバー以上のものではなく、そのため、社内リポジトリを立てる作業は、思ったより小さいものです。その代わり、小さいからこそ起きる事故があります。インデックスは自動では更新されないので、新しいバージョンをアップロードするときに--mergeを忘れると、古いバージョンが一覧からまるごと消えます。受け取る側では、versionとappVersionを混同して、「アプリケーションはそのままなのに、なぜバージョンが上がったのか」という質問が繰り返されます。最後に、依存関係は、buildとupdateのどちらを使うかによって、CIが再現可能なビルドをすることも、毎回異なるバージョンを取ってくることもあります。この3つを1回ずつ自分で起こしてみれば、次からは目に見えるようになります。
ステップ
/root/hc-packageでhelm create catalogでチャートを作成し、/root/hc-package/catalog/Chart.yamlのversionを1.0.0、appVersionを"2.4.0"、descriptionを상품 목록 서비스(韓国語の文は「商品一覧サービス」という意味です)に変更してください。この2つのバージョンが別々のものを指しているという事実が、このラボの間ずっと判定の基準です。/root/hc-package/repoディレクトリに、catalogを2回パッケージ化してください。1回目はチャートのバージョン1.0.0・appVersion2.4.0、2回目はチャートのバージョン1.1.0・appVersion2.5.0です。Chart.yamlをもう一度直さず、helm packageのオプションで上書きしてください。結果のファイル名が何で決まるかを確認してください。helm repo indexで/root/hc-package/repo/index.yamlを作成してください。インデックスにcatalogの項目が2つのバージョンとも入っていて、各バージョンにdigestとurlsがある必要があります。インデックスを開いて、appVersionがバージョンごとに違って書かれていることを確認してください。/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 search repo hclocal/catalogを、すべてのバージョンが出るように実行して、結果をJSONで/root/hc-package/out/search.jsonに保存してください。何もオプションを付けずに検索すると、いくつ出るかも、先に見てください。- リポジトリから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に保存してください。取得して展開しなくても、内容を見られるというのが要点です。 /root/hc-package/stageに、チャートのバージョン1.2.0・appVersion2.6.0をパッケージ化したあと、既存のインデックスをマージして/root/hc-package/stage/index.yamlを作成してください。マージしたインデックスには、3つのバージョンがすべてある必要があります。そのあと、stageのtgzとindex.yamlを/root/hc-package/repoへ移し、helm repo update hclocalを実行して、3つのバージョンが検索されるかを確認してください。/root/hc-package/storefrontチャートを作成し、catalog1.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がある必要があります。
参考
helm package <차트> --version <v> --app-version <a> -d <디렉터리>(プレースホルダーは順にチャート、バージョン、アプリのバージョン、ディレクトリです)helm repo index <디렉터리> --merge <옛 index.yaml>(プレースホルダーは順にディレクトリと、古いindex.yamlです)helm search repo <저장소>/<차트> --versions -o json(プレースホルダーは順にリポジトリとチャートです)- Helm 3は
file://をリポジトリのプロトコルとして受け付けません。このPodでは、python3 -m http.serverで立ち上げます - よくある間違い: 新しいバージョンをアップロードするとき、インデックスをマージせず、古いバージョンが消えます
- よくある間違い: Chart.yamlの依存関係のバージョンを直したあと、
helm dependency buildを実行して、lockのずれのエラーに遭遇します - 公式ドキュメント: https://helm.sh/docs/topics/chart_repository/ ・ https://helm.sh/docs/helm/helm_repo_index/
パッケージ化するチャートに、先に身分を書く
/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でエラーも一緒に受け取ってください。