为什么需要 Helm
这一课你将能做到
- 用自己的话说清 Chart(包)、Release(安装实例)、Repository(仓库) 三个概念分别对应「模板」「一次部署」「发现渠道」,并能与 docker 镜像、npm 包做类比
- 对照本站手写的 Deployment/Service/ConfigMap 裸 YAML,指出多环境(dev/staging/prod)时的三处失控点:重复、漂移、不可追溯
- 画出「一份 Chart + 多份 values →
helm install → 集群里一组资源」的交付路径,并说明 GitOps(Argo CD/Flux)接在哪一层
为什么要学
本站 backend 是一个 Spring Boot 应用,依赖 MySQL 和 Redis,前面由 Nginx 做入口。在 kubernetes-essentials 里你已经能用裸 YAML 把它部署起来:一个 Deployment、一个 Service、一个 ConfigMap、一组 Secret。单环境没问题,问题出在规模——dev、staging、prod 三套环境几乎相同的清单,镜像 tag、副本数、数据库地址、资源限额散落在十几个文件里。改一个 tag 要同步改三处;有人手改了集群但没人发现;想把「标准 Spring Boot 部署形态」复用到新服务,只能复制整个目录再逐行排查差异。
Helm 是 Kubernetes 生态事实上的包管理器(官方定义 The package manager for Kubernetes)。它把清单做成 Chart:模板 + 默认 values + 版本元数据;一次 helm install 生成一个命名的 Release——集群里多了一组资源,Helm 侧多了一条可追溯、可升级、可回滚的安装记录。本 track 前半学 Helm 打包与发布,后半学 GitOps:把 Chart 和 values 放进 Git,由 Argo CD 或 Flux 在集群内持续同步。前置要求:已会 docker-essentials 的镜像构建、kubernetes-essentials 的资源与探针——本课不回头讲 Pod。
面试视角:说说你对 Helm 的理解、Helm 解决了什么问题 是 DevOps/SRE 岗高频题;答案的核心不是背命令,而是讲清「裸 YAML 在规模化时的失控点」与「Helm 用什么机制收口」。
先建立图像
裸 YAML 世界(容易失控)
deploy-dev/deployment.yaml
deploy-staging/deployment.yaml ← 三份几乎一样,改一处漏两处
deploy-prod/deployment.yaml
Helm 世界
charts/backend/ ← Chart:模板 + 默认 values
values-dev.yaml ← 环境差异(副本、tag、db 地址)
values-prod.yaml
│
▼ helm install backend ./charts/backend -f values-prod.yaml
Release「backend」= 集群里这组已渲染资源的命名实例(带 revision 历史)
| 概念 | 人话 | 类比 |
|---|
| Chart | 可安装的应用包:模板、默认配置、版本元数据 | npm 包 / deb 包 |
| Release | Chart 在某集群某命名空间的一次安装实例 | 装好的软件副本,有名字、有版本历史 |
| Repository | 存放 Chart 的索引与下载地址 | npm registry |
| values | 覆盖默认配置的参数表 | 结构化的环境配置文件 |
kubectl apply -f *.yaml → 你推送「最终 YAML」,集群不记得谁装的第几版
helm install … -f values → Helm 渲染模板再交给 API,并记录 Release revision
GitOps(后半课) → Git 存 Chart/values,Argo/Flux 在集群内做等价 upgrade
人话:Helm 像「带版本号的安装包」;GitOps 像「让集群自己对照说明书装,而不是 CI 拿着钥匙直接进门拧螺丝」。
跟着做
步骤 1:盘点你已有的裸清单
打开你在 k8s-practice 里写过的 backend Deployment/Service/ConfigMap,逐项问一句:「这个字段会随环境变吗?」把结论标进笔记:
- Deployment:
image.tag(dev 是 1.0.0-dev,prod 是 1.0.0)、replicas、资源限额
- Service:端口一般稳定,类型可能 dev 用 NodePort、prod 用 ClusterIP
- ConfigMap:数据库地址、Redis 地址、日志级别
- Secret:数据库密码(生产绝不能明文进 Git)
标不出差异就说明还没分清「结构」与「参数」——结构(资源长什么样)与参数(每环境不同取值)的分离,正是 Chart 与 values 要切开的缝。
步骤 2:对照官方「Chart / Release」定义
- Chart 是一组按约定目录组织的文件,最小合法单位是「Chart.yaml + values.yaml + templates/」
helm install <release-name> <chart> 创建名为 <release-name> 的 Release
- 同一个 Chart 可以装多次——不同 Release 名或不同命名空间,互不干扰
官方文档反复强调的是 package 与 release 这两个词,说明 Helm 定位是「包管理器 + 发布记录」,不是「又一种 YAML 方言」。
步骤 3:用一张表钉死痛点与对策
把下表抄进笔记,右侧补上本站 backend 的具体例子:
| 痛点 | 裸 YAML | Helm |
|---|
| 重复 | 三环境三份 Deployment | 一份模板 + 多份 values |
| 版本 | 镜像 tag 散落各文件 | image.tag 一处覆盖 |
| 追溯 | 难知谁 apply 了哪版 | helm history 按 revision 记录 |
| 回滚 | 手写旧 YAML 再 apply | helm rollback 一条命令 |
| 复用 | 复制目录再手改 | Chart 进仓库 helm pull |
步骤 4:建立与 GitOps 的边界(先立图像,后半课动手)
写 Chart → helm template 验证渲染 →(本机/CI)helm install / upgrade
↘(团队化)Git 存 Chart+values → Argo/Flux 持续 sync
笔记写死一句:「Helm 解决 如何打包与参数化;GitOps 解决 谁、何时、以什么版本把期望状态落到集群。」二者常组合出现,但不在同一层——前者是「打包格式」,后者是「部署操作模型」。
步骤 5:与本站技术栈对号入座
| 组件 | 部署形态建议 |
|---|
| Spring Boot backend | 自研 Chart(Deployment + Service + 探针),本 track 主线 |
| Redis | demo/学习环境用 Bitnami 子 Chart;生产视情况托管 |
| MySQL | 生产常放集群外(托管库/独立实例),Chart 里只引用连接地址 |
| Nginx | 集群级平台组件(ingress-nginx 等),独立 Release,不塞进业务 Chart |
这张表决定了后面六课的例子走向:给 backend 写 Chart,Redis 做子 Chart 演示依赖,MySQL 外接,Nginx 归平台层。
步骤 6:一句话验收
大声说出来:「Chart 是包,Release 是装好的实例,Repository 是发现渠道;我用 values 表达环境差异,而不是复制整份 YAML。」说不顺就回到上面的表格重读一遍。
讲清楚要点
- 因为多环境差异主要是参数而不是结构,所以用 values 覆盖而不是复制目录——Deployment 的字段顺序、探针写法是结构;副本数、tag、DB 地址是参数。结构进 templates,参数进 values,这是 Helm 一切收益的来源。
- 因为
kubectl apply 不记录「这次安装叫什么、第几版」,所以 Helm 引入 Release 与 revision——升级、回滚都以 Release 为单位,helm history 就是部署审计日志。
- 因为团队要共享标准部署形态,所以 Chart 应该能进 Repository 被
search/pull——像共享库一样分发,而不是私有粘贴板。
- 因为 Helm 3 已移除 Tiller,所以权限边界就是你的 kubeconfig/ServiceAccount——装 Chart 的能力等于能改那些 API 资源的能力,RBAC 拒绝时
helm install 与 kubectl apply 一样失败。
- 因为渲染结果仍是普通 K8s 对象,所以先会 Deployment/Service 再学 Helm 才有意义——Helm 不替代你理解探针、滚动更新、Service selector;它只是让这些东西可以参数化和复用。
- 因为生产要把「打包」与「谁有权改集群」拆开,所以后半 track 接 GitOps——CI 只构建镜像;Git 存期望状态;集群内控制器负责同步与纠漂移。
你可能会懵的地方
-
Helm 会不会取代 kubectl?
不会。Helm 最终仍然通过 Kubernetes API 创建/更新对象,排障时你照样 kubectl get/describe/logs。Helm 在其上多提供了模板渲染、values 合并、Release 历史三层能力。
-
Chart 名和 Release 名为什么都要有?
Chart 名是包身份(写在 Chart.yaml 的 name),全局唯一于一个仓库;Release 名是这次安装的实例名(helm install backend … 里的 backend)。同一个 Chart 可以同时装出 backend-dev、backend-prod 两个 Release。
-
已经会 Kustomize 了还需要 Helm 吗?
二者解决「变体管理」的思路不同:Kustomize 擅长「基础 YAML + 补丁」,没有模板语言;Helm 擅长「参数多、条件渲染、可发布到仓库」,社区第三方组件(ingress-nginx、Bitnami 系列)生态以 Chart 为主。两者可以并存,面试时能对比优劣势即可(gitops-repo 课会给可背的对比表)。
-
用 shell 脚本 + envsubst 替换变量不行吗?
能跑,但没有版本化元数据、没有安装记录、没有回滚语义、没有依赖管理。团队规模一大,「谁的脚本是最新的」就变成玄学。Helm 把这些工程化问题标准化了。
-
GitOps 是不是必须先学完 Helm?
不是。GitOps 也可以同步裸 YAML 或 Kustomize;本站路径选 Helm + values,因为与「多环境参数化」这条线天然衔接,且第三方组件大多以 Chart 分发。
错法对照
| 错法 | 问题 | 正解 |
|---|
| 每个环境复制一整份 Deployment YAML | 改漏、漂移、难评审 | 一份 Chart + values-*.yaml |
| 把 Helm 当「不用懂 YAML」的银弹 | 渲染出错无法排障 | 先会读渲染后的 YAML,再写模板 |
| 把 Secret 明文写进 values 提交 Git | 密钥进仓库历史 | values 只引用 Secret 名,密文走封存/外部方案 |
认为 helm install 后就不用管 kubectl | 探针失败、事件看不到 | Release 健康仍靠 K8s 状态与探针 |
| 小改动直接手改集群而不改 values | 与 GitOps/审计冲突 | 改期望状态(values/Chart),再 upgrade/sync |
| 一个超级 Chart 塞进 backend+MySQL+Redis+Nginx 全家桶 | 难维护、平台组件重复安装 | 业务 Chart 浅依赖,平台组件独立 Release |
卡点急救
- 分不清「哪些字段该进 values」:打开现有 YAML,把每个字段问一遍「dev 和 prod 会不一样吗」。会变 → values;不会变 → 留在模板。拿不准的先留模板,之后要参数化随时可以抽出来。
- 三份环境 YAML 已经分叉,不知道哪份是对的:以生产那份为准做基线,用 diff 工具(
diff -u 或 VS Code 对比)列出三份差异,差异项就是你的 values 键清单;收敛过程顺手记录,这份清单就是后面写 Chart 的需求文档。
- 接手了别人的 Chart 看不懂:按固定顺序读——
Chart.yaml(是什么、什么版本、有哪些依赖)→ values.yaml(有哪些旋钮)→ helm template 渲染一遍看最终产物 → 最后才进 templates/ 读逻辑。不要一上来逐行抠模板。
面试常问
-
Helm 是什么?解决了什么问题?
Helm 是 Kubernetes 的包管理器。核心解决三件事:一是把多份 YAML 模板化并用 values 参数化,消除多环境重复清单;二是引入 Release/revision 概念,让每次安装/升级可追溯、可回滚;三是让部署包可以版本化分发(私有仓库/公共仓库),实现「标准部署形态」的团队复用。
-
Chart、Release、Repository 的关系?
Chart 是应用包(模板+默认 values+元数据);Release 是 Chart 在集群中的一次命名安装实例,每次 upgrade 产生新 revision;Repository 是 Chart 的分发渠道(HTTP 或 OCI registry)。类比 npm:Chart≈包,Release≈装到项目里的依赖实例,Repository≈registry。
-
Helm 和 Kustomize 怎么选?
Helm 是模板引擎:适合参数多、需要条件渲染、要发布到仓库供他人安装的场景,社区生态以 Chart 为主;Kustomize 无模板语言,用 base+overlay 补丁叠加,适合「同一份 YAML 少量变体」的场景。两者不互斥,很多团队 Helm 渲染后再用 Kustomize 打补丁,或平台层用 Kustomize、业务层用 Helm。
自测三问
- Chart、Release、Repository 各回答什么问题?
helm install backend ./charts/backend 里哪个是 Release 名?
- 为什么「三环境三份几乎相同的 Deployment」会失控?Helm 用什么机制切开结构与参数?
- Helm 与 GitOps 各解决哪一层问题?画出二者接到同一条交付链上的路径。
小结一句话
Helm 用 Chart 把 K8s 清单模板化、用 Release 记录每次安装;多环境靠 values 覆盖而不是复制 YAML——这为后面的 install/upgrade 实操与 GitOps 持续同步铺平了路。
延伸