4. Helm 基础回顾:Chart 结构、模板引擎、Values 文件、依赖管理与仓库配置

在深入 Longhorn 的自动化变更门禁之前,必须牢固掌握 Helm 的核心概念。Helm 是 Kubernetes 的包管理器,它将应用的所有资源(Deployment、Service、PVC 等)打包为一个 Chart,并通过模板化实现环境间配置分离。本节将系统梳理 Helm 的五大支柱:Chart 目录结构、模板引擎语法、Values 文件层级、依赖管理机制以及仓库配置。

4.1 Chart 标准目录结构

一个标准的 Helm Chart 遵循固定的目录布局,每个目录和文件都有特定职责。下表列出了核心组件及其作用:

路径 / 文件必需说明
Chart.yaml是Chart 元数据:名称、版本、API 版本、描述、关键字等
values.yaml是默认配置值,供模板引擎引用
templates/是存放 Go 模板文件(.yaml/.tpl),渲染后生成 Kubernetes 资源
charts/否子 Chart 的打包目录,用于依赖管理
crds/否自定义资源定义(CRD),在模板渲染前安装
README.md否Chart 使用说明
.helmignore否打包时忽略的文件模式(类似 .gitignore)
💡 最佳实践: 在 Longhorn 的 Helm Chart 中,crds/ 目录用于存放 volumes.longhorn.io 等 CRD,确保在部署应用资源之前,Kubernetes 集群已注册这些自定义资源。

4.2 模板引擎与核心函数

Helm 使用 Go 模板引擎,结合 Sprig 函数库,将 values.yaml 中的值注入到模板文件中。模板文件位于 templates/ 目录,后缀通常为 .yaml 或 .tpl。

核心语法示例:

# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-{{ .Chart.Name }}
spec:
  replicas: {{ .Values.replicaCount | default 1 }}
  template:
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          env:
            - name: STORAGE_SIZE
              value: {{ .Values.storage.size | quote }}

常用模板函数与管道:

  • .Values — 引用 values.yaml 中的值
  • .Release.Name — 当前 Helm Release 名称
  • .Chart.Name / .Chart.Version — Chart 元数据
  • default — 设置默认值,如 replicas: {{ .Values.replicaCount | default 3 }}
  • quote / squote — 为字符串添加双引号或单引号
  • include — 引入命名模板(在 _helpers.tpl 中定义)
  • toYaml — 将结构体转为 YAML 格式
🔍 关键概念: 模板中的 . 代表当前作用域上下文。在 range 循环或 with 块中,. 会切换为当前迭代元素,此时需要通过 $.Values 访问全局根对象。

4.3 Values 文件层级与覆盖策略

Helm 支持多级 Values 文件,允许用户按环境(开发、测试、生产)或按功能模块(存储、网络、监控)拆分配置。加载优先级从低到高如下:

  1. 内置默认值 — values.yaml 中定义的默认值
  2. 父 Chart Values — 当 Chart 作为依赖被引用时,父 Chart 的 values 会覆盖子 Chart 的默认值
  3. 用户自定义 Values 文件 — 通过 -f 或 --values 指定,可叠加多个文件
  4. 命令行 --set 参数 — 最高优先级,直接覆盖单个键值对

典型 Values 文件结构示例:

# values.yaml (默认)
replicaCount: 3
image:
  repository: longhornio/longhorn-manager
  tag: v1.6.0
storage:
  defaultClass: true
  reclaimPolicy: Delete

# values-production.yaml (生产覆盖)
replicaCount: 5
storage:
  reclaimPolicy: Retain
  defaultClassReplicaCount: 3

部署时合并 Values:

helm upgrade --install longhorn longhorn/longhorn \
  -f values.yaml \
  -f values-production.yaml \
  --set image.tag=v1.6.1

4.4 依赖管理与子 Chart

当 Chart 需要依赖其他 Chart(如 Longhorn 依赖 csi-attacher、csi-provisioner)时,通过 Chart.yaml 中的 dependencies 字段声明。Helm 会自动下载并管理这些子 Chart。

依赖声明示例(Chart.yaml):

dependencies:
  - name: csi-attacher
    version: "4.4.0"
    repository: "https://kubernetes-csi.github.io/charts"
    condition: csi-attacher.enabled
  - name: csi-provisioner
    version: "3.6.0"
    repository: "https://kubernetes-csi.github.io/charts"
    alias: provisioner

依赖管理常用命令:

命令作用
helm dependency update根据 Chart.yaml 更新 charts/ 目录和 Chart.lock 文件
helm dependency build从 Chart.lock 重建依赖,确保版本锁定
helm dependency list列出当前 Chart 的所有依赖及其状态
⚠️ 注意: 在 Longhorn 的变更门禁场景中,依赖版本锁定(Chart.lock)至关重要。未锁定的依赖可能导致 CI/CD 流水线在不同时间拉取不同版本的子 Chart,引发非预期的变更。务必在提交代码前运行 helm dependency update 并提交 Chart.lock 文件。

4.5 仓库配置与 Chart 发布

Helm 仓库是存储和分发 Chart 的 HTTP 服务器。配置仓库后,可以通过 helm repo add 添加,并通过 helm search 查找 Chart。

仓库操作核心命令:

# 添加 Longhorn 官方仓库
helm repo add longhorn https://charts.longhorn.io

# 更新本地仓库索引
helm repo update

# 搜索特定版本的 Chart
helm search repo longhorn --versions

# 从仓库安装 Chart
helm install my-longhorn longhorn/longhorn --version 1.6.0

仓库配置对比:

仓库类型示例 URL适用场景
官方仓库https://charts.longhorn.io生产环境,稳定发布
OCI 仓库oci://registry-1.docker.io/longhorn容器镜像仓库托管 Chart,支持签名和认证
本地仓库file:///path/to/charts开发测试,离线环境
Git 仓库https://github.com/longhorn/charts.gitCI/CD 流水线,直接从源码拉取
Helm Chart 核心组件与数据流 Helm Chart 核心组件与数据流 values.yaml --set 参数 父 Chart Values Go 模板引擎 templates/*.yaml _helpers.tpl Sprig 函数库 渲染为 Kubernetes 资源 Deployment Service / PVC DaemonSet / CRD 💡 数据流:Values 文件提供配置 → 模板引擎渲染 → 生成最终 Kubernetes 资源 依赖管理通过 charts/ 目录注入子 Chart 的模板和 Values

4.6 综合示例:Longhorn Chart 的 Helm 操作流程

以下是一个完整的 Helm 操作流程,涵盖从仓库配置到部署验证的步骤,适用于 Longhorn 存储变更门禁场景:

# 1. 添加并更新仓库
helm repo add longhorn https://charts.longhorn.io
helm repo update

# 2. 查看可用版本
helm search repo longhorn/longhorn --versions

# 3. 拉取 Chart 到本地(用于审计或离线部署)
helm pull longhorn/longhorn --version 1.6.0 --untar

# 4. 检查依赖是否完整
cd longhorn
helm dependency list

# 5. 自定义 Values 并部署
helm upgrade --install longhorn ./longhorn \
  -f values.yaml \
  -f values-production.yaml \
  --namespace longhorn-system \
  --create-namespace \
  --set persistence.defaultClassReplicaCount=3

# 6. 验证渲染结果(不实际安装)
helm template longhorn ./longhorn \
  -f values.yaml \
  --debug > rendered-output.yaml
🔧 变更门禁集成点: 在 CI/CD 流水线中,helm template --debug 的输出可以与基线版本进行 diff 对比。任何非预期的模板变更(如存储类参数、副本数)都会触发门禁告警,阻止自动部署并启动回滚流程。
Helm 依赖解析与版本锁定流程 Helm 依赖解析与版本锁定流程 Chart.yaml 声明 dependencies helm dep update 解析并下载依赖 Chart.lock 锁定版本哈希 charts/ 目录 存储子 Chart 包 helm dep build 从 lock 重建 🔒 版本锁定最佳实践 始终提交 Chart.lock 到版本控制;CI 中使用 helm dep build 而非 update,确保可复现构建

4.7 常见陷阱与避坑指南

  • Values 覆盖顺序混淆: --set 优先级最高,但会覆盖整个列表或映射。对于复杂结构,优先使用 -f 指定文件。
  • 模板缩进错误: Go 模板的 indent 和 nindent 函数容易用错。推荐使用 {{ include "longhorn.fullname" . | indent 4 }} 保持 YAML 对齐。
  • 依赖循环: Chart A 依赖 B,B 又依赖 A,会导致 helm dependency update 死循环。使用 helm dep list 提前检查。
  • CRD 安装时机: CRD 必须在模板资源之前安装。Helm 会先处理 crds/ 目录,但不会更新已存在的 CRD。版本升级时需手动处理 CRD 变更。
  • 仓库认证: 私有仓库需要配置 helm repo add --username --password 或使用 OCI 仓库的 helm registry login。