同じ値をどう書くかで型が変わる
目標
--set系のオプションの文法を、値のダンプで1つずつ確認し、同じ値をvaluesファイルで渡すときと--setで渡すときで、結果がどう変わるかを、JSONの型まで比較します。
なぜ重要なのか
--setは、急いでいるときに使う便利なオプションのように見えますが、実際には小さな言語です。ドットは深さを掘り、カンマは値を分け、波括弧はリストを作り、角括弧は要素を指し、バックスラッシュは、そのルールを一時的にオフにします。文法を知らないために起きる事故よりも、型を知らないために起きる事故のほうが、頻繁です。--set image.tag=8は数値の8を入れ、valuesファイルのtag: "8"は文字列を入れます。チャートが| quoteを掛けていれば、2つは同じに見えますが、掛けていないチャートでは、マニフェストが黙って変わります。値をnullで消すことと、空の文字列にしておくことも違い、ファイルの本文を値として入れる作業には、専用のオプションが必要です。このラボは、その違いをすべて目に見えるようにしておいて、1つずつ確認します。
ステップ
/root/hc-set/dumperチャート(名前dumper、バージョン0.1.0)を作成してください。values.yamlは、image(repositoryregistry.local/api、tag"1.10")、replicas: 2、nodeSelector: {}、args: []、config: {}を入れます。templates/dump.yamlは、<릴리스이름>-dump(プレースホルダーはrelease名です)のConfigMapで、dataにdump.jsonキーを1つだけ置き、その値は、.Values全体をJSONに変えて、引用符で囲んだものです。レンダリングしたあと、そのJSONだけを抜き出して、/root/hc-set/out/base.jsonに保存してください。- デフォルト値を直さず、
--setだけで、image.repositoryをregistry.local/webに、replicasを5に、argsをalpha・beta・gammaの3つの要素のリストに変えてレンダリングし、そのJSONを/root/hc-set/out/basics.jsonに保存してください。 --setで、nodeSelectorにkubernetes.io/os: linuxを、configにfeature.flag: betaを入れてレンダリングし、JSONを/root/hc-set/out/escape.jsonに保存してください。2つのキーとも、名前の中にドットが入っています。- 同じタグを3通りで入れてレンダリングし、それぞれ保存してください。
--set image.tag=8は/root/hc-set/out/num-set.json、--set-string image.tag=8は/root/hc-set/out/num-setstring.json、--set image.tag=1.10は/root/hc-set/out/num-float.jsonです。3つのファイルで、image.tagのJSONの型がどう分かれるかを確認してください。 --set-jsonで、configを{"retries": 3, "mode": "strict"}に、argsを["--a", "--b"]にしてレンダリングし、JSONを/root/hc-set/out/setjson.jsonに保存してください。retriesは数値である必要があります。/root/hc-set/ca.pemに、証明書の形をした3行のファイルを作成してください(-----BEGIN CERTIFICATE-----、MIIBkTCB+wIJAKt、-----END CERTIFICATE-----)。このファイルの内容をconfig.caの値として入れてレンダリングし、JSONを/root/hc-set/out/setfile.jsonに保存してください。パスではなく内容が入る必要があります。--setでimage.tagを消して(キーそのものがなくなる必要があります)レンダリングしたJSONを/root/hc-set/out/null.jsonに、argsのインデックス0の要素にname: firstとvalue: 1を入れてレンダリングしたJSONを/root/hc-set/out/index.jsonに保存してください。valueは数値である必要があります。/root/hc-set/override.yamlにimage.tag: "8"とreplicas: 5を書き、そのファイルでレンダリングしたJSONを/root/hc-set/out/via-file.jsonに保存してください。同じ2つの値を--set image.tag=8 --set replicas=5で渡した結果を/root/hc-set/out/via-set.jsonに、--set-string image.tag=8 --set replicas=5で渡した結果を/root/hc-set/out/via-setstring.jsonに保存します。ファイル版とset版の違いをdiffで取って、/root/hc-set/out/compare.txtに残してください(違いがあるので、diffは0以外のコードで終わります)。
参考
- チャートが
.ValuesをJSONとしてダンプするので、値の型まで目に見えます jq -r '.image.tag | type'で、数値か文字列かを確認します--setオプションは、シェルが先に触らないように、シングルクォートで囲みます- よくある間違い: キーの中のドットをエスケープせず、ネストしたマップが作られることです
- よくある間違い: イメージタグを
--setで渡して、数値になることです。--set-stringを使います - 公式ドキュメント: https://helm.sh/docs/chart_best_practices/values/ ・ https://helm.sh/docs/helm/helm_template/
渡された値をそのまま出力するチャート
/root/hc-set/dumperチャート(名前dumper、バージョン0.1.0)を作成してください。values.yamlは、image(repository registry.local/api、tag "1.10")、replicas: 2、nodeSelector: {}、args: []、config: {}を入れます。templates/dump.yamlは、<릴리스이름>-dump(プレースホルダーはrelease名です)のConfigMapで、dataにdump.jsonキーを1つだけ置き、その値は、.Values全体をJSONに変えて、引用符で囲んだものです。レンダリングしたあと、そのJSONだけを抜き出して、/root/hc-set/out/base.jsonに保存してください。
{{ .Values | toJson | quote }}の1行で済みます。レンダリング結果からその文字列だけを取り出すには、yq -r '.data."dump.json"'を使ってください。こうしておくと、値の型まで目で確認できます。YAMLでダンプすると、文字列か数値かが、引用符の規則に隠れてしまいます。
ドット・カンマ・波括弧: setの文法
デフォルト値を直さず、--setだけで、image.repositoryをregistry.local/webに、replicasを5に、argsをalpha・beta・gammaの3つの要素のリストに変えてレンダリングし、そのJSONを/root/hc-set/out/basics.jsonに保存してください。
ドットは深さを掘り、カンマは1つのオプションの中で複数の値を分けます。リストをまるごと渡すには、波括弧で囲んだ一覧({a,b,c})を使います。シェルが波括弧を先に展開しないように、引用符で囲んでください。--setは、何回でも使えます。
キーの中にドットが入っているとき
--setで、nodeSelectorにkubernetes.io/os: linuxを、configにfeature.flag: betaを入れてレンダリングし、JSONを/root/hc-set/out/escape.jsonに保存してください。2つのキーとも、名前の中にドットが入っています。
何も処理せずに書くと、ドットが深さを掘る記号として読まれて、kubernetesの下にio/osというネストしたマップが作られます。キーの一部であるドットは、バックスラッシュでエスケープします(\.)。シェルもバックスラッシュを食べるので、オプション全体をシングルクォートで囲むほうが安全です。
数値として読まれる値と、そうでない値
同じタグを3通りで入れてレンダリングし、それぞれ保存してください。--set image.tag=8は/root/hc-set/out/num-set.json、--set-string image.tag=8は/root/hc-set/out/num-setstring.json、--set image.tag=1.10は/root/hc-set/out/num-float.jsonです。3つのファイルで、image.tagのJSONの型がどう分かれるかを確認してください。
--setは、値が整数として読めれば、数値として入れます。小数点のある値や、0で始まる値は、整数として読まれず、文字列のままです。自分でレンダリングして確認してください。型はjq -r '.image.tag | type'で見られます。イメージタグのように、数値に見える文字列が問題を起こす場所が、まさにここです。
リストとオブジェクトをまるごと入れる
--set-jsonで、configを{"retries": 3, "mode": "strict"}に、argsを["--a", "--b"]にしてレンダリングし、JSONを/root/hc-set/out/setjson.jsonに保存してください。retriesは数値である必要があります。
--setでネストしたオブジェクトを作るには、config.retries=3,config.mode=strictのように、平らに書き下す必要があり、リストの中にオブジェクトが入ると、すぐに読みにくくなります。--set-jsonは値をJSONのまま受け取るので、型も意図したとおりに入ります。シェルが波括弧と引用符に触れないように、シングルクォートで囲んでください。
ファイルの内容を値として入れる
/root/hc-set/ca.pemに、証明書の形をした3行のファイルを作成してください(-----BEGIN CERTIFICATE-----、MIIBkTCB+wIJAKt、-----END CERTIFICATE-----)。このファイルの内容をconfig.caの値として入れてレンダリングし、JSONを/root/hc-set/out/setfile.jsonに保存してください。パスではなく内容が入る必要があります。
--set config.ca=/root/...で渡すと、パスの文字列がそのまま値になります。ファイルを読み込んで入れる専用のオプションが別にあります(helm template --helpで、setで始まるオプションを見てみてください)。証明書や設定ファイルの本文のように、複数行の値を入れるときに使います。
値を消して、リストの要素を指定して直す
--setでimage.tagを消して(キーそのものがなくなる必要があります)レンダリングしたJSONを/root/hc-set/out/null.jsonに、argsのインデックス0の要素にname: firstとvalue: 1を入れてレンダリングしたJSONを/root/hc-set/out/index.jsonに保存してください。valueは数値である必要があります。
--set key=nullは、そのキーを空にするのではなく、なくします。空の文字列(key=)とは違う結果です。チャートがif .Values.image.tagで分岐するなら、2つのケースは同じように動作しますが、hasKeyで見る場所では、分かれます。リストの要素は、args[0].name=...のように、角括弧で位置を指定します。
同じ値をファイルで渡すときと、setで渡すとき
/root/hc-set/override.yamlにimage.tag: "8"とreplicas: 5を書き、そのファイルでレンダリングしたJSONを/root/hc-set/out/via-file.jsonに保存してください。同じ2つの値を--set image.tag=8 --set replicas=5で渡した結果を/root/hc-set/out/via-set.jsonに、--set-string image.tag=8 --set replicas=5で渡した結果を/root/hc-set/out/via-setstring.jsonに保存します。ファイル版とset版の違いをdiffで取って、/root/hc-set/out/compare.txtに残してください(違いがあるので、diffは0以外のコードで終わります)。
3つのファイルのうち、2つはまったく同じで、1つだけが違います。どの2つなのかを、先に予想してから、確認してください。jq -S . <파일>(プレースホルダーはファイルです)でキーの順序をソートしておくと、比較が楽です。diffは0以外のコードで終わるので、|| trueを付けるか、終了コードを無視する形で書いてください。