LabHub
学习 学习路径 课程

Helm Chart 的制作与发布

搭出 chart 骨架并打上标准标签

在 LabHub 中继续学习

目标

亲手创建 Helm chart 的标准结构,在一个位置管理名称与 label,使所有 object 都带上一致的标准 label。

为什么重要

学习 chart 时,人们往往先关心 template 语法,但真正决定 chart 生命周期的是结构。Chart.yaml 负责说明这组内容是什么,values.yaml 负责说明用户能调整什么,templates/ 负责将这些值呈现为什么形态。只有这样分离,才能消除“为每个环境复制文件再修改”的习惯。label 也不是偏好问题。app.kubernetes.io/* 是 Kubernetes 官方推荐标准,管理工具与 dashboard 会据此聚合 resource。尤其要注意:common label 与 selector label 必须分离。Deployment 的 spec.selector 创建后不可更改,而 common label 混有 chart version 与 app version;若直接用于 selector,升级版本时就会被拒绝。

步骤

  1. /root/helm/lab/labhub-web 创建 chart scaffold(可执行 helm create labhub-web,运行目录为 /root/helm/lab)。必须包含 Chart.yamlvalues.yaml.helmignore 三个文件、至少含 3 个文件的 templates/,以及 charts/ 目录。另请预先创建产物目录 /root/helm/lab/out
  2. 填写 /root/helm/lab/labhub-web/Chart.yaml。必须包含 apiVersion: v2name: labhub-webtype: application、SemVer version(如 0.1.0)、appVersion: "1.27",以及一行 description
  3. /root/helm/lab/labhub-web/values.yaml 默认值设为:replicaCount: 2image.repository: nginximage.tag: "1.27"image.pullPolicy: IfNotPresentservice.port: 80。文件中至少要有一行以 # 开头的 comment。
  4. /root/helm/lab/labhub-web/templates/_helpers.tpl 中必须定义 labhub-web.fullnamelabhub-web.labelslabhub-web.selectorLabels,名称生成处必须包含 trunc 63/root/helm/lab/labhub-web/templates/deployment.yaml 必须以 include "labhub-web... 形式调用这些定义。
  5. helm template labhub-web /root/helm/lab/labhub-web > /root/helm/lab/out/rendered.yaml 保存 render 结果。结果至少包含 2 个 object;Deployment 的 metadata.labels 必须包含 app.kubernetes.io/managed-by: Helmapp.kubernetes.io/name: labhub-webapp.kubernetes.io/version,Service 的 metadata.labels 也必须带有同样的 common label。
  6. /root/helm/lab/labhub-web/templates/NOTES.txt 至少各引用一个以 .Release.Name.Values. 开头的值,并将实际 render 后的说明保存到 /root/helm/lab/out/notes.txt。可从 helm install labhub-web /root/helm/lab/labhub-web --dry-run 输出中截取 NOTES: 以下部分(sed -n '/^NOTES:/,$p')。保存文件必须包含 labhub-web,且不能残留未 render 的花括号语法。
  7. 使用 helm lint /root/helm/lab/labhub-web > /root/helm/lab/out/lint.txt 保存 lint 结果。文件必须包含 lint summary 行,且不能出现任何 [ERROR]
  8. helm template labhub-web /root/helm/lab/labhub-web --set replicaCount=5 > /root/helm/lab/out/scaled.yaml 保存 override value 后的 render。最终确认四点:/root/helm/lab/out/rendered.yaml 中 Deployment 的 spec.replicas 为 2;/root/helm/lab/out/scaled.yaml 中为 5;container image 为 nginx:1.27;Service 首个 port 为 80。此外,Service spec.selector 中的 app.kubernetes.io/name 必须与 Deployment Pod template label 的 app.kubernetes.io/name 相同。

参考

创建 chart scaffold

/root/helm/lab/labhub-web 创建 chart scaffold(可执行 helm create labhub-web,运行目录为 /root/helm/lab)。必须包含 Chart.yamlvalues.yaml.helmignore 三个文件、至少含 3 个文件的 templates/,以及 charts/ 目录。另请预先创建产物目录 /root/helm/lab/out

Helm 提供了一条命令可一次生成标准结构。生成后确认 Chart.yaml、values.yaml、.helmignore、templates/、charts/ 五处都存在;charts/ 即使为空也必须存在。

填写 Chart.yaml 身份信息

填写 /root/helm/lab/labhub-web/Chart.yaml。必须包含 apiVersion: v2name: labhub-webtype: application、SemVer version(如 0.1.0)、appVersion: "1.27",以及一行 description

Helm 3 的 apiVersion 是固定的。还要注意 chart 自身 version 与 app version 是不同字段,请思考哪一个应与 image tag 对齐。

设计 values.yaml 默认值

/root/helm/lab/labhub-web/values.yaml 默认值设为:replicaCount: 2image.repository: nginximage.tag: "1.27"image.pullPolicy: IfNotPresentservice.port: 80。文件中至少要有一行以 # 开头的 comment。

相关值不要全部平铺,而要像 image 一样分组。values.yaml 是用户会阅读的唯一文档,因此至少应有一条 comment。

用 helper 提取名称与 label

/root/helm/lab/labhub-web/templates/_helpers.tpl 中必须定义 labhub-web.fullnamelabhub-web.labelslabhub-web.selectorLabels,名称生成处必须包含 trunc 63/root/helm/lab/labhub-web/templates/deployment.yaml 必须以 include "labhub-web... 形式调用这些定义。

以下划线开头的 template 文件不会 render 成 manifest。请思考为何 common label 与 selector label 必须分别定义。名称还需要长度限制处理。

为所有 object 添加标准 label

helm template labhub-web /root/helm/lab/labhub-web > /root/helm/lab/out/rendered.yaml 保存 render 结果。结果至少包含 2 个 object;Deployment 的 metadata.labels 必须包含 app.kubernetes.io/managed-by: Helmapp.kubernetes.io/name: labhub-webapp.kubernetes.io/version,Service 的 metadata.labels 也必须带有同样的 common label。

Deployment 与 Service 都必须带有同样的 common label。managed-by 值不要手写,应从 release 信息取得。评分器会检查已保存的 render 文件。

编写并 render 安装说明

/root/helm/lab/labhub-web/templates/NOTES.txt 至少各引用一个以 .Release.Name.Values. 开头的值,并将实际 render 后的说明保存到 /root/helm/lab/out/notes.txt。可从 helm install labhub-web /root/helm/lab/labhub-web --dry-run 输出中截取 NOTES: 以下部分(sed -n '/^NOTES:/,$p')。保存文件必须包含 labhub-web,且不能残留未 render 的花括号语法。

NOTES.txt 也是 template。应同时使用 release name 与 values 值,让用户知道安装了什么。保存文件必须是 render 结果,不能残留花括号。

通过 chart lint

使用 helm lint /root/helm/lab/labhub-web > /root/helm/lab/out/lint.txt 保存 lint 结果。文件必须包含 lint summary 行,且不能出现任何 [ERROR]

将完整 lint 输出保存到文件。只要有一个 ERROR 就会失败;warning 虽可通过,也应阅读原因。

验证 render 结果

helm template labhub-web /root/helm/lab/labhub-web --set replicaCount=5 > /root/helm/lab/out/scaled.yaml 保存 override value 后的 render。最终确认四点:/root/helm/lab/out/rendered.yaml 中 Deployment 的 spec.replicas 为 2;/root/helm/lab/out/scaled.yaml 中为 5;container image 为 nginx:1.27;Service 首个 port 为 80。此外,Service spec.selector 中的 app.kubernetes.io/name 必须与 Deployment Pod template label 的 app.kubernetes.io/name 相同。

需要默认 render 与 override value 后的 render 两份结果。还要亲自核对 Service selector 与 Pod template label 的 key/value 是否相同;否则流量无法到达 Pod。