Helm 解决了什么问题
部署一个完整的应用(如 MySQL)需要创建 Deployment、Service、ConfigMap、Secret、PVC、ServiceAccount 等多个 YAML 文件,还需要按正确顺序 apply。Helm 将这些打包为一个 Chart,让你用一行命令完成整个应用的部署。
没有 Helm
- 手动管理 10+ 个 YAML 文件
- 不同环境复制修改 YAML
- 升级时手动比较 diff
- 回滚需要记住旧配置
- 无法复用他人的配置
有了 Helm
- 一条命令安装/升级/回滚
- values.yaml 管理环境差异
- 版本化的发布历史记录
- Artifact Hub 上万现成 Chart
- 模板化复用,DRY 原则
Helm 安装
# macOS
brew install helm
# Linux
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# 验证
helm version
Chart 目录结构
Chart 标准目录结构 my-app/ ├── Chart.yaml Chart 元数据(名称、版本、描述) ├── values.yaml 默认配置值(最重要的文件) ├── charts/ 依赖的子 Chart ├── templates/ YAML 模板目录 │ ├── deployment.yaml │ ├── service.yaml │ ├── configmap.yaml │ ├── ingress.yaml │ ├── _helpers.tpl 模板辅助函数(下划线开头不渲染为资源) │ └── NOTES.txt 安装成功后显示的提示信息 └── .helmignore 类似 .gitignore,打包时排除的文件
Chart.yaml
apiVersion: v2 # Helm 3 使用 v2
name: my-app # Chart 名称
description: A simple web application
type: application # application 或 library
version: 0.1.0 # Chart 版本(SemVer)
appVersion: "1.2.3" # 应用版本(显示用,不影响部署)
dependencies: # 依赖的 Chart
- name: mysql
version: 9.x.x
repository: https://charts.bitnami.com/bitnami
condition: mysql.enabled # 可选条件,values 中控制是否启用
values.yaml
# 这是模板的默认值,用户可以通过 --values 或 --set 覆盖
replicaCount: 2
image:
repository: nginx
tag: "1.25"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: false # 默认不创建 Ingress
host: example.com
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
mysql:
enabled: true
auth:
rootPassword: changeme
database: myapp
模板语法
Helm 使用 Go 模板语言({{ }})将 values.yaml 中的值注入 YAML 模板。
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-app.fullname" . }} # 调用 _helpers.tpl 中的函数
labels:
{{- include "my-app.labels" . | nindent 4 }} # 缩进 4 空格
spec:
replicas: {{ .Values.replicaCount }} # 注入 values
selector:
matchLabels:
{{- include "my-app.selectorLabels" . | nindent 6 }}
template:
spec:
containers:
- name: {{ .Chart.Name }} # Chart 名称
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
resources:
{{- toYaml .Values.resources | nindent 10 }} # 对象直接转 YAML
{{- if .Values.ingress.enabled }} # 条件判断
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "my-app.fullname" . }}
spec:
rules:
- host: {{ .Values.ingress.host }}
{{- end }}
Helm 常用命令
仓库管理
# 添加常用仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add stable https://charts.helm.sh/stable
helm repo update # 更新本地缓存
# 搜索 Chart
helm search repo mysql
helm search hub redis # 从 Artifact Hub 搜索
# 查看 Chart 的 values
helm show values bitnami/mysql
安装与升级
# 安装(第一次部署)
helm install my-release bitnami/mysql \
--namespace production \
--create-namespace \
--values prod-values.yaml \
--set auth.rootPassword=myStrongPass
# 升级(更新配置或 Chart 版本)
helm upgrade my-release bitnami/mysql \
--values prod-values.yaml
# install or upgrade(幂等,推荐在 CI 中使用)
helm upgrade --install my-release bitnami/mysql \
--values prod-values.yaml
# 查看 Release 列表
helm list -A # 所有 namespace
# 查看 Release 状态
helm status my-release
# 查看发布历史
helm history my-release
# 回滚到上一版本
helm rollback my-release
# 回滚到指定版本
helm rollback my-release 2
# 卸载
helm uninstall my-release
helm upgrade --install 的重要性
在 CI/CD 流水线中,始终使用 helm upgrade --install 而不是分别判断 install/upgrade。这样无论是首次部署还是更新,命令都能正确执行,保证流水线的幂等性。
创建自定义 Chart
# 创建 Chart 脚手架
helm create my-app
# 检查模板语法(不部署)
helm lint my-app/
# 渲染模板(查看生成的 YAML,不部署)
helm template my-release my-app/ \
--values my-values.yaml
# 调试安装(--dry-run 只渲染,不实际部署)
helm install my-release my-app/ \
--dry-run --debug
# 打包 Chart
helm package my-app/ # 生成 my-app-0.1.0.tgz
# 推送到 OCI 仓库(Helm 3.8+)
helm push my-app-0.1.0.tgz oci://registry.example.com/charts
多环境配置管理
# values-dev.yaml / values-staging.yaml / values-prod.yaml
# 每个环境只覆盖不同的部分
# 开发环境部署
helm upgrade --install my-app ./my-app \
--namespace dev \
-f values-dev.yaml
# 生产环境部署(基础值 + 生产覆盖值)
helm upgrade --install my-app ./my-app \
--namespace production \
-f values.yaml \
-f values-prod.yaml \ # 后面的 -f 覆盖前面的
--set image.tag=$CI_COMMIT_SHA # --set 优先级最高
常见错误:values 中的密码暴露
不要将生产密码写入 values.yaml 并提交到 Git!使用 --set 从 CI/CD 环境变量注入,或配合 Helm Secrets 插件(结合 SOPS 加密)管理敏感 values。在 values.yaml 中只保留空占位符或非敏感默认值。