Helm:Kubernetes 的包管理器
概述#
当你手动管理过几十个 YAML 文件、为 dev/staging/prod 三套环境反复拷贝修改配置之后,你一定会想:有没有一种方式,把 Deployment、Service、ConfigMap 打包成一个可复用的"应用模板"?Helm 就是 K8s 生态中解决这个问题的标准答案。本章从 Helm 的定位讲起,逐步带你完成第一个 Helm 部署。
一、为什么需要 Helm#
1.1 纯 YAML 管理的三大痛点#
在没有 Helm 的时候,部署一个应用通常需要维护多个 YAML 文件:
my-app/
├── deployment.yaml
├── service.yaml
├── configmap.yaml
├── ingress.yaml
└── hpa.yaml当需要部署到多个环境时,问题就来了:
| 痛点 | 表现 | 后果 |
|---|---|---|
| 多环境重复配置 | dev/staging/prod 各拷贝一份,手动改 replicas、镜像 tag、资源限制 | 改一个地方漏了另一个,发版靠人肉校对 |
| 版本管理混乱 | "上次部署用的是什么版本的镜像?""这个 ConfigMap 是谁改的?" | 回滚靠记忆,出问题抓瞎 |
| 依赖关系手动维护 | 应用依赖 Redis → 先去部署 Redis → 返回头部署应用 → 改连接配置 | 步骤多,容易出错 |
1.2 Helm 解决了什么#
Helm 将应用定义为 Chart(包),将所有 K8s 资源模板化,并通过 values.yaml 集中管理可变配置:
手动管理:
环境1 → 拷贝修改6个YAML → kubectl apply
环境2 → 拷贝修改6个YAML → kubectl apply ← 6×N 个文件
环境3 → 拷贝修改6个YAML → kubectl apply
Helm 管理:
一份模板 + 环境参数 → helm install/upgrade ← 模板+参数
dev: helm install -f values-dev.yaml
staging: helm install -f values-staging.yaml
prod: helm install -f values-prod.yaml核心价值:模板化(一处定义,多处使用)+ 版本化(每次部署都有版本记录,可回滚)+ 依赖管理(声明式定义应用之间的依赖关系)。
二、Chart 结构#
一个标准的 Helm Chart 目录如下:
my-app/
├── Chart.yaml # Chart 元数据
├── values.yaml # 默认配置值
├── templates/ # K8s 资源模板
│ ├── _helpers.tpl # 模板函数(不会直接渲染为资源)
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── configmap.yaml
│ └── NOTES.txt # 安装后显示给用户的说明
└── charts/ # 子 Chart 依赖2.1 Chart.yaml — 元数据#
描述 Chart 的基本信息,Helm 用这些信息做版本管理和依赖声明。
apiVersion: v2
name: my-app
description: 一个示例应用
type: application # application 或 library
version: 1.0.0 # Chart 自身的版本号(SemVer)
appVersion: "1.2.3" # 所部署应用的版本号
dependencies: # 依赖的其他 Chart
- name: redis
version: 18.x.x
repository: https://charts.bitnami.com/bitnami2.2 templates/ — K8s 资源模板#
templates/ 是 Chart 的核心。这里的每个 .yaml 文件都是一个 Go Template 模板,Helm 渲染时会用 values.yaml 中的值填充模板变量,生成最终的 K8s YAML。
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
labels:
app: {{ .Chart.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Chart.Name }}
template:
metadata:
labels:
app: {{ .Chart.Name }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: {{ .Values.service.port }}
protocol: TCP模板中的常用内置对象:
| 对象 | 含义 | 示例 |
|---|---|---|
.Release.Name | Release 名称(安装时指定) | my-app |
.Release.Namespace | 目标 Namespace | production |
.Chart.Name | Chart 名称 | my-app |
.Chart.Version | Chart 版本 | 1.0.0 |
.Values | values.yaml 中的配置 | .Values.replicaCount |
2.3 values.yaml — 可变配置#
values.yaml 存放所有可配置的参数,并附上默认值。它也是配置项的文档——每个字段都应该有注释说明用途。
# values.yaml — 默认值,同时作为配置文档
# 副本数,生产环境建议设为 3
replicaCount: 2
image:
repository: registry.example.com/my-app
pullPolicy: IfNotPresent
tag: "" # 部署时通过 --set image.tag=xxx 传入,避免误用 latest
service:
type: ClusterIP
port: 8080
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
# 健康检查
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 10
periodSeconds: 52.4 三件套协作流程#
values.yaml templates/ 最终 K8s YAML
┌──────────┐ ┌──────────────┐ ┌─────────────────┐
│replicaCount: 3 → │{{.Values. │ → │replicas: 3 │
│image.tag: v1.2 → │ replicaCount}}│ → │image: ...:v1.2 │
│port: 8080 → │ ... │ → │containerPort:8080│
└──────────┘ └──────────────┘ └─────────────────┘三、常用命令速查#
3.1 安装与卸载#
# 安装 Chart(从本地目录)
helm install my-release ./my-chart -n production --create-namespace
# 安装时传入自定义值
helm install my-release ./my-chart \
-f values-prod.yaml \ # 指定 values 文件
--set image.tag=v1.2.3 \ # 命令行覆盖单个值
-n production
# 卸载
helm uninstall my-release -n production3.2 升级#
# 升级到新版本
helm upgrade my-release ./my-chart \
-f values-prod.yaml \
--set image.tag=v1.2.4 \
-n production
# 生产环境推荐参数
helm upgrade my-release ./my-chart \
-f values-prod.yaml \
--set image.tag=v1.2.4 \
-n production \
--atomic \ # 升级失败自动回滚
--timeout 10m \ # 等待超时
--wait # 等待所有资源就绪后才返回
# upgrade --install:不存在则安装,存在则升级(CI 中最常用)
helm upgrade --install my-release ./my-chart \
-f values-prod.yaml \
--set image.tag=v1.2.4 \
-n production \
--atomic --wait --timeout 5m3.3 回滚#
# 查看发布历史
helm history my-release -n production
# 输出示例:
# REVISION UPDATED STATUS CHART DESCRIPTION
# 1 Tue Jun 24 10:00:00 superseded my-app-1.0 Install complete
# 2 Tue Jun 24 14:00:00 superseded my-app-1.0 Upgrade complete
# 3 Tue Jun 24 16:00:00 deployed my-app-1.0 Upgrade complete
# 回滚到上一个版本
helm rollback my-release -n production
# 回滚到指定版本
helm rollback my-release 2 -n production --wait3.4 查看状态和配置#
# 查看 Release 状态
helm status my-release -n production
# 查看当前生效的所有 values
helm get values my-release -n production --all
# 查看渲染后的完整 YAML(不会真正部署,用于调试)
helm template my-release ./my-chart \
-f values-prod.yaml \
--set image.tag=v1.2.4
# 查看 Release 列表
helm list -n production3.5 升级前 diff(强烈推荐)#
# 安装 helm-diff 插件
helm plugin install https://github.com/databus23/helm-diff
# 升级前预览实际变更
helm diff upgrade my-release ./my-chart \
-f values-prod.yaml \
--set image.tag=v1.2.4 \
-n production
# 输出会清晰显示哪些资源新增、修改、删除3.6 命令速查表#
| 命令 | 用途 | 常用参数 |
|---|---|---|
helm create <name> | 生成标准 Chart 骨架 | - |
helm install <name> <chart> | 首次安装 | -n, -f, --set, --create-namespace |
helm upgrade <name> <chart> | 升级 | -n, -f, --set, --atomic, --wait, --timeout |
helm rollback <name> [rev] | 回滚 | -n, --wait |
helm list | 列出 Release | -n, -A(所有 Namespace) |
helm status <name> | 查看状态 | -n |
helm history <name> | 查看版本历史 | -n |
helm get values <name> | 查看 values | -n, --all |
helm uninstall <name> | 卸载 | -n |
helm template <name> <chart> | 本地渲染预览 | -f, --set |
四、实战:用 Helm 部署应用#
4.1 创建 Chart#
# 生成标准 Chart 骨架
helm create my-web-app这会生成一个包含 Nginx 模板的示例 Chart。我们把它改造为自己的应用。
4.2 修改 values.yaml#
# my-web-app/values.yaml
replicaCount: 2
image:
repository: registry.example.com/my-web-app
pullPolicy: IfNotPresent
tag: "1.0.0" # 实际部署时通过 --set 覆盖
service:
type: ClusterIP
port: 8080
ingress:
enabled: true
host: my-web-app.example.com
path: /
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi4.3 本地验证模板#
# 渲染模板,确认没有语法错误
helm template my-web-app ./my-web-app --dry-run
# 检查渲染结果
helm template my-web-app ./my-web-app | grep -E "kind:|name:|image:"4.4 首次安装#
# 安装到 dev 环境
helm install my-web-app ./my-web-app \
--namespace dev \
--create-namespace \
--set image.tag=1.0.0
# 查看状态
helm status my-web-app -n dev
helm list -n dev4.5 升级部署#
# 升级镜像版本
helm upgrade my-web-app ./my-web-app \
--namespace dev \
--set image.tag=1.0.1 \
--atomic \
--wait \
--timeout 5m4.6 回滚操作#
# 假设 1.0.1 有问题,需要回滚
# 先查看历史
helm history my-web-app -n dev
# 回滚到上一个版本
helm rollback my-web-app -n dev --wait
# 确认回滚后的版本
kubectl get deployment my-web-app -n dev \
-o jsonpath='{.spec.template.spec.containers[0].image}'4.7 完整工作流总结#
开发 Chart 部署 运维
┌──────────┐ ┌──────────┐ ┌──────────┐
│helm create│ │helm install │helm upgrade
│修改模板和values│ → │or │helm rollback
│helm template验证│ │upgrade --install │helm history
└──────────┘ └──────────┘ └──────────┘4.8 实战要点#
upgrade --install比单独install更实用:在 CI 流水线中用这一条命令,首次自动安装,后续自动升级- 生产部署必须
--atomic:升级过程中如果 Pod 启动失败,Helm 会自动回滚,不会让集群处于半升级状态 - 上线前 run
helm diff:防止配置变更意外删除或修改关键资源 helm template先本地跑一遍:检查模板渲染是否正确,避免把错误的 YAML 推到集群
小结#
Helm 解决的是 K8s YAML 管理从"手工拷贝"到"模板化+版本化"的升级问题。它的核心是三个部分:
- Chart.yaml:声明 Chart 的元数据和依赖
- templates/:K8s 资源的 Go Template 模板,定义"资源长什么样"
- values.yaml:可变配置的集中存放地,定义"环境间的差异"
日常工作流就是:helm upgrade --install 部署 → helm diff 预览变更 → helm history + helm rollback 运维。记住,生产环境升级务必加 --atomic,这是用 Helm 最基本的保险。