同一个值怎么写决定了它的类型
目标
用值转储一个个确认 --set 系列选项的语法,并比较把同一个值用 values 文件传入与用 --set 传入时结果有何不同,直到 JSON 类型的层面。
为什么重要
--set 看起来像是着急时用的便利选项,实际上是一门小语言。点向下挖层级,逗号分隔值,花括号构造列表,方括号指定元素,反斜杠暂时关闭这些规则。因不了解类型而出的事故比因不了解语法而出的事故更常见。--set image.tag=8 放入数字 8,而 values 文件里的 tag: "8" 放入字符串。如果 Chart 加了 | quote,两者看起来一样,但在没有加的 Chart 中,清单会悄悄变得不同。用 null 删除值与保留空字符串也不同,把文件正文作为值放入需要专用选项。本实验把这些差别全部做成看得见的,一个个确认。
步骤
- 创建
/root/hc-set/dumperChart(名称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,其值是把整个.Values转成 JSON 并加上引号的内容。渲染之后只取出那段 JSON,保存到/root/hc-set/out/base.json。 - 不要改默认值,只用
--set把image.repository改为registry.local/web,replicas改为5,args改为alpha、beta、gamma三个元素的列表,渲染并把该 JSON 保存到/root/hc-set/out/basics.json。 - 用
--set向nodeSelector放入kubernetes.io/os: linux,向config放入feature.flag: beta,渲染并把 JSON 保存到/root/hc-set/out/escape.json。这两个键名称里都带有点。 - 用三种方式放入同一个标签来渲染,并分别保存——
--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。请确认三个文件中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中创建一个外观像证书的三行文件(-----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。把同样两个值用--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。用diff取出文件版与 set 版的差异,留到/root/hc-set/out/compare.txt(因为有差异,diff 会以非 0 代码结束)。
参考
- Chart 把
.Values转储成 JSON,所以连值的类型也能看到 - 用
jq -r '.image.tag | type'确认是数字还是字符串 --set选项用单引号括起来,避免被 shell 先动手- 常见错误:不转义键里的点,结果生成了嵌套 map
- 常见错误:用
--set传镜像标签而变成了数字——应该用--set-string - 官方文档:https://helm.sh/docs/chart_best_practices/values/ · https://helm.sh/docs/helm/helm_template/
把传入的值原样输出的 Chart
创建 /root/hc-set/dumper Chart(名称 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,其值是把整个 .Values 转成 JSON 并加上引号的内容。渲染之后只取出那段 JSON,保存到 /root/hc-set/out/base.json。
只需一行 {{ .Values | toJson | quote }}。想从渲染结果中只取出那个字符串,用 yq -r '.data."dump.json"'。这样做,就连值的类型也能用眼睛确认——如果用 YAML 转储,是字符串还是数字会被引号规则遮住。
点、逗号、花括号——set 的语法
不要改默认值,只用 --set 把 image.repository 改为 registry.local/web,replicas 改为 5,args 改为 alpha、beta、gamma 三个元素的列表,渲染并把该 JSON 保存到 /root/hc-set/out/basics.json。
点向下挖层级,逗号在一个选项内分隔多个值。要整个给出列表,就用花括号括起来的列表({a,b,c})——为了不让 shell 先展开花括号,请用引号括起来。--set 也可以使用多次。
键里带点的时候
用 --set 向 nodeSelector 放入 kubernetes.io/os: linux,向 config 放入 feature.flag: beta,渲染并把 JSON 保存到 /root/hc-set/out/escape.json。这两个键名称里都带有点。
不做任何处理直接写,点会被读成向下挖层级的符号,在 kubernetes 下生成名为 io/os 的嵌套 map。作为键一部分的点要用反斜杠转义(\.)。shell 也会吃掉反斜杠,所以把整个选项用单引号括起来更安全。
被读成数字的值和没有被读成数字的值
用三种方式放入同一个标签来渲染,并分别保存——--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。请确认三个文件中 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 原样接收值,所以类型也会按意图放入。为了不让 shell 动花括号和引号,请用单引号括起来。
把文件内容作为值放入
在 /root/hc-set/ca.pem 中创建一个外观像证书的三行文件(-----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=)不同——如果 Chart 用 if .Values.image.tag 来分支,两种情况行为相同,但在用 hasKey 查看的地方就会分开。列表元素用 args[0].name=... 这样的方括号来指定位置。
同一个值,用文件传和用 set 传
在 /root/hc-set/override.yaml 中写入 image.tag: "8" 和 replicas: 5,把用该文件渲染的 JSON 保存到 /root/hc-set/out/via-file.json。把同样两个值用 --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。用 diff 取出文件版与 set 版的差异,留到 /root/hc-set/out/compare.txt(因为有差异,diff 会以非 0 代码结束)。
三个文件中有两个完全相同,只有一个不同。 请先预测是哪两个,再确认。用 jq -S . <파일>(占位符为文件)把键顺序排序好,比较起来会容易。diff 会以非 0 代码结束,所以加上 || true,或用忽略退出码的写法。