LabHub
学习 学习路径 课程

Helm Chart 的制作与发布

挂上子 chart,用钩子造出顺序

在 LabHub 中继续学习

目标

把两个独立 chart 组装为 parent 与 subchart,亲手实现 dependency 管理的四个核心:value 传递、条件启用、global value 与 hook。

为什么重要

构建 platform chart 时,必然会遇到“这个 component 应放在同一个 chart 中,还是单独拆出”的问题。dependency 是二者之间的答案。child 仍是可独立安装的完整 chart,parent 通过声明引用它并覆盖 value。规则只有一条:parent values 中与 subchart 同名的 key 之下所写内容,会成为 child 的 .Values 顶层。只有必须同时传给 parent 和 child 的值才放在 global 下。本环境没有互联网,因此 repository 必须使用 file:// 本地路径。这并非特殊限制,而是实际工作中在同一 repository 放置多个 chart 并相互引用的常见结构。最后,hook 是在部署中建立顺序的唯一手段;但hook resource 不归 release 所有,若不写删除策略,每次部署都会堆积。

步骤

  1. /root/helm/deps/cache 创建名为 cache 的 chart,在 /root/helm/deps/platform 创建 parent chart。两者都必须包含 Chart.yamlvalues.yamltemplates/。将 /root/helm/deps/cache/values.yamlreplicaCount 设为 1,并预先创建产物目录 /root/helm/deps/out
  2. /root/helm/deps/platform/Chart.yamldependencies 第一项写入 name: cacherepository: "file://../cache"、与 cache chart version 相同的 version(例如 0.1.0),以及 condition: cache.enabled。由于没有互联网,远程 repository URL 无法使用。
  3. 执行 helm dependency update /root/helm/deps/platform。必须生成 /root/helm/deps/platform/Chart.lock,其中第一项 dependency 名称为 cachedigestsha256: 开头,且 /root/helm/deps/platform/charts/ 中存在 cache package。
  4. /root/helm/deps/platform/values.yaml 中写入 cache.enabled: truecache.replicaCount: 3,再用 helm template platform /root/helm/deps/platform > /root/helm/deps/out/rendered.yaml render。名称含 cache 的 Deployment,其 spec.replicas 必须为 3。此时 /root/helm/deps/cache/values.yaml 中的 replicaCount 必须仍为 1,本步骤用于确认 parent override。
  5. 保存 helm template platform /root/helm/deps/platform --set cache.enabled=false > /root/helm/deps/out/disabled.yaml。该文件中不能出现任何 cache 字符串,parent chart object 必须仍保留至少 1 个。parent chart 自身的 resource 名称或内容不要使用 cache
  6. /root/helm/deps/platform/values.yaml 中设置 global.environment: stage,并在 parent 与 subchart 两侧 template 的 metadata.labels 中加入 labhub.io/environment: {{ .Values.global.environment }}。重新 render 的 /root/helm/deps/out/rendered.yaml 中必须至少出现两行 labhub.io/environment: stage,名称含 cache 的 object 也必须带该 label。
  7. /root/helm/deps/platform/templates/ 中添加一个 hook Job。名称形如 {{ .Release.Name }}-db-migrate(不要含 cache);annotation 为 helm.sh/hook: pre-install,pre-upgradehelm.sh/hook-weight: "-5"helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded。将包含 hook 的 render 保存到 /root/helm/deps/out/hooks.yamlhelm template 默认也输出 hook)。
  8. 创建 /root/helm/deps/out/deps-report.json,含四个 key。object_count/root/helm/deps/out/rendered.yaml 中以 kind: 开头的行数;subcharts["cache"]lock_digest 原样取自 /root/helm/deps/platform/Chart.lockdigesthooks 是含至少一个 hook resource 名称的数组。此外,render 后至少一个 Deployment 名称必须包含 release name platform

参考

准备 subchart 与 parent chart

/root/helm/deps/cache 创建名为 cache 的 chart,在 /root/helm/deps/platform 创建 parent chart。两者都必须包含 Chart.yamlvalues.yamltemplates/。将 /root/helm/deps/cache/values.yamlreplicaCount 设为 1,并预先创建产物目录 /root/helm/deps/out

需要两个独立 chart。child chart 本身也必须具备完整结构(metadata、默认值、template),之后才能 package。

在 parent Chart.yaml 中声明 dependency

/root/helm/deps/platform/Chart.yamldependencies 第一项写入 name: cacherepository: "file://../cache"、与 cache chart version 相同的 version(例如 0.1.0),以及 condition: cache.enabled。由于没有互联网,远程 repository URL 无法使用。

此环境没有互联网,请使用相对于 parent chart 的路径,而非远程 repository URL;同时写入可控制启停的字段。

锁定 dependency 并填充 charts/

执行 helm dependency update /root/helm/deps/platform。必须生成 /root/helm/deps/platform/Chart.lock,其中第一项 dependency 名称为 cachedigestsha256: 开头,且 /root/helm/deps/platform/charts/ 中存在 cache package。

锁定 dependency 后会生成 lockfile,并把 package 放入 charts/。声明 version 与 child chart version 不同时会在此失败。

从 parent override subchart value

/root/helm/deps/platform/values.yaml 中写入 cache.enabled: truecache.replicaCount: 3,再用 helm template platform /root/helm/deps/platform > /root/helm/deps/out/rendered.yaml render。名称含 cache 的 Deployment,其 spec.replicas 必须为 3。此时 /root/helm/deps/cache/values.yaml 中的 replicaCount 必须仍为 1,本步骤用于确认 parent override。

不要修改 child chart 的默认 values 文件。在 parent values 中与 subchart 同名的 key 下写入 value,该内容就成为 child 的顶层 value。

通过 condition 关闭 subchart

保存 helm template platform /root/helm/deps/platform --set cache.enabled=false > /root/helm/deps/out/disabled.yaml。该文件中不能出现任何 cache 字符串,parent chart object 必须仍保留至少 1 个。parent chart 自身的 resource 名称或内容不要使用 cache

condition 只关闭 child chart。若关闭后结果中仍出现 child 名称,说明 parent template 自己创建了该 resource。

把 global value 传递给 subchart

/root/helm/deps/platform/values.yaml 中设置 global.environment: stage,并在 parent 与 subchart 两侧 template 的 metadata.labels 中加入 labhub.io/environment: {{ .Values.global.environment }}。重新 render 的 /root/helm/deps/out/rendered.yaml 中必须至少出现两行 labhub.io/environment: stage,名称含 cache 的 object 也必须带该 label。

需要同时传到 parent 和 child 的值有专门位置。请在两侧 template 添加同一 label,并查看 render 结果确认确实传递。

添加安装 hook

/root/helm/deps/platform/templates/ 中添加一个 hook Job。名称形如 {{ .Release.Name }}-db-migrate(不要含 cache);annotation 为 helm.sh/hook: pre-install,pre-upgradehelm.sh/hook-weight: "-5"helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded。将包含 hook 的 render 保存到 /root/helm/deps/out/hooks.yamlhelm template 默认也输出 hook)。

hook 通过三个 annotation 定义,分别说明何时执行、多个 hook 的顺序,以及完成后由谁清理。

创建 umbrella render 报告

创建 /root/helm/deps/out/deps-report.json,含四个 key。object_count/root/helm/deps/out/rendered.yaml 中以 kind: 开头的行数;subcharts["cache"]lock_digest 原样取自 /root/helm/deps/platform/Chart.lockdigesthooks 是含至少一个 hook resource 名称的数组。此外,render 后至少一个 Deployment 名称必须包含 release name platform

从 render 结果与 lockfile 直接提取数字并整理为 JSON。object 数与 digest 不要手写,应从文件读取。