valuesはどの順でマージされるのか
一言でいうと
-fは何回でも使え、あとに来たものが勝ちます。--setは、すべての-fに勝ちます。この順序を知らないと、「確かに値を入れたのに反映されない」で1日を燃やします。
なぜ必要なのか
本番のデプロイでは、valuesファイルが、たいてい2–3層になります。チャートのデフォルト値、環境別の値、そしてCIが注入するイメージタグです。どれが勝つのかが混乱すると、ステージングの値が本番に漏れ込みます。
優先度は、低いものから次のとおりです。
- チャートの
values.yaml - 親チャートがサブチャートに渡した値
-f a.yaml(先に来たもの)-f b.yaml(あとに来たもの。aを上書きします)--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:の下に置いた値だけを、すべてのサブチャートが一緒に見ます。この区別を知らないと、「サブチャートが値を読まない」と迷います。