4. Helm Chart 基础:Chart 结构、模板引擎、Values 文件、依赖管理
Helm 是 Kubernetes 生态中最成熟的包管理工具,它将一组 Kubernetes 资源清单封装为 Chart,并通过模板引擎实现参数化部署。在《策略即代码》项目中,Rego 规则需要以 ConfigMap 或 Job 的形式注入集群,Helm Chart 正是承载这些规则、实现环境差异化部署的核心载体。理解 Chart 的结构与模板机制,是后续将 Rego 策略与 Helm 集成的前提。
4.1 Chart 目录结构
一个标准的 Helm Chart 遵循固定的目录约定。以下是一个包含 Rego 策略的 Chart 示例结构:
my-policy-chart/
├── Chart.yaml # Chart 元数据(名称、版本、依赖)
├── values.yaml # 默认配置值
├── values.schema.json # (可选)Values 的 JSON Schema 校验
├── charts/ # (可选)依赖的子 Chart
├── templates/ # 模板文件目录
│ ├── _helpers.tpl # 模板辅助函数(命名模板)
│ ├── configmap.yaml # 用于存放 Rego 规则的 ConfigMap
│ ├── job.yaml # 执行 OPA 扫描的 Job
│ ├── rbac.yaml # ServiceAccount / Role / RoleBinding
│ └── tests/ # (可选)Chart 测试模板
│ └── test-connection.yaml
└── README.md # Chart 使用说明
关键目录说明:
templates/目录下的文件都会经过模板引擎渲染,生成最终的 Kubernetes 清单。_helpers.tpl定义可复用的命名模板,通常用于生成标签、名称等公共逻辑。charts/目录存放手动管理的依赖 Chart,与Chart.yaml中的dependencies字段配合使用。
4.2 模板引擎与渲染流程
Helm 使用 Go 模板引擎(text/template)结合 Sprig 函数库,将 values.yaml 中的值注入到模板文件中。渲染流程如下:
模板语法核心包括:
- 值注入:
{{ .Values.rego.rules }}引用values.yaml中的嵌套字段。 - 控制结构:
{{- if .Values.rbac.create }}条件判断,{{- range .Values.policies }}循环遍历。 - 管道与函数:
{{ .Values.name | default "default-policy" | quote }}链式处理。 - 命名模板:在
_helpers.tpl中定义{{- define "myChart.labels" -}},在模板中通过{{ include "myChart.labels" . }}引用。
实战要点: 在 Rego 策略集成场景中,
values.yaml 通常包含 rego.rules 字段,用于存储多段 Rego 代码。模板通过 range 循环将每段规则写入 ConfigMap 的 data 字段,实现策略的动态加载。
4.3 Values 文件与值层级
values.yaml 是 Chart 的默认配置入口。Helm 支持多层级值覆盖机制,优先级从低到高依次为:
| 优先级 | 来源 | 说明 |
|---|---|---|
| 1(最低) | Chart 内建 values.yaml |
Chart 开发者提供的默认值 |
| 2 | 父 Chart 的 values.yaml |
当 Chart 作为依赖被引用时,父 Chart 的值可覆盖子 Chart 默认值 |
| 3 | 用户提供的 -f my-values.yaml |
通过 --values 或 -f 指定的自定义值文件 |
| 4(最高) | --set 命令行参数 |
直接通过 --set key=value 传入的值,优先级最高 |
以下是一个适用于 Rego 策略集成的 values.yaml 示例:
# values.yaml
rego:
enabled: true
rules:
- name: "deny-privileged-containers"
code: |
package kubernetes.admission
deny[msg] {
input.request.object.spec.containers[_].securityContext.privileged == true
msg := "Privileged containers are not allowed"
}
- name: "require-resource-limits"
code: |
package kubernetes.admission
deny[msg] {
not input.request.object.spec.containers[_].resources.limits
msg := "Container must specify resource limits"
}
configMapName: "rego-policies"
rbac:
create: true
serviceAccountName: "opa-sa"
注意: 在
values.yaml 中嵌入多行 Rego 代码时,必须使用 YAML 的块标量(| 或 |+)保留换行符。模板中通过 {{ .code | indent 4 }} 保持缩进正确。
4.4 依赖管理
Helm 支持通过 Chart.yaml 的 dependencies 字段声明对其他 Chart 的依赖。依赖管理机制使得我们可以将 Rego 策略引擎(如 OPA)作为基础 Chart,将自定义策略作为子 Chart 或依赖进行组合。
依赖声明示例:
# Chart.yaml
apiVersion: v2
name: policy-manager
version: 1.0.0
dependencies:
- name: opa
version: "1.5.0"
repository: "https://open-policy-agent.github.io/opa-helm"
condition: opa.enabled
- name: common
version: "2.0.0"
repository: "file://../common-chart"
tags:
- infrastructure
依赖管理常用命令:
| 命令 | 作用 |
|---|---|
helm dependency update |
根据 Chart.yaml 中的依赖声明,下载或更新 charts/ 目录下的依赖 Chart |
helm dependency build |
从 Chart.lock 文件锁定版本,重建依赖(适用于 CI/CD 环境) |
helm dependency list |
列出当前 Chart 的所有依赖及其状态 |
依赖管理最佳实践:
- 使用
condition字段控制依赖是否启用,例如condition: opa.enabled允许用户通过--set opa.enabled=false跳过 OPA 安装。 - 使用
tags对依赖分组,通过--set global.tags=infrastructure批量启用或禁用一组依赖。 - 在 CI/CD 中始终使用
helm dependency build而非update,确保版本锁定。
4.5 本章小结
Helm Chart 的结构化设计为策略即代码提供了标准化的部署框架:
- Chart 结构 明确了策略文件、模板和配置的存放位置。
- 模板引擎 将 Rego 规则从静态 YAML 中解放出来,实现参数化注入。
- Values 文件 提供了多层级覆盖能力,适配开发、测试、生产等不同环境的策略差异。
- 依赖管理 允许将 OPA 引擎与策略规则分离管理,提升复用性和可维护性。