4. Chart 目录结构:核心文件与规范
一个标准的 Helm Chart 并非随意放置文件,而是遵循一套严格的目录约定。理解这套结构是创建、维护和共享 Chart 的基础。本章将逐一剖析 Chart 根目录下每个关键文件与目录的作用、规范及最佳实践。
核心原则:Helm 通过约定优于配置的方式,在
chart/ 目录中查找特定名称的文件来构建应用模板。任何不符合约定的文件或目录都可能被忽略或导致渲染失败。
4.1 Chart 顶层目录全景
一个典型的 Chart 项目结构如下所示。你可以通过 helm create my-chart 命令快速生成此骨架。
my-chart/
├── Chart.yaml # Chart 元数据定义(必需)
├── values.yaml # 默认配置值(必需)
├── charts/ # 子 Chart 依赖目录(可选)
├── templates/ # 模板文件目录(必需)
│ ├── NOTES.txt # 安装后提示信息(可选)
│ ├── _helpers.tpl # 模板辅助函数(可选)
│ ├── deployment.yaml
│ ├── service.yaml
│ └── ...
└── .helmignore # 打包时忽略的文件列表(可选)
4.2 Chart.yaml:Chart 的身份证
Chart.yaml 是每个 Chart 的必需文件,它定义了 Chart 的元数据。Helm 通过此文件识别 Chart 的名称、版本、描述等信息。
核心字段规范
| 字段 | 是否必需 | 类型 | 说明与规范 |
|---|---|---|---|
apiVersion |
是 | string | Chart API 版本。v2 用于 Helm 3+,v1 用于 Helm 2(已弃用)。 |
name |
是 | string | Chart 名称,必须符合 DNS-1123 子域名规范(小写字母、数字、连字符)。 |
version |
是 | string | Chart 版本号,必须遵循 SemVer 2 规范,如 1.2.3。 |
description |
否 | string | Chart 的简短描述,用于在仓库中展示。 |
type |
否 | string | Chart 类型:application(默认)或 library。 |
dependencies |
否 | list | 定义 Chart 依赖的子 Chart 列表。 |
appVersion |
否 | string | 所包含应用的版本号,与 Chart 版本独立。 |
kubeVersion |
否 | string | 兼容的 Kubernetes 版本范围,如 >=1.19.0-0。 |
最佳实践:始终显式声明
apiVersion: v2。每次发布新版本时,务必递增 version 字段,这是 Helm 仓库索引和升级的核心依据。
# 一个标准的 Chart.yaml 示例
apiVersion: v2
name: my-web-app
description: A Helm chart for deploying a web application on Kubernetes
type: application
version: 0.1.0
appVersion: "1.16.0"
kubeVersion: ">=1.19.0-0"
dependencies:
- name: redis
version: "17.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
4.3 values.yaml:配置的默认值
values.yaml 是 Chart 的默认配置入口。它定义了模板中使用的所有可配置变量的默认值。用户可以通过 --values 或 --set 覆盖这些值。
文件规范
- YAML 格式:必须使用合法的 YAML 语法,支持层级嵌套。
- 自文档化:每个字段应附带注释,说明其用途和默认值。
- 扁平化优先:避免过深的嵌套(超过 3 层),以提高可读性。
- 类型明确:字符串、数字、布尔值、列表、字典需清晰区分。
# values.yaml 示例
replicaCount: 3
image:
repository: nginx
tag: latest
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
避坑指南:不要在
values.yaml 中硬编码敏感信息(如密码、密钥)。应使用 --set 或外部 Secret 管理工具注入。Helm 不会对 values 文件内容进行加密。
4.4 templates/:Kubernetes 资源模板
templates/ 目录存放所有 Go 模板文件,Helm 会将这些文件与 values 结合渲染成最终的 Kubernetes 资源清单。此目录是 Chart 的核心逻辑所在。
目录规范
- 文件扩展名:模板文件通常以
.yaml、.tpl或.txt结尾。Helm 会处理所有非_开头的文件。 - 命名约定:按 Kubernetes 资源类型命名,如
deployment.yaml、service.yaml、hpa.yaml。 - 下划线前缀:以
_开头的文件(如_helpers.tpl)被视为辅助文件,不会直接生成 Kubernetes 资源,但可以被其他模板引用。 - 模板语法:使用 Go 模板语法
{{ .Values.key }}引用 values 中的值。
# templates/deployment.yaml 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "my-chart.fullname" . }}
labels:
{{- include "my-chart.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "my-chart.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "my-chart.selectorLabels" . | nindent 8 }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.port }}
4.5 charts/:子 Chart 依赖目录
charts/ 目录用于存放 Chart 的依赖子 Chart。这些子 Chart 可以是手动放置的 .tgz 包,也可以是通过 helm dependency update 自动下载的。
工作机制
- 依赖声明:在
Chart.yaml的dependencies字段中声明依赖。 - 自动管理:运行
helm dependency update会根据声明下载子 Chart 到charts/目录。 - 本地覆盖:你也可以手动将子 Chart 的
.tgz文件或解压后的目录放入此目录。 - 作用域:子 Chart 拥有独立的
values.yaml,父 Chart 可以通过父键.子键的方式传递值。
提示:对于复杂的微服务架构,建议将公共组件(如 Redis、MySQL)作为子 Chart 依赖,而不是在父 Chart 中重复编写模板。这能显著提升复用性和维护性。
4.6 templates/NOTES.txt:安装后的使用说明
NOTES.txt 是一个特殊的模板文件,它在 helm install 或 helm upgrade 成功后,会将其内容打印到终端。它通常用于向用户展示如何访问应用、获取密码或执行后续操作。
规范与示例
- 纯文本模板:支持 Go 模板语法,可以引用
.Values、.Release等内置对象。 - 用户友好:内容应简洁、直接,提供可执行的命令。
- 可选文件:如果不需要,可以完全省略此文件。
# 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={{ include "my-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 }}
4.7 templates/_helpers.tpl:模板辅助函数
_helpers.tpl 是 Chart 中最重要的辅助文件。它用于定义可复用的模板片段(通常称为“命名模板”),避免在多个资源文件中重复相同的逻辑。
核心作用
- 定义标签:统一生成
app.kubernetes.io/name、app.kubernetes.io/instance等标准标签。 - 生成名称:创建符合 Kubernetes 命名规范的资源名称。
- 封装逻辑:将复杂的条件判断或字符串处理逻辑封装成模板函数。
# templates/_helpers.tpl 示例
{{- define "my-chart.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- define "my-chart.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{- define "my-chart.labels" -}}
helm.sh/chart: {{ include "my-chart.name" . }}-{{ .Chart.Version | replace "+" "_" }}
{{ include "my-chart.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{- define "my-chart.selectorLabels" -}}
app.kubernetes.io/name: {{ include "my-chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
4.8 文件规范速查表
| 文件/目录 | 必需性 | 核心作用 | 常见错误 |
|---|---|---|---|
Chart.yaml |
必需 | 定义 Chart 元数据、版本、依赖 | 版本号未遵循 SemVer;apiVersion 使用 v1 |
values.yaml |
必需 | 提供模板的默认配置值 | YAML 缩进错误;未注释导致用户困惑 |
templates/ |
必需 | 存放 Kubernetes 资源模板 | 模板语法错误;未使用命名空间隔离 |
charts/ |
可选 | 存放子 Chart 依赖 | 依赖版本与 Chart.yaml 不一致 |
NOTES.txt |
可选 | 安装后打印使用说明 | 模板引用错误导致渲染失败 |
_helpers.tpl |
强烈推荐 | 定义可复用的命名模板 | 模板名称冲突;未使用 include 正确引用 |
总结:一个结构清晰的 Chart 目录是 Helm 落地的基石。
Chart.yaml 是身份证明,values.yaml 是配置中心,templates/ 是逻辑引擎,_helpers.tpl 是复用利器,charts/ 是依赖管理,NOTES.txt 是用户体验。掌握每个文件的作用与规范,你就能构建出专业、可维护的 Helm Chart。