Oamc

Helm 包管理实战

本页目录

场景

团队需要在 K8s 集群里部署复杂应用:微服务、数据库、中间件、监控组件。手写 YAML 不仅繁琐,还难以管理版本、环境差异、依赖关系。

Helm 解决三个核心问题:

  • 模板化 — 把 YAML 参数化,同一套 Chart 跨环境复用
  • 依赖管理 — requirements.yaml / Chart.yaml 声明依赖,一键拉取
  • 发布管理 — 版本、回滚、历史、diff,发布过程可控

前置条件

  • K8s 集群 1.19+(Helm 3 不再需要 Tiller)
  • 本地已安装 Helm 3.8+
  • 有集群的 kubeconfig,且有创建 namespace、CRD 的权限
  • 了解基本的 K8s 资源对象

配置

1. 基础操作

# 添加常用仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add grafana https://grafana.github.io/helm-charts
helm repo update

# 搜索
helm search repo nginx
helm search repo prometheus

# 查看 Chart 详情
helm show chart bitnami/redis
helm show values bitnami/redis > redis-values.yaml

2. 安装与配置

# 默认值安装
helm install my-redis bitnami/redis -n redis --create-namespace

# 自定义 values
helm install my-redis bitnami/redis \
  -n redis --create-namespace \
  -f redis-values.yaml \
  --set auth.password=StrongPass123 \
  --set replica.replicaCount=2

# 覆盖单个值(命令行优先级最高)
helm upgrade my-redis bitnami/redis -n redis \
  --set replica.replicaCount=3 \
  --set auth.password=NewPass456

3. 管理发布

# 查看
helm list -n redis
helm status my-redis -n redis
helm get values my-redis -n redis       # 当前生效的值
helm get manifest my-redis -n redis     # 渲染后的完整 manifest

# 回滚
helm history my-redis -n redis
helm rollback my-redis 1 -n redis       # 回滚到 revision 1

# 卸载(保留 PVC 用 --keep-history)
helm uninstall my-redis -n redis

4. 开发自己的 Chart

helm create myapp
# 生成结构:
# myapp/
#   Chart.yaml          # 元数据
#   values.yaml         # 默认值
#   templates/          # 模板
#   charts/             # 依赖 Chart

Chart.yaml 关键字段

apiVersion: v2
name: myapp
description: 我的微服务应用
type: application
version: 1.0.0        # Chart 版本
appVersion: "1.2.3"   # 应用版本
keywords:
  - microservice
  - api
maintainers:
  - name: 运维团队
    email: ops@example.com
dependencies:
  - name: redis
    version: "17.x.x"
    repository: "https://charts.bitnami.com/bitnami"
    condition: redis.enabled

values.yaml 设计原则

# 全局配置
global:
  imageRegistry: harbor.example.com
  imagePullSecrets:
    - harbor-secret

# 开关控制
redis:
  enabled: true
  auth:
    enabled: true
    password: "changeme"

# 资源配额
resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 200m
    memory: 256Mi

# 环境区分
env: production

5. 模板最佳实践

# _helpers.tpl 定义通用标签
{{- define "myapp.labels" -}}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
{{ include "myapp.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

# 模板中使用
metadata:
  labels:
    {{- include "myapp.labels" . | nindent 4 }}

环境区分(values-prod.yaml / values-staging.yaml)

# 生产环境
helm install myapp ./myapp -n prod -f values.yaml -f values-prod.yaml

# 测试环境
helm install myapp ./myapp -n staging -f values.yaml -f values-staging.yaml

6. 常用调试技巧

# 只渲染不安装(调试模板)
helm template myapp ./myapp -n test -f values.yaml

# 模拟升级(看 diff)
helm upgrade --dry-run myapp ./myapp -n prod -f values-prod.yaml

# 查看 hooks
helm get hooks my-release -n ns

# 调试模板函数
helm template ./myapp --show-only templates/deployment.yaml

验证

# 部署后检查
kubectl get pods -n ns -l app=myapp
kubectl logs -n ns -l app=myapp -c main
helm test my-release -n ns          # 运行 Chart 定义的测试

# 验证 Chart 语法
helm lint ./myapp

回滚

# 快速回滚
helm rollback myapp 1 -n prod

# 指定版本回滚
helm history myapp -n prod
helm rollback myapp 3 -n prod

坑

坑 现象 避坑
values 里写了 enabled: false 但依赖 Chart 还是装了 依赖的 condition 写错 检查 Chart.yaml 里的 condition: xxx.enabled
升级后旧 PVC 绑不上 StorageClass / PVC 名字变了 用 helm upgrade 不要改 PVC 名,或手动迁移
helm upgrade 把 ConfigMap 覆盖了 没用 --reuse-values helm upgrade -f new.yaml --reuse-values
helm dependency update 报错 依赖仓库没加 / 版本不存在 helm repo update 先,指定版本号
Chart 版本和 App 版本混淆 Chart version ≠ appVersion version 是 Chart 版本,appVersion 是镜像版本
环境变量没生效 模板里写死值了 用 .Values.xxx 不要硬编码
helm upgrade 把 PVC 删了 Chart 里 PVC 没设 keepPolicy 加 helm.sh/resource-policy: keep 注解