前言

在 K8s 上部署一个应用要写 Deployment+Service+ConfigMap+Ingress 一大摞 YAML;部署十个微服务?复制粘贴地狱。Helm 就是 K8s 的包管理器——模板化 + 参数化 + 版本化,一个命令装好整套应用。

一、三大概念

Chart    = 应用包(模板 + 默认值的集合, 一个目录/压缩包)
Release  = Chart 的一次安装实例(同名 Chart 可装多份, 各自独立)
Repository = 存放 Chart 的仓库(官方/自建 Harbor)

类比:Chart ≈ rpm 包,values ≈ 配置文件,Release ≈ 安装好的软件实例,helm repo ≈ yum 源。

二、安装与常用命令

# 安装 helm(国内加速)
curl -LO https://ghfast.top/https://github.com/helm/helm/releases/download/v3.15.2/helm-v3.15.2-linux-amd64.tar.gz
tar -xzf helm-v3.15.2-linux-amd64.tar.gz && install linux-amd64/helm /usr/local/bin/

helm version

# 仓库管理
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# 搜索与安装
helm search repo nginx
helm install my-web bitnami/nginx \
  --namespace web --create-namespace \
  --set replicaCount=2

# 升级 / 回滚 / 卸载
helm upgrade my-web bitnami/nginx --set replicaCount=4
helm rollback my-web 1
helm uninstall my-web -n web

# 查看
helm list -A
helm status my-web -n web
helm get values my-web -n web        # 当前生效的覆盖值
helm history my-web -n web

三、Chart 结构

helm create myapp            # 生成脚手架
myapp/
├── Chart.yaml          # 元信息: name/version/appVersion/依赖
├── values.yaml         # 默认值(被 --set/-f 覆盖)
├── charts/             # 子 Chart 依赖
└── templates/
    ├── deployment.yaml # 模板(引用 values 的值)
    ├── service.yaml
    ├── ingress.yaml
    ├── _helpers.tpl    # 公共命名函数
    ├── NOTES.txt       # 安装完成后的提示输出
    └── tests/          # helm test 的 Pod

模板核心语法:

# templates/deployment.yaml(节选)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "myapp.fullname" . }}
spec:
  replicas: {{ .Values.replicaCount }}          # 引用 values
  template:
    spec:
      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
        resources:
          requests:
            cpu: {{ .Values.resources.requests.cpu }}
        {{- if .Values.metrics.enabled }}       # 条件块
        ports:
        - containerPort: 9090
        {{- end }}
# values.yaml(可覆盖的旋钮)
replicaCount: 2
image:
  repository: reg.local/myapp
metrics:
  enabled: false
resources:
  requests: {cpu: 100m}

value 覆盖的三种方式(优先级从低到高):values.yaml → -f custom.yaml → --set k=v。

四、实战:部署一个完整业务

# 用自定义 values 部署(比改模板优雅)
cat > prod-values.yaml <<'EOF'
replicaCount: 5
image:
  repository: reg.local/team/api
  tag: v1.8.0
ingress:
  enabled: true
  hosts:
    - host: api.antidebug.cn
      paths: [{path: /, pathType: Prefix}]
  tls:
    - secretName: api-tls
      hosts: [api.antidebug.cn]
resources:
  limits: {cpu: 500m, memory: 512Mi}
autoscaling:
  enabled: true
  minReplicas: 5
  maxReplicas: 20
EOF

helm upgrade --install api ./myapp \
  -n prod --create-namespace \
  -f prod-values.yaml
# --install: 没装过就装, 装过就升级(幂等, CI 首选写法)

多环境管理:

myapp/
├── values.yaml          # 公共默认
└── envs/
    ├── dev.yaml         # 1副本/debug
    ├── staging.yaml     # 2副本
    └── prod.yaml        # 5副本/HPA/正式域名

五、发布与版本管理

# 打包
helm package myapp            # → myapp-0.1.0.tgz

# 推到私有仓库(Harbor 开启 chartmuseum)
helm plugin install https://ghfast.top/https://github.com/chartmuseum/helm-push
helm repo add harbor https://harbor.local/chartrepo/team
helm push myapp-0.1.0.tgz harbor

# 团队成员
helm repo update
helm install team-api team/myapp -f my-overrides.yaml

版本语义:Chart.yaml 的 version 是 Chart 打包版本,appVersion 是应用版本——升应用改 image.tag 即可,改模板结构才动 version。

六、Helm 的版本机制本质

helm install/upgrade 时:
  1. 渲染全部模板 → 生成最终 YAML
  2. 写入 Secret 保存这份 YAML(就是 Release 历史)
  3. 应用到集群

helm rollback 时:
  直接取出历史 Secret 里的旧 YAML 重新 apply
  → 所以"回滚秒级且可靠"
# 只渲染不安装(调试模板神器)
helm template myapp -f prod-values.yaml | less
helm template myapp --debug | kubectl apply --dry-run=server -f -

# 模板渲染错误排查
helm lint myapp
helm install --dry-run --debug myapp ./myapp

七、依赖与公共 Chart 复用

# Chart.yaml: 应用依赖一个数据库
dependencies:
- name: redis
  version: "19.x.x"
  repository: "oci://registry-1.docker.io/bitnamicharts"
helm dependency update myapp     # 拉取到 charts/ 目录
helm install myapp ./myapp

子 Chart 的值用 redis.auth.password=xxx 前缀覆盖——复杂中间件直接复用公共 Chart,别手写。

八、常见坑

现象 原因
--set 值没生效 key 路径写错;helm get values 看实际值
模板改了但没变化 忘了 upgrade;看 helm list 的 chart 版本
uninstall 后资源还在 资源带了 helm.sh/resource-policy: keep 注解
rollback 报丢失 Release 被 purge 过(--keep-history 没加)
数字/布尔被当字符串 --set replicaCount=2 是数字, --set name="2" 要引号
升级卡 pending-upgrade 上次操作超时中断 → helm rollback 或删 lock

九、Helm vs Kustomize

维度 Helm Kustomize
思路 模板 + 变量渲染 原始 YAML + overlay 打补丁
适合 一个产品装 N 家、参数多 同一套 YAML 多环境微调
依赖/仓库 ✅ 完整生态 无
学习 模板语法有成本 几乎零语法

实践:中间件/公共组件用 Helm,自家应用多环境用 Kustomize 或 Helm 皆可。

小结

任务 命令
装 helm install xx chart -f values.yaml
升级 helm upgrade --install(幂等)
回滚 helm rollback xx 1
调试 helm template / --dry-run --debug
发布 helm package + helm push 到 Harbor

本文是「云原生」系列第 15 篇。