4. Helm Chart 基础回顾:Chart 结构、模板引擎、Values 文件管理、依赖管理与子 Chart
Helm 是 Kubernetes 生态中事实上的包管理标准。一个 Helm Chart 本质上是一个预配置的 Kubernetes 资源模板集合,通过参数化实现环境间复用。本节从四个核心维度系统回顾 Chart 的基础知识,为后续跨集群调度与安全审计奠定技术基础。
4.1 Chart 目录结构与核心文件
一个标准 Chart 遵循固定目录布局,Helm CLI 通过该结构识别元数据、模板、依赖和资源文件。下表列出核心文件及其职责:
| 文件/目录 | 必需 | 说明 |
|---|---|---|
Chart.yaml |
是 | Chart 元数据:名称、版本、API 版本、描述、关键字等 |
values.yaml |
是 | 默认配置值,模板引擎的输入数据源 |
templates/ |
是 | Go 模板文件目录,渲染后生成 Kubernetes 清单 |
charts/ |
否 | 子 Chart 或依赖 Chart 的打包文件(.tgz)存放目录 |
crds/ |
否 | 自定义资源定义(CRD),在模板渲染前安装 |
templates/NOTES.txt |
否 | 安装成功后输出的使用说明文本 |
templates/_helpers.tpl |
否 | 模板命名片段定义,供其他模板复用 |
安全审计要点: 在变更门禁场景中,
Chart.yaml 中的 apiVersion 字段必须为 v2(Helm 3+),禁止使用已废弃的 v1。同时需检查 templates/ 目录下是否存在非 Kubernetes 资源文件(如 shell 脚本、敏感配置文件),防止模板注入风险。
4.2 模板引擎(Go Template)核心机制
Helm 使用 Go 标准库 text/template 作为模板引擎,并扩展了 Sprig 函数库(超过 70 个字符串、数学、列表、字典操作函数)。模板引擎将 values.yaml 中的值注入到 templates/ 目录下的模板文件中,最终生成完整的 Kubernetes 清单。
4.2.1 基本语法与数据注入
# values.yaml
replicaCount: 3
image:
repository: nginx
tag: "1.25"
service:
port: 80
# templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-nginx
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Chart.Name }}
template:
metadata:
labels:
app: {{ .Chart.Name }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: {{ .Values.service.port }}
内置对象速查:
.Values 指向 values.yaml 及用户传入的自定义值;.Release 包含 Release 名称、命名空间、版本号等元数据;.Chart 提供 Chart.yaml 中的字段;.Files 允许访问 Chart 内的非模板文件。
4.2.2 流程控制与函数
模板引擎支持 if/else、range(循环)、with(作用域切换)等控制结构。以下示例展示条件判断与默认值函数:
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ .Release.Name }}-ingress
spec:
rules:
- host: {{ .Values.ingress.host | default "example.com" }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ .Release.Name }}-service
port:
number: {{ .Values.service.port }}
{{- end }}
安全审计红线: 模板中禁止直接使用
tpl 函数渲染用户输入字符串,防止模板注入攻击。所有用户提供的值必须经过 quote、squote 或 toYaml 等安全函数转义。在变更门禁中,应扫描模板文件中的 tpl、include 调用链,确保无未过滤的外部输入。
4.3 Values 文件管理与优先级
Helm 支持多层 Values 覆盖机制,理解优先级顺序对跨集群配置管理至关重要。以下为完整的 Values 优先级链(从低到高):
- Chart 内置
values.yaml—— 默认值,最低优先级 - 父 Chart 的
values.yaml—— 当 Chart 作为子 Chart 被引用时,父 Chart 的值可覆盖子 Chart 默认值 helm install -f或helm upgrade -f指定的外部 YAML 文件 —— 可指定多个文件,后出现的文件优先级更高--set命令行参数 —— 覆盖单个键值对,支持key=value和 JSON 路径语法--set-string命令行参数 —— 强制将值视为字符串,避免自动类型推断
| 场景 | 命令示例 | 优先级说明 |
|---|---|---|
| 仅使用默认值 | helm install myapp ./mychart |
仅加载 values.yaml |
| 覆盖单个值 | --set image.tag=1.26 |
覆盖 values.yaml 中的 image.tag |
| 多环境配置 | -f prod-values.yaml -f region-override.yaml |
后者覆盖前者,最终合并结果覆盖默认值 |
| 全局值传递 | --set global.cluster=prod-eu |
全局值可被子 Chart 通过 .Values.global 访问 |
跨集群调度实践: 在变更门禁审计中,建议将集群特定配置(如集群名称、区域、节点池标签)放入独立的
cluster-values.yaml 文件,并通过 -f 参数注入。审计规则应检查是否所有 --set 参数都对应 values.yaml 中已声明的键,防止未预期的配置漂移。
4.4 依赖管理与子 Chart
Helm 通过 Chart.yaml 中的 dependencies 字段声明子 Chart 依赖。依赖管理支持版本约束、仓库别名、条件启用等高级特性。
4.4.1 依赖声明与版本约束
# Chart.yaml
apiVersion: v2
name: myapp
version: 1.0.0
dependencies:
- name: redis
version: ">=17.0.0 < 18.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
alias: cache
- name: postgresql
version: "12.x"
repository: "https://charts.bitnami.com/bitnami"
tags:
- database
- production
依赖管理常用命令:
helm dependency update—— 根据Chart.yaml下载依赖到charts/目录并生成Chart.lock锁定文件helm dependency build—— 使用Chart.lock中的精确版本重建依赖,确保可复现helm dependency list—— 显示当前依赖状态(已下载、缺失、版本不匹配)
4.4.2 子 Chart 的值传递与作用域
子 Chart 的 Values 通过父 Chart 的 values.yaml 中与子 Chart 同名的键传递。以下示例展示如何为 redis 子 Chart 传递配置:
# 父 Chart 的 values.yaml
redis:
enabled: true
architecture: standalone
auth:
enabled: false
master:
persistence:
enabled: false
# 子 Chart 内部通过 .Values.architecture 访问上述值
全局值(global)机制: 所有子 Chart 均可通过
.Values.global 访问父 Chart 中 global 键下的值。该机制适用于跨子 Chart 共享的配置,如全局集群名称、公共标签、镜像仓库地址等。在安全审计中,应检查 global 值是否被意外覆盖或泄露。
4.5 安全审计视角下的 Chart 基础检查清单
在变更门禁流水线中,对 Helm Chart 的基础审查应包含以下维度:
| 检查项 | 审计标准 | 风险等级 |
|---|---|---|
| Chart.yaml API 版本 | 必须为 v2,禁止 v1 |
高 |
模板中 tpl 函数使用 |
禁止直接渲染用户输入;必须经过 quote 或白名单校验 |
严重 |
| Values 文件敏感信息 | 密码、密钥、 必须通过 --set 或外部 Secret 管理,禁止硬编码 |
高 |
| 依赖版本锁定 | 必须存在 Chart.lock 且与 Chart.yaml 中的依赖声明一致 |
中 |
| 子 Chart 条件启用 | 使用 condition 字段控制子 Chart 启用,避免空依赖安装 |
低 |
| 全局值污染 | global 键下的值不应被子 Chart 意外覆盖,建议使用唯一前缀 |
中 |
变更门禁阻断规则: 当检测到模板中包含
tpl .Values.* 且未使用 quote 或 squote 包裹时,流水线应直接阻断并返回安全告警。同时,Chart.lock 缺失或与 Chart.yaml 版本不匹配时,应触发警告但允许人工审批通过。