helm —— K8s 的包管理器

运维工具手册 06-容器与编排 6.9 KB 原文

helm —— K8s 的包管理器

分类:06 容器与编排 适用:Helm 3.x(v2 已淘汰,无 Tiller) 一句话:把一组 K8s 清单打包成 chart,用 values 参数化,安装/升级/回滚一条命令。

1. 它解决什么问题

  • 一个应用有 Deployment、Service、ConfigMap、Ingress、HPA 十几个 YAML,手工维护易错。
  • 多环境(dev/staging/prod)只有少量参数不同,不想复制三份清单。
  • 升级失败要能一条命令回到上一版。
  • 用社区成熟 chart 快速搭 Prometheus、Redis、Nginx。

2. 安装与基本概念

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
helm version
概念 含义
chart 应用包(目录或 tgz)
release 一次安装实例,同名 release 在一个 namespace 内唯一
repository chart 仓库
values 参数文件,覆盖 chart 默认值
revision 每次 install/upgrade 递增的版本号

3. 仓库与搜索

helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm repo list
helm search repo nginx
helm search repo nginx --versions        # 所有版本
helm search hub redis                    # 搜 Artifact Hub

国内网络可换镜像源或用离线 chart:

helm pull bitnami/nginx --version 15.0.0 --untar
helm install web ./nginx

4. 安装与升级

# 安装
helm install web bitnami/nginx -n myapp --create-namespace

# 带自定义 values
helm install web bitnami/nginx -n myapp -f values-prod.yaml

# 覆盖单个值
helm install web bitnami/nginx --set replicaCount=3 --set image.tag=1.25

# 安装或升级(幂等,CI 常用)
helm upgrade --install web bitnami/nginx -n myapp -f values.yaml --create-namespace

# 指定版本
helm upgrade --install web bitnami/nginx --version 15.0.0

# 升级并等待就绪,失败自动回滚
helm upgrade --install web bitnami/nginx -n myapp -f values.yaml \
  --atomic --wait --timeout 5m

# 只渲染不安装(预览)
helm template web bitnami/nginx -f values.yaml
helm install web bitnami/nginx --dry-run --debug

--set 语法

--set image.tag=1.25
--set replicas=3
--set resources.limits.memory=1Gi
--set ingress.hosts[0].host=app.example.com
--set-string image.tag=1.25          # 强制字符串(避免 1.25 被当浮点)
--set-json 'config={"a":1}'
--set-file config=./app.conf

值里有逗号、点号时要用 --set-string 或 --set-literal,否则会被解析成嵌套结构。

5. 查看与回滚

helm list -A                          # 所有 release
helm list -n myapp
helm status web -n myapp
helm history web -n myapp             # 版本历史
helm get values web -n myapp          # 当前生效的 values(用户覆盖部分)
helm get values web -n myapp --all    # 含默认值
helm get manifest web -n myapp        # 渲染后的清单
helm get all web -n myapp             # 全部信息

helm rollback web 3 -n myapp          # 回到 revision 3
helm rollback web -n myapp            # 回到上一版
helm uninstall web -n myapp
helm uninstall web -n myapp --keep-history

6. chart 开发

helm create mychart

目录结构:

mychart/
├── Chart.yaml          # 元信息:name/version/appVersion
├── values.yaml         # 默认值
├── templates/          # 模板(Go template)
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── _helpers.tpl    # 可复用片段
│   ├── NOTES.txt       # 安装后提示
│   └── tests/
└── charts/             # 子 chart 依赖

常用模板语法

metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
          env:
            {{- range $k, $v := .Values.env }}
            - name: {{ $k }}
              value: {{ $v | quote }}
            {{- end }}

条件与循环

{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
...
{{- end }}

{{- range .Values.hosts }}
- host: {{ . }}
{{- end }}

校验与打包

helm lint mychart
helm template mychart -f values.yaml | kubectl apply --dry-run=server -f -
helm package mychart                  # 生成 mychart-0.1.0.tgz
helm install test ./mychart-0.1.0.tgz

依赖

Chart.yaml:

dependencies:
  - name: redis
    version: "17.x.x"
    repository: https://charts.bitnami.com/bitnami
    condition: redis.enabled
helm dependency update mychart        # 生成 Chart.lock 与 charts/
helm dependency build mychart

7. 实战场景

7.1 标准发布流程

# 1. 渲染预览
helm template web ./charts/app -n prod -f values-prod.yaml > /tmp/rendered.yaml
kubectl diff -f /tmp/rendered.yaml

# 2. 校验
helm lint ./charts/app -f values-prod.yaml

# 3. 发布(失败自动回滚)
helm upgrade --install web ./charts/app -n prod \
  -f values-prod.yaml \
  --set image.tag="$CI_COMMIT_SHA" \
  --atomic --wait --timeout 10m

# 4. 确认
helm status web -n prod
kubectl rollout status deploy/web -n prod

7.2 升级后 Pod 起不来,快速回滚

helm history web -n prod
helm rollback web <上一个revision> -n prod --wait
kubectl get pods -n prod -w

7.3 多环境 values 管理

charts/app/
values.yaml            # 默认
values-dev.yaml        # 开发覆盖
values-staging.yaml
values-prod.yaml
helm upgrade --install app ./charts/app -f values.yaml -f values-prod.yaml

后加载的文件覆盖前面的,--set 优先级最高。

7.4 查看实际部署了什么

helm get manifest web -n prod | grep -E 'image:|replicas:'
helm get values web -n prod
kubectl get deploy web -o jsonpath='{.spec.template.spec.containers[*].image}'

7.5 迁移已有资源到 Helm

# 手工创建的资源加注解与标签,纳入 release 管理
kubectl annotate deploy web meta.helm.sh/release-name=web -n prod
kubectl annotate deploy web meta.helm.sh/release-namespace=prod -n prod
kubectl label deploy web app.kubernetes.io/managed-by=Helm -n prod
helm upgrade --install web ./charts/app -n prod

8. 常见坑

  1. --reuse-values 会沿用旧值:升级时改了 values.yaml 但加了 --reuse-values,新值不生效。除非明确要保留历史值,否则别用。
  2. CRD 不会被升级:crds/ 目录只在 install 时安装,升级需手动 kubectl apply CRD。
  3. --atomic 需要 --wait:否则不检测就绪,回滚条件不成立。
  4. --wait 会卡住:有 Job/InitContainer 未完成时一直等,配 --timeout。
  5. release 存在 Secret 里:kubectl get secret -n <ns> -l owner=helm,同名 release 冲突时能看到历史。
  6. upgrade 不会删掉已从模板移除的资源:例如删了 Service 模板,旧 Service 仍在,需手动删。
  7. helm uninstall 删不干净:PVC、CRD、Namespace 通常保留,要手动清理。
  8. values 里的 null 与空字符串:null 表示删除该键,可能让默认值失效。
  9. --set 里的特殊字符:逗号、点、等号要转义或用 --set-string。
  10. chart 版本与 appVersion 混淆:--version 指 chart 版本,镜像 tag 要单独设。
  11. hooks 失败导致升级卡住:pre-upgrade Job 失败会阻塞,helm history 能看到状态。
  12. 多 namespace 同名 release 互不影响,但 -n 漏写会装到 default。
  13. Helm 3 没有 helm init:老教程的 Tiller 概念全部作废。

9. 速查表

helm repo add <name> <url> && helm repo update
helm search repo <kw> --versions
helm pull <repo>/<chart> --untar

helm install <rel> <chart> -n <ns> --create-namespace -f v.yaml
helm upgrade --install <rel> <chart> -n <ns> -f v.yaml --atomic --wait
helm upgrade --install <rel> <chart> --set image.tag=1.2.3
helm template <rel> <chart> -f v.yaml          # 预览
helm lint <chart>
helm install <rel> <chart> --dry-run --debug

helm list -A
helm status <rel> -n <ns>
helm history <rel> -n <ns>
helm get values <rel> -n <ns> --all
helm get manifest <rel> -n <ns>
helm rollback <rel> <rev> -n <ns> --wait
helm uninstall <rel> -n <ns>

helm create <chart>
helm package <chart>
helm dependency update <chart>