你是否曾被以下问题困扰?

  • 一个微服务要部署到 dev、staging、prod 三个环境,却要维护三套几乎相同的 YAML 文件?
  • 想给同事分享一个可部署的 Go 服务,结果对方改了 20 个地方才跑起来?
  • 每次升级镜像版本,都要手动 sed 替换所有 Deployment 中的 image: my-app:v1

如果你还在“手写 YAML + 复制粘贴”管理 K8s 应用,那你正在重复造轮子。

Helm 正是为解决这些问题而生——它不是“更复杂的 YAML”,而是云原生时代的应用包管理器,就像 apt、yum 或 pip 之于操作系统和 Python。

本文将带你从痛点出发,深入 Helm 的核心结构、模板语法,并通过一个完整的 Go 微服务示例,展示如何实现标准化、可复用、多环境兼容的交付。


一、为什么需要 Helm?YAML 管理的三大痛点

痛点 1:重复配置

Deployment、Service、ConfigMap……一个微服务通常需要 4~6 个 YAML 文件。若团队有 20 个服务,就要维护上百个文件。

痛点 2:环境差异难管理

dev 用 replicas: 1,prod 用 replicas: 5;staging 连测试 DB,prod 连生产 DB。硬编码导致配置混乱。

痛点 3:缺乏版本与分发机制

YAML 文件散落在 Git 仓库中,无法像软件包一样“安装/升级/回滚”。

Helm 通过“模板 + 参数”机制,将这些痛点一并解决。


二、Chart 结构:一个标准 Helm 包长什么样?

执行 helm create my-app 会生成标准目录结构:

my-app/
├── Chart.yaml          # 元信息(名称、版本、描述)
├── values.yaml         # 默认参数值
├── charts/             # 依赖的子 Chart(可选)
└── templates/          # K8s YAML 模板
    ├── deployment.yaml
    ├── service.yaml
    ├── configmap.yaml
    └── _helpers.tpl    # 模板函数

核心思想

  • templates/ 中的文件是 Go 模板(text/template),支持变量、条件、循环;
  • 所有变量默认来自 values.yaml,可通过 --set-f custom-values.yaml 覆盖。

三、模板语法:让 YAML “活”起来

3.1 变量引用

# templates/deployment.yaml
spec:
  replicas: {{ .Values.replicaCount }}
  containers:
    - name: {{ .Chart.Name }}
      image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"

3.2 条件判断

{{- if .Values.serviceMonitor.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
...
{{- end }}

3.3 循环(range)

env:
{{- range $key, $value := .Values.env }}
  - name: {{ $key }}
    value: {{ $value | quote }}
{{- end }}

💡 提示:{{--}} 用于去除模板渲染时的多余空行,保持 YAML 格式整洁。


四、实战:将 Go 微服务封装为 Helm Chart

假设你有一个 Go 编写的用户服务,监听 8080 端口,依赖数据库地址和日志级别。

Step 1:定义 values.yaml

# values.yaml
replicaCount: 2

image:
  repository: harbor.example.com/go/user-service
  tag: "v1.0.0"
  pullPolicy: IfNotPresent

service:
  port: 80
  targetPort: 8080

env:
  LOG_LEVEL: info
  DB_HOST: user-db.prod.svc.cluster.local

resources:
  limits:
    memory: "128Mi"
    cpu: "100m"

Step 2:编写 templates/deployment.yaml

apiVersion: apps/v1
kind: Deployment
meta
  name: {{ include "user-service.fullname" . }}
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    spec:
      containers:
        - name: user-service
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          ports:
            - containerPort: {{ .Values.service.targetPort }}
          env:
          {{- range $key, $val := .Values.env }}
            - name: {{ $key }}
              value: {{ $val | quote }}
          {{- end }}
          resources:
            {{- toYaml .Values.resources | nindent 12 }}

Step 3:部署到不同环境

# 开发环境
helm install user-svc ./user-service -f values-dev.yaml

# 生产环境
helm install user-svc ./user-service -f values-prod.yaml --version 1.0.0

优势

  • 同一份 Chart,适配多环境;
  • 镜像版本、副本数、资源配置全部参数化;
  • 可通过 helm upgrade 安全滚动更新。

🔗 Helm 的 values.yaml 可替代《微服务》【配置篇】中的部分配置中心功能,适用于部署时静态配置。 对于运行时动态配置(如开关、限流阈值),仍需使用 Apollo、Nacos 等配置中心。


五、多环境支持:values 文件的组合策略

推荐目录结构:

charts/user-service/
├── values.yaml          # 默认值(通常对应 dev)
├── values-staging.yaml  # 覆盖 staging 特有配置
└── values-prod.yaml     # 覆盖 prod 特有配置

部署命令:

helm install user-svc . -f values-prod.yaml

Helm 会按顺序合并:

  1. 内置默认值(_helpers.tpl 中定义)
  2. values.yaml
  3. -f values-prod.yaml
  4. --set replicaCount=5

最终生效的是最高优先级的值。


六、私有仓库:Harbor + Helm Repo

公有 Chart 仓库(如 Artifact Hub)不适合企业。推荐使用 Harbor 自建 Helm 仓库

Harbor 从 v2.0 起原生支持 Helm Chart,操作简单:

  1. 在 Harbor 创建项目(如 charts);
  2. 推送 Chart:
helm package user-service
helm push user-service-1.0.0.tgz oci://harbor.example.com/charts
  1. 安装时直接引用:
helm install user-svc oci://harbor.example.com/charts/user-service --version 1.0.0

优势

  • 与镜像共用 Harbor 认证体系;
  • 支持 Chart 签名、漏洞扫描(需集成 Trivy);
  • 实现“镜像 + Chart”一体化治理。

结语:Helm 是工程规范的体现

Helm 的价值不在于“减少 YAML 行数”,而在于建立标准化、可审计、可复用的应用交付单元
一个优秀的 Helm Chart,应做到:

  • 参数清晰,文档完整;
  • 支持多环境,无硬编码;
  • 与 CI/CD 流水线无缝集成。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐