3. Helm 基础回顾:Chart 结构、模板引擎、Values 与依赖管理
在深入 OPA 策略与 Helm 集成之前,必须牢固掌握 Helm 的核心基础。Helm 是 Kubernetes 的包管理工具,它将应用的所有 Kubernetes 资源定义、配置参数和部署逻辑打包为一个标准化的 Chart。本章将系统回顾 Chart 的目录结构、模板引擎的工作机制、Values 的传递与覆盖,以及依赖管理的最佳实践。
3.1 Chart 标准目录结构
一个标准的 Helm Chart 遵循固定的目录布局,每个文件和文件夹都有明确的职责。理解这一结构是编写可维护 Chart 的前提。
| 路径 / 文件 | 必需 | 说明 |
|---|---|---|
Chart.yaml |
是 | Chart 的元数据文件,包含名称、版本、API 版本、描述等。 |
values.yaml |
是 | 默认配置值文件,模板引擎从这里读取变量。 |
templates/ |
是 | 存放 Go 模板文件,渲染后生成 Kubernetes 资源清单。 |
charts/ |
否 | 存放子 Chart(依赖 Chart)的压缩包或目录。 |
crds/ |
否 | 自定义资源定义(CRD),在模板渲染前安装。 |
README.md |
否 | Chart 的使用说明文档。 |
.helmignore |
否 | 打包时忽略的文件模式列表,类似 .gitignore。 |
关键原则:
templates/ 目录下的所有文件都会被 Helm 模板引擎处理。非 .yaml 或 .tpl 文件会被原样复制,但通常建议只放置模板文件。
3.2 模板引擎核心机制
Helm 使用 Go 的 text/template 包作为模板引擎,并扩展了 sprig 函数库。模板引擎将 templates/ 中的文件与 values.yaml 及用户提供的值合并,生成最终的 Kubernetes 清单。
3.2.1 模板语法速览
- 取值:
{{ .Values.replicaCount }}— 从 Values 对象中读取replicaCount。 - 内置对象:
.Values、.Release(发布信息)、.Chart(Chart 元数据)、.Files(文件访问)、.Capabilities(集群能力)。 - 控制结构:
{{- if .Values.service.enabled -}}…{{- end -}},{{- range .Values.containers -}}…{{- end -}}。 - 管道与函数:
{{ .Values.image.tag | default "latest" | quote }}— 使用default和quote函数。 - 命名模板: 在
templates/_helpers.tpl中定义,使用{{- define "myapp.labels" -}},调用时使用{{ include "myapp.labels" . }}。
3.2.2 模板渲染流程
调试技巧: 使用
helm template . 在本地渲染模板并输出 YAML,无需实际安装。使用 helm lint . 检查 Chart 语法和最佳实践。
3.3 Values 的层级与覆盖策略
Values 是 Helm 配置的核心。理解其层级结构和覆盖顺序,对于在多环境(开发、测试、生产)中复用同一 Chart 至关重要。
3.3.1 Values 来源与优先级(从低到高)
- Chart 内
values.yaml— 默认值,优先级最低。 - 父 Chart 的
values.yaml— 当 Chart 作为子 Chart 被依赖时,父 Chart 的值可以覆盖子 Chart 的默认值。 - 用户提供的
-f/--values文件 — 可以指定多个文件,后指定的文件优先级更高。 - 命令行
--set参数 — 直接传递键值对,优先级最高。
3.3.2 全局 Values 与子 Chart 值传递
当 Chart 包含子 Chart 时,可以通过 global 字段共享全局配置:
# 父 Chart 的 values.yaml
global:
registry: "my-registry.cn"
environment: "production"
# 子 Chart 模板中通过 .Values.global.registry 访问
注意: 子 Chart 默认无法直接访问父 Chart 的非 global 值。必须显式通过
global 或使用 --set 的层级语法(如 --set subchart.key=value)来传递。
3.4 依赖管理
Helm 支持通过 Chart.yaml 中的 dependencies 字段声明对其他 Chart 的依赖。依赖管理使得复杂应用可以拆分为多个可复用的组件。
3.4.1 声明依赖
# Chart.yaml
dependencies:
- name: postgresql
version: "12.1.0"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled # 条件控制,当 postgresql.enabled 为 true 时安装
tags:
- database
- name: redis
version: "17.0.0"
repository: "https://charts.bitnami.com/bitnami"
tags:
- cache
3.4.2 依赖管理命令
| 命令 | 作用 |
|---|---|
helm dependency update |
根据 Chart.yaml 中的依赖声明,下载 Chart 包到 charts/ 目录,并生成 Chart.lock 锁定版本。 |
helm dependency build |
基于 Chart.lock 文件重新下载依赖,确保可复现的构建。 |
helm dependency list |
列出当前 Chart 的所有依赖及其状态。 |
3.4.3 子 Chart 的 Values 覆盖
在父 Chart 的 values.yaml 中,可以通过与子 Chart 同名的键来覆盖子 Chart 的默认值:
# 父 Chart values.yaml
postgresql:
image:
tag: "14.5"
auth:
database: "myapp"
username: "appuser"
redis:
architecture: "standalone"
auth:
enabled: false
最佳实践: 始终使用
helm dependency update 生成 Chart.lock 文件,并将其纳入版本控制。这可以确保团队和 CI/CD 流水线使用完全相同的依赖版本,避免“在我机器上能跑”的问题。
3.5 本章小结
Helm 的 Chart 结构、模板引擎、Values 层级和依赖管理共同构成了云原生应用打包与部署的基础。掌握这些概念后,你将能够设计出高度可配置、可复用的 Helm Chart。在下一阶段,我们将在此基础上引入 OPA 策略,在模板渲染和发布执行的关键节点注入合规校验,实现自动化治理。