CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Helm 与 GitOps 入门/课时/Chart 目录结构
RawBlame
课时目录12 节

Helm 与 GitOps 入门

  1. 01为什么需要 Helm
  2. 02安装 Helm 与仓库
  3. 03Chart 目录结构
  4. 04模板与 values
  5. 05install upgrade rollback
  6. 06依赖与子 Chart
  7. 07GitOps 是什么
  8. 08仓库布局与清单
  9. 09Argo CD 入门
  10. 10Flux 概览
  11. 11发布策略
  12. 12综合练习

Chart 目录结构

Chart.yaml、values.yaml、templates/、helpers。

30 分钟

Chart 目录结构

这一课你将能做到

  1. 用 helm create 生成标准骨架,并指认 Chart.yaml、values.yaml、templates/、_helpers.tpl 各自的职责
  2. 把脚手架删减为「Deployment + Service」的最小 backend Chart,说清为何删除 HPA/Ingress 等可选模板是合理取舍
  3. 对照本站裸 YAML 清单,列出应抽进 values 的环境差异字段(至少镜像 tag、副本数、DB 地址、探针路径)

为什么要学

仓库约定是 Helm 的「合同」:Helm 按固定目录找元数据、默认配置与模板,渲染器按固定规则处理下划线开头的文件。目录乱、把密钥写进 values、把环境常量硬编码进模板,后面 helm template、helm lint 和 GitOps 同步都会痛。本课目标是搭出 可 lint、可渲染 的 backend Chart 骨架——下一课才填 Go template 的语法细节。你已会 K8s 资源语义,这里学的是「把它们装进包」的标准形状。

先建立图像

coderoadmap-backend/                 ← Chart 根目录(目录名通常=Chart 名)
├── Chart.yaml                       ← 包身份证:name、version、依赖声明
├── values.yaml                      ← 默认配置(可被 -f / --set 覆盖)
├── charts/                          ← 子 Chart(dependency update 后出现)
├── templates/                       ← 待渲染的 YAML 模板
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── _helpers.tpl                 ← 可复用的命名/标签片段(下划线开头不直接渲染)
│   ├── NOTES.txt                    ← install 成功后打印的使用提示
│   └── NOTES 之外的文件按资源类型命名
└── .helmignore                      ← 打包时忽略的文件(类似 .gitignore)
文件/目录人话什么时候改它
Chart.yaml包名、版本、描述、依赖发版 bump version、加依赖
values.yaml出厂默认旋钮定默认值;环境差异另建 values-*.yaml
templates/*.yaml资源形状增删资源种类(Deployment/Service…)
_helpers.tpl命名与标签函数统一资源名前缀、统一标签
charts/解压后的依赖包不手改,由 dependency 命令管理
.helmignore打包黑名单排除文档、测试脚本等

人话:Chart.yaml 是包装盒上的标签;values.yaml 是出厂预设的旋钮;templates/ 是「按旋钮填空」的说明书;_helpers.tpl 是说明书里反复引用的填空公式。

跟着做

步骤 1:生成骨架

helm create coderoadmap-backend
cd coderoadmap-backend
# Linux/macOS: ls -R 或 tree
# Windows PowerShell: tree /F

你会看到上面图里的标准结构。官方脚手架自带示例 Deployment、Service、Ingress、HPA、ServiceAccount 和测试——对学习用的 backend 来说偏重,下一步裁剪。

步骤 2:读懂并改写 Chart.yaml

# Chart 包元数据(apiVersion: v2 表示 Helm 3 格式)
apiVersion: v2
name: coderoadmap-backend
description: CodeRoadMap Spring Boot backend (MySQL + Redis via config, Nginx at edge)
type: application          # application=可安装应用;library=供依赖复用的库 Chart
version: 0.1.0             # Chart 自身版本(SemVer,每次发布必须递增)
appVersion: "1.0.0"        # 应用版本提示,与镜像 tag 策略对齐
# dependencies: []         # 依赖在 helm-deps 课再引入

笔记写:「version 变了才算发了新包;只改 templates 不 bump version,仓库消费者无从感知变更。」appVersion 习惯加引号——K8s 注解值必须是字符串。

步骤 3:裁剪 templates 到最小集

学习目标:保留并渲染以下文件,其余(Ingress、HPA、ServiceAccount、tests、serviceaccount 相关 helper)删除或移走:

  • templates/deployment.yaml
  • templates/service.yaml
  • templates/_helpers.tpl(保留 fullname/labels 相关 define,删掉用不到的)
  • templates/NOTES.txt(可简化为一行访问提示)
helm template demo . --debug

应输出合法 YAML,只含 Deployment + Service。若报错,通常是删文件时把 helper 引用弄断了——对照报错行修掉。

步骤 4:约定 values.yaml 放什么

# 只放「环境会变」或「安装时可调」的项;默认值应安全、可本地跑
replicaCount: 1

image:
  repository: registry.example/coderoadmap-backend
  tag: "1.0.0"            # 最常见覆盖点
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 8080

# 探针(本站 Spring Boot actuator)
probes:
  readinessPath: /actuator/health/readiness
  livenessPath: /actuator/health/liveness

# 数据库:只写地址与 Secret 名,绝不写密码明文
db:
  host: mysql.coderoadmap-dev.svc
  port: 3306
  passwordSecretName: backend-db-secret
  passwordSecretKey: password

# 空对象 = 模板里条件渲染,dev 不配资源限额也能跑
resources: {}

对照 k8s-practice 的裸清单:凡是「环境差异字段」都应出现在这里成为键。本课先列键,下一课在模板里用 .Values.xxx 消费它们。

步骤 5:确认 _helpers.tpl 的职责

打开 _helpers.tpl,看到形如下面的 define(语法细节下一课讲,本课只认职责):

{{/* 统一全名:Release 名 + Chart 名,全集群唯一且可预测 */}}
{{- define "coderoadmap-backend.fullname" -}}
{{- printf "%s-backend" .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- end -}}

要点:Deployment 的 metadata.name、Service 的 metadata.name、Service 的 selector 都引用同一批 helper——改一处全员生效,且不会拼错。这正是 Service selector 与 Pod 标签必须严格一致的保障。

步骤 6:验收骨架可用性

helm lint .                                   # 语法与最佳实践检查
helm template myrel . > out.yaml              # 渲染产物
# 检查 out.yaml:Deployment 与 Service 名称带 release 前缀、selector 与标签一致
helm package .                                # 打出 coderoadmap-backend-0.1.0.tgz,验证可打包

helm lint 无 Error、helm template 产物可读、helm package 能出包——骨架合格。把「本 Chart 最小文件清单」写进笔记,这就是你后面所有课的工作目录。

讲清楚要点

  1. 因为 Helm 按约定目录工作,所以不要自创「随便一个 yaml 文件夹」当 Chart——缺 Chart.yaml 就不是合法 Chart,helm lint/install 都会拒绝。
  2. 因为默认脚手架偏完整,所以业务 Chart 应按需删减——少一个用不到的 Ingress 模板,就少一处「误开公网入口」的风险面;HPA 同理,先稳再扩。
  3. 因为 values 是覆盖点,所以默认 values 应安全、可在学习集群直接跑——环境差异放 values-*.yaml 覆盖,而不是改模板或改默认 values。
  4. 因为密钥进 Git 会永久泄漏,所以 values 只引用 Secret 名——passwordSecretName 这类键 + 集群侧 Secret/外部注入,是贯穿本 track 的铁律。
  5. 因为资源命名要稳定可预期,所以用 _helpers.tpl 统一 fullname 与 labels——Service selector 与 Pod 标签来自同一 helper,杜绝「选不中 Pod」这类事故。
  6. 因为 charts/ 里的内容是构建产物,所以要约定提交策略——要么提交锁定包(可复现),要么 gitignore + CI 每次 helm dependency update(helm-deps 课详述),团队二选一并写进 README。

你可能会懵的地方

  • type: application 和 library 有什么区别? application 可直接 helm install;library 不产生资源,只通过 define 给其他 Chart 提供 helpers。backend 这种业务 Chart 永远是 application。

  • 为什么有的文件以下划线开头? _helpers.tpl 这类下划线开头的文件不会被单独渲染成集群对象,只作为「片段库」被 include/template 引用。这是 Helm 的约定:下划线 = 不直接输出。

  • .helmignore 有什么用? helm package 时不打进包里的文件列表,类似 .gitignore。文档、本地脚本、IDE 配置放这里,避免包体积与信息泄漏。

  • Ingress 模板要不要保留? 本站架构里入口由集群级 ingress-nginx 统一管理,业务 Chart 只暴露 ClusterIP Service,Ingress 规则由平台层声明——所以业务 Chart 删掉 Ingress 是正确取舍。若你的服务需要独立域名规则,再以 values 开关加回。

  • NOTES.txt 算资源吗? 不算。它不渲染成集群对象,只在 install/upgrade 成功后打印到终端,作用是告诉使用者「接下来怎么访问、密码从哪取」。写好 NOTES 是 Chart 用户体验的加分项。

错法对照

错法问题正解
三环境复制三份 Chart 目录模板分叉,修 bug 要改三处一份 Chart + 多份 values
明文 DB 密码写进 values.yaml密钥随 Git 永久泄漏Secret 名 + 集群侧注入
保留 create 生成的全部模板误开 Ingress、HPA 抢资源删到最小可运行集
手改 charts/ 里解压的内容下次 dependency update 全部冲掉用父 values 覆盖或换上游版本
资源名写死不带 Release 名同命名空间多实例冲突helpers fullname 引用 .Release.Name
忘记 bump version 就发包消费者拉到旧包且无感知发版流程强制递增 version

卡点急救

  1. 现象:helm lint 报 [ERROR] templates/: template not found——某个模板 include/template 引用了不存在的 define 名(常见于删文件后忘改引用);全文搜索报错里的 helper 名,补回 define 或删掉引用。
  2. 现象:helm template 输出里 Service selector 和 Pod 标签对不上——两处没有用同一个 selectorLabels helper;把 Deployment 的 template.metadata.labels 与 Service 的 selector 统一改为引用同一 define。
  3. 现象:helm package 把临时文件也打进了包——把忽略项加进 .helmignore(如 *.md、.idea/、out.yaml),重新打包并 helm template 抽查。

面试常问

  • 一个 Helm Chart 的最小合法结构是什么? 至少包含 Chart.yaml(含 name 与 version)和 templates/ 目录;实践中必有 values.yaml 提供默认配置。apiVersion: v2 表示 Helm 3 格式。额外常见:templates/_helpers.tpl(复用片段)、NOTES.txt(安装提示)、charts/(依赖)、.helmignore。

  • _helpers.tpl 为什么要存在?模板文件不是都可以写在 yaml 里吗? 为了 DRY 与一致性。 fullname、labels、selectorLabels 这类逻辑在多个资源间必须完全一致,集中到 define 后改一处生效全局;下划线前缀保证它们不被当作独立资源渲染。这也是「Service 选不中 Pod」这类经典事故的标准预防手段。

  • Chart 的 version 和 appVersion 分别控制什么? version 是 Chart 包自身的 SemVer,决定仓库里包的版本与升级解析,每次模板/values 变更发布都必须递增;appVersion 是所打包应用的版本提示,供人与工具识别「这个包对应哪代应用」,常与镜像 tag 对齐但不会自动生效。

自测三问

  1. Chart.yaml 的 version 与 appVersion 分别给谁看?何时必须 bump version?
  2. 最小 backend Chart 建议保留哪些模板文件?为什么删除 Ingress 可能是合理取舍?
  3. values 里适合放什么、绝对不该放什么?各举一个本站 backend 的键名例子。

小结一句话

标准 Chart = Chart.yaml + values.yaml + templates(含 helpers);先用 helm create 起步、裁剪出可 lint 可渲染的最小骨架,把环境差异字段列进 values——下一课填模板语法。

延伸

  • Helm — The Chart File Structure
  • Helm — Charts Best Practices
  • 下一课:Go template 语法与 values 覆盖顺序,把 Deployment/Service 真正参数化。
加载本节练习…
← 上一课安装 Helm 与仓库下一课 →模板与 values