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 中的值注入到模板文件中。渲染流程如下:

Helm 模板渲染流程 values.yaml (用户配置值) 模板文件 (templates/*.yaml) Go 模板引擎 + Sprig 函数库 Kubernetes 清单 (渲染后的 YAML) helm install / helm template 命令触发渲染,输出最终 YAML 并提交给 Kubernetes API

模板语法核心包括:

  • 值注入:{{ .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 的所有依赖及其状态
Helm 依赖管理架构 policy-manager 主 Chart(编排层) opa OPA 引擎 Chart rego-policies 策略规则 Chart common 公共资源 Chart 依赖 Chart 通过 condition 和 tags 实现条件部署,支持全局开关
依赖管理最佳实践:
  • 使用 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 引擎与策略规则分离管理,提升复用性和可维护性。