3、Helm Chart项目结构:标准Chart目录结构、templates/NOTES.txt/Chart.yaml/values.yaml的作用

一个规范的 Helm Chart 是 Helm 打包、分发和部署应用的基础单元。理解标准 Chart 目录结构以及核心文件的作用,是编写可维护、可测试 Chart 模板的前提。本章将系统梳理标准目录布局,并深入解析 templates/、NOTES.txt、Chart.yaml 和 values.yaml 四个关键组件的职责与最佳实践。

3.1 标准 Chart 目录结构

Helm 社区推荐的标准 Chart 目录结构如下,每个文件和目录都有明确的语义。创建新 Chart 时,可使用 helm create <chart-name> 命令自动生成此骨架。

my-chart/
├── Chart.yaml          # Chart 元数据(名称、版本、描述等)
├── values.yaml         # 默认配置值
├── values.schema.json  # (可选)values.yaml 的 JSON Schema 校验文件
├── charts/             # 子 Chart 依赖(手动或通过 helm dependency 管理)
├── crds/               # 自定义资源定义(CRD),优先于 templates 安装
├── templates/          # Go 模板文件,渲染后生成 Kubernetes 资源清单
│   ├── NOTES.txt       # 安装成功后的使用提示文本
│   ├── _helpers.tpl    # 模板辅助函数(命名模板)
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── ...
└── README.md           # (可选)Chart 使用说明
关键原则: templates/ 目录下的所有文件都会被 Helm 引擎解析并渲染;非 .yaml、.tpl、.txt 后缀的文件会被忽略。单元测试文件(如 deployment_test.yaml)通常放在 templates/tests/ 子目录中,避免与正式资源混淆。
标准 Helm Chart 目录结构分层图 my-chart/ Chart.yaml values.yaml charts/ crds/ templates/ NOTES.txt _helpers.tpl deployment.yaml service.yaml ... 说明: • templates/ 是核心目录,所有 .yaml/.tpl/.txt 文件都会被渲染。 • charts/ 存放子 Chart 依赖,crds/ 存放 CRD 资源。 • values.schema.json 和 README.md 为可选文件,但推荐生产 Chart 包含。

3.2 核心文件作用详解

3.2.1 Chart.yaml — Chart 的身份证

Chart.yaml 是每个 Chart 必须存在的元数据文件,定义了 Chart 的名称、版本、API 版本、描述、关键字、依赖等信息。Helm 在安装、打包、发布时都会读取此文件。

字段 是否必填 说明 示例
apiVersion 是 Chart API 版本,v2 为当前标准 v2
name 是 Chart 名称,必须符合 DNS 标签规范 my-app
version 是 Chart 语义化版本(SemVer 2) 1.2.3
description 否 Chart 简短描述 A Helm chart for Kubernetes
type 否 Chart 类型:application 或 library application
dependencies 否 子 Chart 依赖列表 见下方代码块
appVersion 否 应用版本号,与 Chart 版本独立 1.0.0
# Chart.yaml 典型示例
apiVersion: v2
name: my-app
description: A Helm chart for deploying my-app on Kubernetes
type: application
version: 1.2.3
appVersion: "1.0.0"
keywords:
  - web
  - microservice
dependencies:
  - name: redis
    version: "17.0.0"
    repository: "https://charts.bitnami.com/bitnami"
    condition: redis.enabled
maintainers:
  - name: DevOps Team
    email: devops@example.com
测试关注点: 单元测试和集成测试中,Chart.yaml 的 version 和 appVersion 字段常被用于生成资源标签(如 app.kubernetes.io/version)。测试应验证这些字段是否正确传递到模板输出中。

3.2.2 values.yaml — 默认配置的单一事实来源

values.yaml 是 Chart 的默认配置值文件,定义了所有可配置参数的默认值。用户在安装或升级时可以通过 --set 或自定义 values 文件覆盖这些值。它是模板渲染的输入数据源。

# values.yaml 典型结构
replicaCount: 3

image:
  repository: nginx
  tag: "1.25.0"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: false
  host: my-app.example.com

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 250m
    memory: 256Mi

nodeSelector: {}
tolerations: []
affinity: {}
设计原则 说明
扁平化优先 避免过度嵌套,通常不超过 3 层,便于 --set 覆盖
默认值合理 默认值应能直接 helm install 成功,无需用户额外配置
类型明确 字符串、数字、布尔值、列表、字典类型清晰,避免隐式转换
注释完整 每个字段上方添加 # 注释,说明用途和可选值
可测试性 为单元测试提供最小化测试值集,避免依赖外部环境

3.2.3 templates/ — 模板渲染引擎

templates/ 目录是 Chart 的核心,存放所有 Go 模板文件。Helm 会将这些文件与 values.yaml 及内置对象(如 .Release、.Chart、.Files)结合,渲染出最终的 Kubernetes 资源清单。

  • 模板文件命名: 通常以资源类型命名,如 deployment.yaml、service.yaml、ingress.yaml。测试文件建议放在 templates/tests/ 子目录。
  • 辅助模板: _helpers.tpl 用于定义可复用的命名模板(define),通过 {{ include "chart-name.labels" . }} 调用。
  • 渲染规则: 所有 .yaml、.tpl、.txt 文件都会被处理;其他后缀文件被忽略。空文件或仅含注释的文件不会产生输出。
{{- /* templates/_helpers.tpl 示例 */ -}}
{{- define "my-app.labels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}

3.2.4 NOTES.txt — 安装后的用户指引

NOTES.txt 是一个特殊的模板文件,在 helm install 或 helm upgrade 成功后,Helm 会将其渲染并输出到终端。它通常用于向用户展示如何访问应用、获取密码、查看状态等操作指引。

# templates/NOTES.txt 示例
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
  http://{{ .Values.ingress.host }}
{{- else }}
  export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ .Chart.Name }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:{{ .Values.service.port }}
{{- end }}
测试注意事项: NOTES.txt 也是模板文件,同样会被渲染。单元测试应覆盖 NOTES.txt 的渲染结果,确保在不同 values 组合下输出正确的指引信息。集成测试中,NOTES.txt 的内容可作为验证部署成功的辅助依据。

3.3 文件职责对比表

文件/目录 核心职责 是否参与渲染 测试验证点
Chart.yaml 定义 Chart 元数据、版本、依赖 是(作为 .Chart 对象) 版本号、依赖条件、类型字段正确传递
values.yaml 提供默认配置值 是(作为 .Values 对象) 默认值完整性、类型正确性、覆盖行为
templates/ 存放 Go 模板,渲染为 K8s 资源 是(核心渲染单元) 模板语法、资源结构、标签/注解、条件逻辑
NOTES.txt 安装成功后的用户提示 是 提示信息正确性、条件分支渲染
charts/ 子 Chart 依赖包 是(子 Chart 独立渲染) 依赖版本、子 Chart 配置合并
crds/ 自定义资源定义 否(直接安装,不经过模板引擎) CRD 语法正确性、集群兼容性
Helm Chart 核心文件数据流与渲染关系 Chart.yaml values.yaml templates/*.yaml NOTES.txt Helm 模板引擎 Go Template + Sprig 渲染 + 校验 K8s 资源清单 终端提示信息 错误/警告日志 数据流说明: Chart.yaml 提供元数据,values.yaml 提供配置值,templates/ 提供模板逻辑,三者经 Helm 引擎渲染后输出 K8s 资源清单和提示信息。

3.4 目录结构对测试的影响

理解标准目录结构后,可以更高效地组织测试文件:

  • 单元测试文件位置: 推荐在 templates/tests/ 下创建 <resource>_test.yaml,使用 helm test 或 helm unittest 插件执行。
  • 测试 values 文件: 在 Chart 根目录创建 ci/ 目录(如 ci/test-values.yaml),用于集成测试的特定配置组合。
  • 依赖管理: 子 Chart 的 values 合并行为需要在集成测试中验证,确保覆盖顺序正确。
  • CRD 测试: crds/ 中的 CRD 不经过模板引擎,需单独使用 kubectl apply --dry-run 或 kubeconform 校验。
最佳实践: 使用 helm create 生成骨架后,立即在 templates/tests/ 下创建至少一个单元测试文件,并编写 ci/ 目录下的集成测试 values 文件。这能确保从项目初始化阶段就具备可测试性。