Helm Chart Scaffolding 实战指南:从 Chart 骨架搭建到多环境交付的完整工作流
【免费下载链接】agentsMulti-harness agentic plugin marketplace for Claude Code, Codex, Cursor, OpenCode, GitHub Copilot, and Google Antigravity项目地址: https://gitcode.com/GitHub_Trending/agents24/agents
本篇技术指南以当前仓库plugins/kubernetes-operations/skills/helm-chart-scaffolding技能包为蓝本,系统讲解 Helm Chart 的设计、组织与管理:从helm create初始化标准目录结构,到 Chart.yaml 元数据、values.yaml 层级化配置、Go 模板渲染、依赖管理、验证测试、打包分发与多环境部署的完整闭环。读完本文,你将能够独立搭建一套可直接投产的 Helm Chart,并用仓库自带的校验脚本与模板资产(assets 与 scripts 目录)落地可复现的交付流水线。
Helm 定位:Kubernetes 应用的包管理器
Helm 是 Kubernetes 生态中的包管理器,它围绕四个核心能力解决了“应用如何标准化交付”的问题:
- 模板化 Kubernetes 清单(Templates):通过 Go 模板把同一份清单渲染成不同环境的资源,实现复用;
- 管理与回滚 Release(Releases):以 Release 为单位跟踪部署历史,支持升级与回滚;
- 处理 Chart 间依赖(Dependencies):通过
dependencies声明子 Chart(如数据库、缓存),统一打包; - 部署版本控制与跨环境配置管理:Chart 版本与 App 版本分离,配合多套 values 文件实现环境差异化。
在本仓库中,这一技能与k8s-manifest-generator(生成基础 Kubernetes 清单)、gitops-workflow(ArgoCD/Flux 自动化部署)互补,构成“生成清单 → 打包成 Chart → GitOps 持续交付”的完整链路,详见 helm-chart-scaffolding/SKILL.md。
十步工作流:从零构建生产级 Helm Chart
1. 初始化 Chart 结构
helm create my-apphelm create会生成符合官方规范的标准骨架:
my-app/ ├── Chart.yaml # Chart 元数据 ├── values.yaml # 默认配置值 ├── charts/ # Chart 依赖 ├── templates/ # Kubernetes 清单模板 │ ├── NOTES.txt # 安装后提示 │ ├── _helpers.tpl # 模板辅助函数 │ ├── deployment.yaml │ ├── service.yaml │ ├── ingress.yaml │ ├── serviceaccount.yaml │ ├── hpa.yaml │ └── tests/ │ └── test-connection.yaml └── .helmignore # 打包忽略文件关于目录的完整约定,仓库中的 references/chart-structure.md 做了更细的补充:
Chart.lock:由helm dependency update自动生成,锁定依赖版本与校验摘要;values.schema.json:JSON Schema 形式的 values 校验(Helm 3 原生支持);crds/:自定义资源定义目录,不参与模板渲染、不会随 Chart 升级或删除;files/:需要注入模板的附加文件(如files/config/app.conf);templates/tests/:测试 Pod 目录,配合helm test使用;- 模板命名约定:小写加连字符(
deployment.yaml)、以_前缀表示局部模板(_helpers.tpl)。
2. 配置 Chart.yaml 元数据
Chart 元数据定义了包的“身份”,是 Helm 校验与发现的依据:
apiVersion: v2 name: my-app description: A Helm chart for My Application type: application version: 1.0.0 # Chart 版本 appVersion: "2.1.0" # 应用版本 # 便于 Chart 检索的关键词 keywords: - web - api - backend # 维护者信息 maintainers: - name: DevOps Team email: devops@example.com url: https://github.com/example/my-app # 源码仓库 sources: - https://github.com/example/my-app # 主页 home: https://example.com # Chart 图标 icon: https://example.com/icon.png # 依赖 dependencies: - name: postgresql version: "12.0.0" repository: "https://charts.bitnami.com/bitnami" condition: postgresql.enabled - name: redis version: "17.0.0" repository: "https://charts.bitnami.com/bitnami" condition: redis.enabled仓库提供了可直接套用的模板 assets/Chart.yaml.template,其中还包含本示例未覆盖的字段:
kubeVersion: ">=1.24.0":声明兼容的 Kubernetes 版本区间;dependencies[].tags:给依赖打标签分组(如database、cache),配合 values 的tags机制统一开关一组依赖;annotations:任意附加注解,如category: Application、licenses: Apache-2.0。
值得注意的版本语义(见 chart-structure.md):
- Chart version(
version)遵循 SemVer:MAJOR 表示破坏性变更、MINOR 新增向后兼容特性、PATCH 修复缺陷; - App version(
appVersion)是所部署应用的版本,可以是任意字符串,不强制 SemVer,通常加引号避免被 YAML 解析为数字。
3. 设计 values.yaml 的层级化结构
values.yaml 是 Chart 的“默认配置面”,建议按资源类型分层组织:
# 镜像配置 image: repository: myapp tag: "1.0.0" pullPolicy: IfNotPresent # 副本数 replicaCount: 3 # Service 配置 service: type: ClusterIP port: 80 targetPort: 8080 # Ingress 配置 ingress: enabled: false className: nginx hosts: - host: app.example.com paths: - path: / pathType: Prefix # 资源配额 resources: requests: memory: "256Mi" cpu: "250m" limits: memory: "512Mi" cpu: "500m" # 自动伸缩 autoscaling: enabled: false minReplicas: 2 maxReplicas: 10 targetCPUUtilizationPercentage: 80 # 环境变量 env: - name: LOG_LEVEL value: "info" # ConfigMap 数据 configMap: data: APP_MODE: production # 依赖子 Chart postgresql: enabled: true auth: database: myapp username: myapp redis: enabled: false仓库中的 assets/values.yaml.template 提供了远超示例的生产级结构,可直接复制扩展,其关键设计点包括:
- global 段:
imageRegistry、imagePullSecrets、storageClass等可被子 Chart 共享的全局值; - image.tag 留空:注释说明默认回退到
.Chart.AppVersion,由模板侧default函数兜底; - 安全上下文:
podSecurityContext(runAsNonRoot: true、runAsUser/Group/fsGroup: 1000、seccompProfile: RuntimeDefault)与容器级securityContext(allowPrivilegeEscalation: false、readOnlyRootFilesystem: true、drop ALL capabilities); - 探针:
livenessProbe/readinessProbe的httpGet.path、initialDelaySeconds、periodSeconds; - 可用性设施:
podDisruptionBudget(minAvailable: 1)、nodeSelector、tolerations、affinity(模板内置 podAntiAffinity 示例); - 可观测性:
serviceMonitor(interval: 30s、scrapeTimeout: 10s); - 网络策略:
networkPolicy的policyTypes: [Ingress, Egress]; - 密钥管理提示:
secrets默认enabled: false,注释明确建议生产环境使用外部密钥管理。
4. 创建模板文件:Go 模板 + Helm 函数
模板文件是 Chart 的灵魂,通过 Go 模板语法与 Helm 内置函数将 values 渲染为清单:
# templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: {{ include "my-app.fullname" . }} labels: {{- include "my-app.labels" . | nindent 4 }} spec: {{- if not .Values.autoscaling.enabled }} replicas: {{ .Values.replicaCount }} {{- end }} selector: matchLabels: {{- include "my-app.selectorLabels" . | nindent 6 }} template: metadata: labels: {{- include "my-app.selectorLabels" . | nindent 8 }} spec: containers: - name: {{ .Chart.Name }} image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: {{ .Values.service.targetPort }} resources: {{- toYaml .Values.resources | nindent 12 }} env: {{- toYaml .Values.env | nindent 12 }}这里用到的关键惯用法:
{{- ... -}}修剪模板两侧空白,保证渲染后 YAML 缩进正确;include+nindent组合:先引入命名模板,再用nindent N统一缩进,这是官方最佳实践中最重要的模式之一;default函数:为tag提供兜底值.Chart.AppVersion;toYaml+nindent:将 values 中结构化的resources、env原样序列化并缩进,避免手写重复结构。
5. 创建模板辅助函数 _helpers.tpl
对于“名称计算”“统一标签”这类反复使用的逻辑,应抽取到templates/_helpers.tpl:
{{/* 展开 Chart 名称 */}} {{- define "my-app.name" -}} {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} {{- end }} {{/* 创建默认的全限定应用名 */}} {{- define "my-app.fullname" -}} {{- if .Values.fullnameOverride }} {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} {{- else }} {{- $name := default .Chart.Name .Values.nameOverride }} {{- if contains $name .Release.Name }} {{- .Release.Name | trunc 63 | trimSuffix "-" }} {{- else }} {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} {{- end }} {{- end }} {{- end }} {{/* 通用标签 */}} {{- define "my-app.labels" -}} helm.sh/chart: {{ include "my-app.chart" . }} {{ include "my-app.selectorLabels" . }} {{- if .Chart.AppVersion }} app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} {{- end }} app.kubernetes.io/managed-by: {{ .Release.Service }} {{- end }} {{/* 选择器标签 */}} {{- define "my-app.selectorLabels" -}} app.kubernetes.io/name: {{ include "my-app.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} {{- end }}这些 helper 的工程价值:
- 名称约束:Kubernetes 资源名最长 63 字符,
trunc 63 | trimSuffix "-"确保超长时截断且不留下尾横线; - 覆盖优先级:
fullnameOverride>nameOverride> Chart 名与 Release 名的组合; - 标签一致性:
labels与selectorLabels分离——selector 只含可变性最低的 name 与 instance,避免 Deployment selector 被非预期标签污染导致滚动更新失败; my-app.chart用{{ .Chart.Name }}-{{ .Chart.Version }}构成,并把+替换为_(SemVer 预发布版本号中的+不合法于标签值)。
chart-structure.md 还给出一个可复用的my-app.imagehelper,统一global.imageRegistry/image.registry与 tag 回退逻辑:
{{- define "my-app.image" -}} {{- $registry := .Values.global.imageRegistry | default .Values.image.registry -}} {{- $repository := .Values.image.repository -}} {{- $tag := .Values.image.tag | default .Chart.AppVersion -}} {{- printf "%s/%s:%s" $registry $repository $tag -}} {{- end -}}6. 管理 Chart 依赖
在 Chart.yaml 中声明依赖:
dependencies: - name: postgresql version: "12.0.0" repository: "https://charts.bitnami.com/bitnami" condition: postgresql.enabled同步并构建依赖:
helm dependency update helm dependency build覆盖依赖的默认值(values.yaml 中与子 Chart 同名的顶层键即为其 values):
# values.yaml postgresql: enabled: true auth: database: myapp username: myapp password: changeme primary: persistence: enabled: true size: 10Gi依赖管理的进阶能力(chart-structure.md):
condition:通过 values 中的布尔值开关单个依赖;tags则按组开关(可组合使用);import-values:将子 Chart 的值导入父 Chart 命名空间,如child: database导入到parent: database;alias:为依赖取别名,以.Values.db引用而非原名;helm dependency list:查看依赖状态;- 锁定版本:
helm dependency update生成的Chart.lock记录精确版本与digest校验和,确保可复现构建;CI 中应提交 Chart.lock 并提示缺失(见下文校验脚本第 10 步的告警逻辑)。
7. 测试与校验:四类命令 + 仓库自带校验脚本
针对 Chart 的完整校验命令集:
# Lint 检查 helm lint my-app/ # 预演安装(不真正部署) helm install my-app ./my-app --dry-run --debug # 仅渲染模板 helm template my-app ./my-app # 带指定 values 渲染 helm template my-app ./my-app -f values-prod.yaml # 查看最终计算值 helm show values ./my-app仓库进一步提供了可直接运行的自动化校验脚本 scripts/validate-chart.sh(bash scripts/validate-chart.sh [chart-dir],默认.),其校验流水线远超“只 lint 一下”的级别:
- 前置检查:确认 Helm 已安装(
command -v helm),Chart.yaml、values.yaml、templates/ 均存在; - helm lint:静态规范检查;
- Chart.yaml 字段解析:用
grep/awk提取 name、version、appVersion 并逐项校验(appVersion 缺失仅告警); - 模板渲染测试:
helm template test-release .失败即退出; - dry-run 安装:
helm install test-release . --dry-run --debug模拟安装; - 资源存在性检查:渲染结果中是否包含
kind: Deployment、Service、ServiceAccount(缺失告警不中断); - 安全基线:
runAsNonRoot: true、readOnlyRootFilesystem: true、allowPrivilegeEscalation: false逐项检查; - 资源配额:
resources:下是否同时定义limits与requests; - 健康探针:
livenessProbe:与readinessProbe:是否配置; - 依赖检查:若声明了
dependencies:,执行helm dependency list并检查 Chart.lock 是否存在(缺失时提示先跑helm dependency update); - values.schema.json:若存在则用
jq empty校验 JSON 合法性。
脚本使用set -e保证任一硬性检查失败即中止,并用彩色对勾/告警输出结果,末尾给出helm package、helm install、helm test的下一步提示。这套脚本本身就是“发布前质量门禁”的最小可落地实现。
如果渲染阶段报错,可配合helm template my-app ./my-app --debug输出模板上下文定位问题(见 SKILL.md 的 Troubleshooting 章节)。
8. 打包与分发
打包 Chart 为 tgz:
helm package my-app/ # 产物:my-app-1.0.0.tgz构建 Chart 仓库索引:
# 生成 index.yaml helm repo index . # 上传到仓库(AWS S3 示例) aws s3 sync . s3://my-helm-charts/ --exclude "*" --include "*.tgz" --include "index.yaml"使用该仓库:
helm repo add my-repo https://charts.example.com helm repo update helm install my-app my-repo/my-app仓库的 index.yaml 形态参考 chart-structure.md:同一 Chart 的多个版本.tgz与index.yaml平铺在同一目录,helm repo index . --url https://charts.example.com可显式指定索引中的 URL 前缀。
9. 多环境配置:环境级 values 文件
按环境拆分 values 文件是 Helm 多环境部署的标准做法:
my-app/ ├── values.yaml # 默认值 ├── values-dev.yaml # 开发环境 ├── values-staging.yaml # 预发环境 └── values-prod.yaml # 生产环境values-prod.yaml 示例:
replicaCount: 5 image: tag: "2.1.0" resources: requests: memory: "512Mi" cpu: "500m" limits: memory: "1Gi" cpu: "1000m" autoscaling: enabled: true minReplicas: 3 maxReplicas: 20 ingress: enabled: true hosts: - host: app.example.com paths: - path: / pathType: Prefix postgresql: enabled: true primary: persistence: size: 100Gi指定环境安装:
helm install my-app ./my-app -f values-prod.yaml --namespace production覆盖优先级(Helm 3 语义):用户显式传入的-fvalues 覆盖 Chart 内 values.yaml 的默认值;--set内联参数优先级最高。多文件可用多个-f叠加,后出现的文件覆盖先出现的文件。
10. 实现 Hooks 与 Tests:安装钩子与连接测试
Helm Hooks 允许在 Release 生命周期的特定时点插入资源。以数据库初始化为例,使用pre-install钩子:
# templates/pre-install-job.yaml apiVersion: batch/v1 kind: Job metadata: name: {{ include "my-app.fullname" . }}-db-setup annotations: "helm.sh/hook": pre-install "helm.sh/hook-weight": "-5" "helm.sh/hook-delete-policy": hook-succeeded spec: template: spec: containers: - name: db-setup image: postgres:15 command: ["psql", "-c", "CREATE DATABASE myapp"] restartPolicy: Never连接测试 Pod:
# templates/tests/test-connection.yaml apiVersion: v1 kind: Pod metadata: name: "{{ include "my-app.fullname" . }}-test-connection" annotations: "helm.sh/hook": test spec: containers: - name: wget image: busybox command: ['wget'] args: ['{{ include "my-app.fullname" . }}:{{ .Values.service.port }}'] restartPolicy: Never运行测试:
helm test my-appHook 机制的关键参数(chart-structure.md):
- Hook 类型:
pre-install、post-install、pre-delete、post-delete、pre-upgrade、post-upgrade、pre-rollback、post-rollback、test;也可用逗号组合如pre-upgrade,pre-install(典型用于数据库迁移任务); - hook-weight:控制同类型 Hook 的执行顺序(取值 -5 到 5,数值小者先执行,默认 0);
- hook-delete-policy:
before-hook-creation(新 Hook 创建前删除旧资源)、hook-succeeded(成功后删除)、hook-failed(失败后删除); - 若测试资源也需要清理,可在
test钩子上追加"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded; - 运行
helm test my-release --logs可查看测试 Pod 日志。
常见模板模式:四个高频写法
模式 1:条件渲染资源
用if包裹整段清单,实现“按 values 开关创建 Ingress / ConfigMap / NetworkPolicy”等可选资源:
{{- if .Values.ingress.enabled }} apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: {{ include "my-app.fullname" . }} spec: # ... {{- end }}注意{{- if开头的横线会吞掉前一行换行,保证最终 YAML 不以空行开头。
模式 2:遍历列表
从 values 中的env列表渲染环境变量:
env: {{- range .Values.env }} - name: {{ .name }} value: {{ .value | quote }} {{- end }}range内.指代当前元素;quote保证字符串值在 YAML 中始终被引号包裹,避免true/123等被 YAML 解析为布尔或数字。
模式 3:注入文件内容
利用 Helm 内置的.Files对象把 Chart 内文件(如应用配置文件)嵌入 ConfigMap:
data: config.yaml: | {{- .Files.Get "config/application.yaml" | nindent 4 }}nindent 4让文件内容整体缩进 4 空格,与data.config.yaml的块标量语法对齐。
模式 4:全局值共享
global段的值会向下传递给所有子 Chart,适合镜像仓库、拉取密钥等全局性配置:
global: imageRegistry: docker.io imagePullSecrets: - name: regcred # 模板中使用: image: {{ .Values.global.imageRegistry }}/{{ .Values.image.repository }}附加验证:values.schema.json 与 .helmignore
除了运行时校验,Helm 3 还支持静态 schema 校验。在 Chart 根目录放置values.schema.json(JSON Schema draft-07),helm install/helm template在渲染前即校验 values:
{ "$schema": "https://json-schema.org/draft-07/schema#", "type": "object", "properties": { "replicaCount": { "type": "integer", "minimum": 1 }, "image": { "type": "object", "required": ["repository"], "properties": { "repository": { "type": "string" }, "tag": { "type": "string" }, "pullPolicy": { "type": "string", "enum": ["Always", "IfNotPresent", "Never"] } } } }, "required": ["image"] }.helmignore则控制打包时排除的文件(开发文件、CI 配置、IDE 目录、临时产物等),示例可参考 chart-structure.md 中的完整清单(.git/、*.md、docs/、.vscode/、*.swp等)。
最佳实践与故障排查
十项最佳实践清单
- Chart 与 App 版本使用语义化版本;
- values.yaml 中所有值都写注释文档化;
- 重复逻辑一律抽取到
_helpers.tpl模板辅助函数; - 打包前必须校验 Chart(lint + template + dry-run);
- 依赖版本显式锁定(配合 Chart.lock);
- 可选资源用
condition/if控制创建; - 命名遵循约定(小写、连字符);
- 包含 NOTES.txt 提供安装后的使用指引(Chart 自带 NOTES.txt 模板支持基于
ingress.enabled分支输出访问 URL 或 port-forward 指引); - 用 helper 统一打标签,保证
app.kubernetes.io/*系列标签一致; - 所有环境都执行安装测试,关键功能配
helm test。
常见故障与排查命令
- 模板渲染错误:
helm template my-app ./my-app --debug(--debug 输出完整模板上下文); - 依赖问题:
helm dependency update、helm dependency list检查依赖状态与 Chart.lock; - 安装失败:
helm install my-app ./my-app --dry-run --debug预演,再kubectl get events --sort-by='.lastTimestamp'查看集群事件定位底层原因。
总结
本文以plugins/kubernetes-operations/skills/helm-chart-scaffolding技能包为骨架,完整覆盖了 Helm Chart 从初始化、元数据配置、values 设计、模板与 helper 编写、依赖管理、自动化校验、打包分发、多环境部署到 Hooks/Tests 的十步工作流,并补充了 schema 校验、.helmignore 与四项高频模板模式。仓库中可深入研读的配套资源包括:SKILL.md(技能总览与排障)、references/chart-structure.md(目录/元数据/依赖/CRD 规范)、assets/Chart.yaml.template 与 assets/values.yaml.template(可直接复用的生产级模板),以及 scripts/validate-chart.sh(发布前自动化质量门禁)。基于这些资产,你可以把“写一个 Chart”升级为“可持续演进的 Chart 工程体系”。
【免费下载链接】agentsMulti-harness agentic plugin marketplace for Claude Code, Codex, Cursor, OpenCode, GitHub Copilot, and Google Antigravity项目地址: https://gitcode.com/GitHub_Trending/agents24/agents
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考