Helm 的模板和 Kustomize 的叠加层怎么选?各自表达环境差异的方式在哪些地方会出问题?这篇用 Helm 4.3.1 和 kubectl 内置的 Kustomize 5.8.1,把同一个小应用的三个环境渲染出来逐字段比较,再逐项试字段没留口子、类型陷阱、写错字段名和配置变更不滚动这几种情形。
环境 Helm 的资源数 Kustomize 的资源数 逐字段不同的地方 详情 dev 3 3 0 - staging 4 4 0 - prod 4 4 0 - 配置行数:Helm chart(Chart.yaml + values.yaml + 4 个模板)73 行 + 三个环境的 values 文件 11 行 = 84 行;Kustomize base 35 行 + 三个 overlay 48 行 = 83 行。两种写法渲染出的资源逐字段相同(上表),所以差别不在结果,在于怎么表达差异;行数只是这个小例子的数字,不能推广
同一个应用三个环境两种写法渲染出的资源逐字段相同,配置行数 84 对 83,渲染耗时 28 ms 对 32 ms,没有明显差别。
helm template:中位数 28 ms,p90 31 ms kubectl kustomize:中位数 32 ms,p90 34 ms 两者都在几十毫秒量级(进程启动占大头),发布流程里这点时间可以忽略;差别不在速度
都是几十毫秒量级,不是选择依据。
Helm --set terminationGracePeriodSeconds=45:退出码 0,渲染出的 Pod spec 里 terminationGracePeriodSeconds = (没有这个字段) Helm --set-string terminationGracePeriodSeconds=45:退出码 0,渲染出的 Pod spec 里 terminationGracePeriodSeconds = (没有这个字段) Kustomize 加一条 JSON patch:退出码 0,渲染出的 Pod spec 里 terminationGracePeriodSeconds = 45 Helm 的 --set 对模板里没有引用的键没有任何作用,而且不报错;chart 里没做成 value 的字段,使用者只能改模板(fork)或者在渲染结果上再处理。Kustomize 的补丁可以改任意字段,不需要上游预先留口子
Helm 的 --set 对模板里没引用的键静默无效;Kustomize 补丁可以改任意字段。
写法 退出码 渲染出的镜像(或错误) helm --set image.tag=1.10 0 busybox:1.10 helm --set-string image.tag=1.10 0 busybox:1.10 values 文件 tag: 1.10(不加引号) 0 busybox:1.1 values 文件 tag: "1.10" 0 busybox:1.10 Kustomize newTag: 1.10(不加引号) 1 error: invalid Kustomization: json: cannot unmarshal number into Go struct field Image.images.newTag of type string Kustomize newTag: "1.10" 0 busybox:1.10 YAML 文件里没加引号的 1.10 是个浮点数,值 1.1,渲染出的镜像变成 busybox:1.1(Helm 不报错);这次测到 --set image.tag=1.10 得到的是 1.10,和 --set-string 一样,没有被当成浮点数。Kustomize 的 newTag 不加引号直接报类型错误。版本号这类看起来像数字的值,在 values 文件里要加引号
values 文件里没加引号的 1.10 渲染成 1.1;Kustomize 的 newTag 不加引号直接报错。
(a)Helm 无 schema:退出码 0,渲染出的副本数 1(想要 9,拿到的是默认值) (b)Helm 加 schema:退出码 1;- at '': additional properties 'replicaCnt' not allowed (c)Kustomize:退出码 0,输出里带着拼错的字段 replicass: True (c)提交给集群(--dry-run=server --validate=strict):退出码 1;Error from server (BadRequest): error when creating "STDIN": Deployment in version "v1" cannot be handled as a Deployment: strict decoding error: unknown field "spec.replicass" Helm 对 values 里的未知键默认静默忽略,拿到的是默认值;加 values.schema.json 之后会报错。Kustomize 不认识字段的含义,拼错的字段会原样输出,到集群的 schema 校验才会被发现
Helm 默认静默忽略未知键,加 values.schema.json 才会报错;Kustomize 会原样输出拼错的字段,到集群校验才发现。
写法 ReplicaSet 数 Pod 重建了吗 容器里的 LOG_LEVEL (a)Helm,没有 checksum 注解 1 否 info (b)Helm,checksumConfig=true 2 是 debug (c)Kustomize configMapGenerator 2 是 debug ConfigMap 改了,但 Deployment 的 Pod 模板没变就不会触发滚动更新:Pod 里还是旧值。Helm 的惯用法是把 ConfigMap 内容的哈希写进 Pod 模板注解(checksum/config);Kustomize 的 configMapGenerator 给 ConfigMap 名字加内容哈希,Deployment 里的引用被自动改写,模板变了就滚动 说明(哪些是测到的,哪些没有测) 渲染比较是离线的,第六节才用集群;只有一个小应用,三个环境,行数和耗时只代表这个例子;没有测:helm install / upgrade 的发布记录(见下一篇)、Helm hooks、子 chart 与 library chart、Kustomize 的 components 与 vars/replacements、helm 与 kustomize 叠加使用(kustomize --enable-helm、post-renderer)
改 ConfigMap 不会让 Pod 重启;Helm 靠 checksum 注解,Kustomize 靠 configMapGenerator 的哈希后缀。