讲解

到这一章你已经能体会一个现实问题:部署一个完整应用要写一堆 YAML——Deployment、Service、ConfigMap、Ingress……每个环境还要改副本数、镜像 tag、域名,靠复制粘贴改文件很快就会失控。Helm 是 Kubernetes 的包管理器,定位类似 apt/Homebrew:把一组相关资源打包成一个 chart(包),把环境间会变的部分抽成 values(参数),安装时 helm install 渲染模板并提交给集群。helm list 看已装哪些「发布」(release)、helm upgrade 换版本、helm rollback 回滚、helm uninstall 卸载——它把「一堆 YAML 的一次部署」变成了「一个可版本化管理的软件包」。

chart 的目录结构有固定约定:Chart.yaml 是包的元信息(名字、版本、依赖);values.yaml 是默认参数;templates/ 目录里是带 Go 模板语法的资源清单,{{ .Values.replicaCount }} 这样的占位符在安装时被 values 替换。安装公开软件的典型流程:helm repo add 加仓库 → helm search repo 找包 → helm install 发布名 仓库/包名 -f 自定义values.yaml。自己写的应用也可以打成 chart,CI/CD 里用 --set 或 -f 注入环境差异。

要清楚 Helm 的边界。它的模板系统灵活但调试体验一般(渲染结果和模板隔着一层,helm template 命令可以先看渲染结果再装);它对 CRD 和复杂有状态应用的管理能力有限,数据库/中间件这类更推荐 Operator 模式;release 状态存在集群的 Secret 里,卸载只删它创建的资源,PVC 之类默认保留。本章的命令只做示意(本机未安装 helm),但「包管理 = 模板 + 参数 + 发布生命周期」这个模型在任何包管理器上都通用;底层和集群对话的方式, Helm 与 kubectl 并无二致。

示例

Helm 的典型工作流(本机未安装 helm,命令仅示意——但每一步的语义都值得记住):

# 仅示意:helm 未安装于本机,以下为标准工作流演示
helm repo add bitnami https://charts.bitnami.com/bitnami
helm search repo nginx
helm install my-web bitnami/nginx --set replicaCount=2
helm list
helm upgrade my-web bitnami/nginx --set replicaCount=3
helm rollback my-web 1
helm uninstall my-web

Helm 本质上替你做的事,用 kubectl 手动等价物演示一遍——渲染好的清单不过就是一份普通 YAML,apply 进集群而已(这份会被真实执行):

# wait: deploy/ohmydocs-verify-manual-web
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ohmydocs-verify-manual-web
  labels:
    app: ohmydocs-verify-manual-web
    # Helm 会给它管理的资源打上这类标签,标记归属的 release
    app.kubernetes.io/managed-by: manual-equivalent
spec:
  replicas: 2
  selector:
    matchLabels:
      app: ohmydocs-verify-manual-web
  template:
    metadata:
      labels:
        app: ohmydocs-verify-manual-web
    spec:
      containers:
        - name: nginx
          image: nginx:1.27-alpine
          ports:
            - containerPort: 80
kubectl get deploy ohmydocs-verify-manual-web
kubectl get pods -l app=ohmydocs-verify-manual-web --no-headers | wc -l
echo "Helm 的价值 = 模板参数化 + release 生命周期管理,集群侧看到的资源与手写 YAML 完全一致"

一个 chart 的典型目录结构:

mychart/
├── Chart.yaml          # 包元信息:名称、版本、依赖
├── values.yaml         # 默认参数(安装时可覆盖)
├── charts/             # 依赖的子 chart
└── templates/          # 带 Go 模板语法的资源清单
    ├── deployment.yaml
    ├── service.yaml
    ├── ingress.yaml
    └── _helpers.tpl    # 可复用的模板片段

常见坑

  • 直接改 chart 渲染出的资源:kubectl edit 改的字段下次 helm upgrade 被模板覆盖;要改就改 values,让包管理器保持一致性。
  • values 层级写错:values.yaml 是嵌套结构,--set a.b=c 对应的是 a: {b: c};层级对不上时参数静默失效,用 helm template 先渲染检查。
  • 生产直接装 latest chart:chart 版本和应用版本是两回事,都要锁定;helm install --version 固定 chart 版本。
  • 指望 Helm 管数据库生命周期:升级不迁移数据、卸载默认留 PVC;有状态中间件认真评估 Operator 方案,别把 helm 当运维自动化银弹。

小结

Helm = chart(模板包)+ values(参数)+ release(发布生命周期);list/upgrade/rollback/uninstall 管理已装软件;它只是生成 YAML 的另一种方式,集群里的一切仍然是你前 23 章学过的那些资源。教程到此完结——从 Pod 到生产运维的主干知识已经在你手里,去把自己的第一个应用部署进集群吧。