3、Chart结构详解:Chart目录结构、Chart.yaml文件详解、values.yaml文件的作用、templates目录规范
一个标准的 Helm Chart 是 Helm 应用打包、分发和部署的核心单元。理解其目录结构、核心元数据文件、参数化入口以及模板渲染规范,是编写可维护、可复用的 Chart 的基础。本章将逐一拆解这些关键组成部分。
3.1 Chart 标准目录结构
Helm 对 Chart 的目录结构有明确的约定。使用 helm create 命令生成的脚手架即遵循此标准。以下是典型结构及其各目录/文件的作用:
| 路径/文件 | 是否必需 | 作用说明 |
|---|---|---|
mychart/ |
是 | Chart 的根目录,名称通常与 Chart 名称一致 |
Chart.yaml |
是 | Chart 的元数据文件,包含名称、版本、描述等核心信息 |
values.yaml |
是 | 默认的配置参数文件,是 Chart 参数化配置的入口 |
templates/ |
是 | 存放 Go 模板文件,Helm 会渲染此目录下的所有 .yaml、.tpl、.txt 文件 |
charts/ |
否 | 存放子 Chart(依赖)的目录,每个子 Chart 也是一个完整的 Chart 包 |
crds/ |
否 | 存放自定义资源定义(CRD)的 YAML 文件,Helm 会在安装时优先安装这些 CRD |
templates/NOTES.txt |
否 | 安装成功后向用户显示的帮助信息模板 |
templates/_helpers.tpl |
否 | 存放可复用的模板子模板(命名模板),供其他模板文件调用 |
templates/tests/ |
否 | 存放用于测试 Chart 安装是否成功的 Pod 模板 |
.helmignore |
否 | 类似于 .gitignore,用于在打包时排除不需要的文件 |
最佳实践: 保持目录结构简洁。对于简单应用,仅保留
Chart.yaml、values.yaml 和 templates/ 三个核心组件即可。复杂的依赖关系应通过 charts/ 或 dependencies 字段管理。
3.2 Chart.yaml 文件详解
Chart.yaml 是 Chart 的“身份证”,包含了 Helm 用于识别、管理和发布 Chart 的所有元数据。以下是一个典型的 Chart.yaml 文件及其字段说明:
apiVersion: v2 # Chart API 版本,v2 表示 Helm 3+
name: mychart # Chart 名称,必须与目录名一致
version: 0.1.0 # Chart 版本号,遵循 SemVer 2 规范
appVersion: "1.16.0" # 应用版本号,用于标识打包的应用版本
description: A Helm chart for Kubernetes
type: application # Chart 类型:application 或 library
keywords:
- web
- nginx
home: https://example.com
sources:
- https://github.com/example/mychart
maintainers:
- name: John Doe
email: john@example.com
url: https://john.example.com
icon: https://example.com/icon.png
dependencies:
- name: redis
version: ">=15.0.0"
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
tags:
- cache
annotations:
category: Infrastructure
| 字段 | 是否必需 | 说明 |
|---|---|---|
apiVersion |
是 | Chart API 版本。Helm 3 必须使用 v2,Helm 2 使用 v1 |
name |
是 | Chart 名称,必须与 Chart 目录名一致,且只能包含小写字母、数字和连字符 |
version |
是 | Chart 的语义化版本号,每次 Chart 内容变更都需要递增 |
appVersion |
否 | 被打包的应用版本号,与 Chart 版本独立,用于标识应用的实际版本 |
kubeVersion |
否 | 兼容的 Kubernetes 版本范围,如 >=1.19.0-0 |
description |
否 | Chart 的简短描述,会显示在 helm search 结果中 |
type |
否 | Chart 类型:application(默认,可部署)或 library(仅提供工具函数,不可独立部署) |
dependencies |
否 | 定义 Chart 的依赖列表,Helm 会自动解析并下载 |
annotations |
否 | 自定义元数据,可用于扩展 Chart 的语义,如分类、标签等 |
版本管理要点:
- Chart 版本(version) 与 应用版本(appVersion) 是独立的。修改模板或 values 时递增 Chart 版本;应用代码升级时递增 appVersion。
- 依赖管理中的
condition和tags字段用于控制子 Chart 的启用/禁用,需与父 Chart 的 values.yaml 配合使用。
3.3 values.yaml 文件的作用
values.yaml 是 Chart 参数化配置的“总开关”。它定义了所有可配置参数的默认值,模板文件通过 .Values 对象引用这些值。其核心作用包括:
- 提供默认配置:为所有模板变量提供合理的默认值,确保 Chart 可以“开箱即用”。
- 分离配置与模板:将环境相关的配置(如副本数、镜像标签、资源限制)从模板逻辑中剥离,实现配置与代码的解耦。
- 支持多环境覆盖:通过
helm install -f或--set参数,用户可以在不修改 Chart 的情况下覆盖任意默认值,实现开发、测试、生产环境的差异化部署。 - 作为文档入口:结构清晰、注释完整的 values.yaml 本身就是一份优秀的配置文档。
# values.yaml 示例
replicaCount: 3
image:
repository: nginx
tag: "1.25.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: false
host: myapp.example.com
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
# 用于条件控制的标志
redis:
enabled: true
最佳实践:
- 使用层级结构组织配置,避免扁平化命名(如
image.repository优于imageRepository)。 - 为每个字段添加注释,说明其用途、可选值和默认行为。
- 将环境特定的配置(如域名、证书)放在顶层,便于用户快速定位和覆盖。
3.4 templates 目录规范
templates/ 目录是 Chart 的核心逻辑所在。Helm 会渲染该目录下所有 .yaml、.tpl、.txt 文件,并将渲染结果合并后提交给 Kubernetes。遵循以下规范可以提升模板的可读性和可维护性:
| 规范项 | 说明 |
|---|---|
| 文件命名 | 使用 Kubernetes 资源类型作为文件名前缀,如 deployment.yaml、service.yaml、ingress.yaml。每个文件只定义一个资源。 |
| 资源命名 | 使用 {{ include "chart.fullname" . }} 等命名模板生成统一的资源名称,避免硬编码。 |
| 标签规范 | 所有资源必须包含 app.kubernetes.io/name、app.kubernetes.io/instance、app.kubernetes.io/managed-by: Helm 等推荐标签。 |
| 模板复用 | 将可复用的模板片段(如标签、名称、注解)定义在 _helpers.tpl 中,通过 include 或 template 调用。 |
| 条件控制 | 使用 if-else、with、range 等控制结构处理可选资源(如 Ingress、ServiceMonitor)和列表。 |
| 缩进与格式 | 模板语法与 YAML 缩进严格对齐。使用 nindent 和 indent 函数控制缩进层级,避免 YAML 解析错误。 |
| NOTES.txt | 提供安装后的使用说明,如访问地址、默认密码获取方式等,提升用户体验。 |
3.5 模板文件编写示例
以下是一个遵循上述规范的 deployment.yaml 模板示例,展示了如何引用 values、使用命名模板以及处理条件逻辑:
{{- include "mychart.labels" . | nindent 0 }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "mychart.fullname" . }}
labels:
{{- include "mychart.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "mychart.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "mychart.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.port }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
关键函数说明:
include:调用命名模板并返回字符串,推荐用于标签和名称生成。nindent:在字符串前添加换行符并缩进指定空格数,是保持 YAML 格式正确的核心函数。toYaml:将 Go 数据结构转换为 YAML 字符串,常用于渲染 resources、nodeSelector 等复杂配置。default:为可能为空的字段提供默认值,如{{ .Values.image.tag | default "latest" }}。
3.6 本章小结
理解 Chart 的结构是编写高质量 Helm Chart 的第一步。核心要点包括:
- 三大核心组件:
Chart.yaml(元数据)、values.yaml(默认配置)、templates/(模板逻辑)缺一不可。 - 参数化设计:所有环境相关的值都应通过
.Values引用,避免在模板中硬编码。 - 模板规范:遵循文件命名、资源命名、标签规范和复用策略,确保 Chart 的可读性和可维护性。
- 配置覆盖优先级:
--set>-f自定义文件 >values.yaml默认值,理解此优先级有助于调试多环境部署问题。