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

Helmのデプロイとロールバック

valuesはどの順でマージされるのか

TT Labで続きを見る

一言でいうと

-fは何回でも使え、あとに来たものが勝ちます。--setは、すべての-fに勝ちます。この順序を知らないと、「確かに値を入れたのに反映されない」で1日を燃やします。

なぜ必要なのか

本番のデプロイでは、valuesファイルが、たいてい2–3層になります。チャートのデフォルト値、環境別の値、そしてCIが注入するイメージタグです。どれが勝つのかが混乱すると、ステージングの値が本番に漏れ込みます。

優先度は、低いものから次のとおりです。

  1. チャートのvalues.yaml
  2. 親チャートがサブチャートに渡した値
  3. -f a.yaml(先に来たもの)
  4. -f b.yaml(あとに来たもの。aを上書きします)
  5. --set / --set-string / --set-file

どう動くのか

マージされた結果を、推測せずに確認します。

helm template demo ./chart -f prod.yaml --set image.tag=abc123 \
  --show-only templates/deployment.yaml

helm get values demo            # 배포된 릴리스에 실제로 들어간 값
helm get values demo --all      # 기본값까지 합친 전체

helm get valuesは、事故の調査で最初に打つコマンドです。「どんな値で起動したか」についての、唯一の事実です。

よくある勘違い

マップはマージされますが、配列はまるごと置き換えられます。-f2つにそれぞれリストがあると、マージされず、あとのものが前のものをまるごと上書きします。そのため、extraEnvのようなリストを環境別に分けておくと、1つだけが残ります。リストをマージしたいなら、マップで設計するのが定石です。

--setのカンマとドットです。--set a.b=1,a.c=2は2つの値です。値の中にカンマがあるなら、\,でエスケープする必要があります。これを見落として、イメージタグが切れる事故がよくあります。値が複雑なら、--set-stringや一時的なvaluesファイルを使うのが安全です。

依存関係はロックしておかないと再現されない

Chart.yamlのdependenciesに書いたバージョンは、範囲です。

dependencies:
  - name: postgresql
    version: "15.x.x"        # 15.5.0 도, 15.9.2 도 이 범위다
    repository: https://charts.bitnami.com/bitnami

helm dependency updateを実行するたびに、異なるバージョンが取得される可能性があります。その結果がChart.lockに書かれ、このファイルをリポジトリにコミットしてはじめて、他の人とCIが同じものを取得します。.gitignoreに入れておくと、「自分のPCでは動くのに」が始まります。

helm dependency build     # Chart.lock 대로 받는다 (재현된다)
helm dependency update    # 범위를 다시 풀어 lock 을 갱신한다 (의도할 때만)

CIではbuildを使います。updateを使うと、デプロイのたびに、異なる依存関係が来る可能性があります。

conditionとtagsでオンオフする

サブチャートを、状況に応じて外す必要があるときがあります。開発ではチャートに付属のPostgreSQLを使い、本番ではマネージドDBを使う、といった具合です。

# Chart.yaml
dependencies:
  - name: postgresql
    version: 15.5.0
    repository: https://charts.bitnami.com/bitnami
    condition: postgresql.enabled     # 이 값이 false 면 통째로 빠진다
# values/prod.yaml
postgresql:
  enabled: false
externalDatabase:
  host: labhub-db-prod-rw.labhub-prod.svc

conditionは値1つを見て、tagsは複数のサブチャートを1つのスイッチにまとめます。条件が偽なら、レンダリング自体が行われないので、そのサブチャートの値が間違っていても、デプロイが通ります。オンにした瞬間に、はじめて発覚します。

値が効かない理由を3段階で探す

# 1) 최종 값이 무엇인가 — 여기서 대개 끝난다
helm template demo ./chart -f prod.yaml --set image.tag=abc | grep -A2 image:

# 2) 값은 맞는데 템플릿이 안 쓰는가
helm template demo ./chart --debug 2>&1 | head -40      # 렌더 전 값이 보인다

# 3) 배포된 릴리스에 실제로 들어간 값
helm get values demo --all

2つ目の段階で、よく出る原因がタイプミスです。imagePullSecretsをimagePullSecretと書いても、Helmは何も言いません。値は、ただ使われないだけです。そのため、チャートにvalues.schema.jsonを置けば、知らないキーをデプロイ前に捕まえられます。

実務で本当に大切なこと

サブチャートの値は、親チャートで、サブチャート名をキーにして指定します。

# 부모 차트의 values.yaml
postgresql:
  auth:
    database: labhub

global:の下に置いた値だけを、すべてのサブチャートが一緒に見ます。この区別を知らないと、「サブチャートが値を読まない」と迷います。