Skip to content

Helm 从入门到实战:从一条 upgrade 命令说起

Helm 从入门到实战:从一条 upgrade 命令说起示意图

引子:一条命令背后的故事

想象这样一个场景:您正在维护一个 Kubernetes 集群,需要将 Web 服务 Nginx 升级到新版本。您执行了下面这条命令:

bash
helm upgrade my-nginx ./nginx-chart --set image.tag=1.25.3 -n web

这条命令简洁而有力,但它背后究竟发生了什么?my-nginx 是什么?./nginx-chart 这个路径指向何方?-n web 又代表什么?

本文将以此为起点,带您深入 Helm 的世界,从基础概念到高级技巧,助您成为 Kubernetes 上的包管理专家。

第一部分:初识 Helm —— K8s 的"应用商店"

什么是 Helm?

Helm 是 Kubernetes 的包管理器。它的作用类似于 Ubuntu 的 apt 或 Golang 的 module,用于简化 Kubernetes 应用的部署、升级和回滚。

在 Kubernetes 中,部署一个复杂的应用通常需要编写多个 YAML 文件(Deployment, Service, ConfigMap, Ingress...)。Helm 通过将一组 YAML 文件打包成一个 Chart,实现了应用的标准化分发。

Helm 的核心概念

要理解那条命令,您必须先掌握以下三个核心概念:

  1. Chart(包):Helm 的软件包,包含运行应用所需的所有资源定义。例如,一个 Nginx Chart 包含了 Deployment、Service、ConfigMap 和 Ingress。
  2. Repository(仓库):存放和共享 Chart 的地方,类似于 Docker Hub。
  3. Release(发布):Chart 在 Kubernetes 集群中运行的一个实例。my-nginx 就是我们这条命令中的 Release 名称

关键组件:Tiller 去哪了?(v3 变化)

如果您看过老教程,会提到 Tiller(服务端组件)。但在 Helm v3 中,Tiller 已被移除!

  • v2:客户端(Client)通过 gRPC 与集群内的 Tiller 交互。
  • v3:客户端直接与 Kubernetes API Server 交互,Release 信息以 Secret 形式存储在 etcd 中。这极大提升了安全性和简易性。

第二部分:破解 helm upgrade 命令的奥秘

让我们将 helm upgrade my-nginx ./nginx-chart --set image.tag=1.25.3 -n web 大卸八块:

参数/选项含义解释
命令upgrade如果 Release 不存在则安装,如果已存在则升级。这是最常用的命令。
Release 名称my-nginx这是您为部署起的名字。后续更新、回滚或删除都靠它来标识。
Chart 路径./nginx-chart这是 Chart 的本体。注意:这里用的是本地路径,而不是仓库名。这说明您在开发或使用本地修改过的 Chart。
配置参数--set image.tag=1.25.3通过命令行动态覆盖 values.yaml 中的镜像版本,无需修改文件即可完成版本升级。
命名空间-n web指定 Release 部署在 web 命名空间下。不指定则默认为 default

执行此命令时,Helm 做了什么?

  1. 读取 ./nginx-chart 目录下的 Chart.yaml 和模板文件。
  2. 根据 values.yaml--set image.tag=1.25.3 合并渲染模板。
  3. 对比集群中 my-nginx 的旧版本与现在的新版本差异。
  4. 生成 Kubernetes 资源对象的 Patch(补丁)并发送给 API Server。
  5. 更新 Release 状态,并将此次版本记录(Revision)保存为 Secret。

第三部分:常用 Helm 命令速查表(附场景)

基于上面的逻辑,我们整理一下日常最常用的命令:

1. 添加仓库与搜索

bash
# 添加 Bitnami 仓库(包含 Nginx Chart)
helm repo add bitnami https://charts.bitnami.com/bitnami

# 添加 Nginx 官方仓库
helm repo add nginx-stable https://helm.nginx.com/stable

# 更新仓库索引
helm repo update

# 搜索 Nginx 相关 Chart
helm search repo nginx

2. 安装(Install)

bash
# 从仓库安装 Nginx
helm install my-nginx bitnami/nginx -n web

# 从本地目录安装(调试常用)
helm install my-nginx ./nginx-chart -f custom-values.yaml

# 安装时指定版本
helm install my-nginx bitnami/nginx --version 15.0.0 -n web

3. 升级与回滚(Upgrade & Rollback)

bash
# 升级 Nginx 镜像版本(对应开篇命令)
helm upgrade my-nginx ./nginx-chart --set image.tag=1.25.3

# 升级时使用新的 values 文件
helm upgrade my-nginx bitnami/nginx -f production-values.yaml

# 查看历史版本
helm history my-nginx -n web

# 回滚到版本 2
helm rollback my-nginx 2

4. 卸载(Uninstall)

bash
# 卸载 Release
helm uninstall my-nginx

# 卸载并保留历史记录(方便恢复)
helm uninstall my-nginx --keep-history

5. 调试与渲染(Debug)

这是最实用的调试技巧,执行后不会真正部署

bash
# 渲染模板并输出到屏幕
helm template my-nginx ./nginx-chart --debug

# 模拟安装过程(连接集群验证)
helm install my-nginx ./nginx-chart --dry-run --debug

# 查看渲染后的完整 YAML(含合并后的 values)
helm template my-nginx ./nginx-chart --debug --set image.tag=1.25.3

第四部分:Chart 结构深度解剖

当您看到 ./nginx-chart 时,一个标准的 Chart 目录结构如下(以 Nginx 为例):

nginx-chart/
├── Chart.yaml          # 必选:Chart 元数据(名称、版本、描述)
│                       # 示例:name: nginx, version: 15.0.0, appVersion: 1.25.3
├── values.yaml         # 必选:默认配置值
│                       # 包含:image.tag, service.type, ingress.enabled 等
├── charts/             # 可选:子 Chart(依赖项)
├── templates/          # 必选:K8s YAML 模板
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── configmap.yaml
│   ├── _helpers.tpl   # 模板函数定义(下划线开头)
│   └── NOTES.txt      # 安装后显示的提示信息
└── crds/               # 可选:自定义资源定义

values.yaml--set 的优先级

  1. 默认 values.yaml (最低)
  2. 父 Chart 的 values.yaml
  3. 命令行 --set--set-file
  4. 命令行 -f 指定的文件 (最高)

最佳实践:复杂项目建议使用 -f production.yaml 区分环境,少用 --set 堆砌参数。例如 Nginx 生产环境推荐使用 -f production.yaml 覆盖副本数、资源限制和 Ingress 配置。

第五部分:进阶实战 —— 让你的 Helm 技能更上一层楼

1. 生命周期钩子(Hooks)

Helm 允许您在 Release 安装/升级/删除的特定时刻执行 Job 或 Pod。常用于配置预热、缓存清理等场景。

以下示例在 Nginx 升级前执行配置验证 Job:

yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: nginx-config-test
  annotations:
    "helm.sh/hook": pre-upgrade          # 在升级前执行
    "helm.sh/hook-weight": "5"           # 权重越小越先执行
    "helm.sh/hook-delete-policy": hook-succeeded # 成功后删除 Job
spec:
  template:
    spec:
      containers:
      - name: config-test
        image: nginx:1.25.3
        command: ["nginx", "-t"]
        volumeMounts:
        - name: config
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
      volumes:
      - name: config
        configMap:
          name: nginx-config
      restartPolicy: Never

2. 依赖管理(Dependencies)

Chart.yaml 中声明依赖,类似于 requirements.txt。例如 Nginx 依赖 Redis 作为缓存后端:

yaml
dependencies:
  - name: redis
    version: "18.x.x"
    repository: "https://charts.bitnami.com/bitnami"
    condition: redis.enabled  # 可通过 values 开关
    alias: cache              # 别名,避免冲突

安装时自动处理依赖:

bash
helm dependency update ./nginx-chart

3. 使用 Lookup 函数实现幂等性

Helm v3 引入了 lookup 函数,允许模板查询集群现有资源。这解决了一个痛点:避免重复创建资源导致的冲突

go
{{ if not (lookup "v1" "ConfigMap" .Release.Namespace "nginx-config") }}
# 如果 ConfigMap 不存在,则创建
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  nginx.conf: |
    {{ .Values.nginxConfig | indent 4 }}
{{ end }}

4. 使用 Values 验证(Schema)

Helm v3 支持通过 values.schema.json 对 values 进行 JSON Schema 验证,在安装前拦截错误配置:

json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "image": {
      "type": "object",
      "properties": {
        "tag": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$" }
      }
    },
    "replicaCount": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10
    }
  },
  "required": ["image", "replicaCount"]
}

第六部分:避坑指南与最佳实践

  1. 不要在模板中硬编码 Namespace:使用 .Release.Namespace 变量,配合 -n 参数动态指定。
  2. 管理 CRD 要谨慎:Helm 不会升级 CRD(除非在 crds/ 目录)。CRD 的变更通常需要手动处理或使用 helm upgrade --force(慎用)。
  3. 存储空间考虑:每次 upgrade 都会生成新的 Secret(记录 Revision)。默认保留 10 个,可修改 --history-max
  4. 使用 OCI 仓库:现代 Helm 支持将 Chart 推送到 Harbor 或 Docker Registry(OCI 格式):
    bash
    helm package ./nginx-chart
    helm push nginx-chart-15.0.0.tgz oci://registry.company.com/charts
  5. 敏感信息管理:避免在 values 中明文存储密码,优先结合 Kubernetes Secret 或外部密钥管理工具(如 Vault)。
  6. 版本锁定:生产环境建议锁定 Chart 版本和 App 版本,避免意外升级破坏兼容性:
    bash
    helm install my-nginx bitnami/nginx --version 15.0.0 --set image.tag=1.25.3

结语:从命令到生产力

再回到开头的命令:

bash
helm upgrade my-nginx ./nginx-chart --set image.tag=1.25.3 -n web

现在您已经知道:这是在 web 命名空间下,使用本地目录 ./nginx-chart 中的 Chart,将名为 my-nginx 的 Nginx Release 升级1.25.3 版本。

Helm 的强大之处在于它将复杂的 YAML 编排抽象为简单的命令和版本管理。掌握了它,您就拥有了管理云原生应用大规模交付的利器。


相关资源推荐

最后更新2026/08/21 02:55
如果你觉得这篇文章有帮助,或者想聊聊技术、工作,欢迎通过下面方式联系我:
contact fishfinal