3. Chart 结构详解:Chart 目录结构、Chart.yaml 文件、values.yaml 文件、templates 目录、charts 目录
Helm Chart 是 Kubernetes 应用的打包格式,其目录结构是 Helm 生态的基石。理解 Chart 的每一层结构,是编写可维护、可复用的部署模板的前提。本章将逐层拆解一个标准 Chart 的骨架,并深入核心文件的作用与约束。
3.1 标准 Chart 目录结构
一个典型的 Helm Chart 目录树如下所示。每个文件和目录都有明确的语义,Helm 在打包(helm package)和安装(helm install)时会严格按此结构解析。
my-chart/
├── Chart.yaml # Chart 元数据(必选)
├── values.yaml # 默认配置值(必选)
├── values.schema.json # values 的 JSON Schema 校验文件(可选)
├── charts/ # 子 Chart 依赖(可选)
│ └── sub-chart-1.0.0.tgz
├── templates/ # 模板文件目录(必选)
│ ├── NOTES.txt # 安装后的使用说明(可选)
│ ├── _helpers.tpl # 模板辅助函数(可选)
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ └── hpa.yaml
├── templates/tests/ # 测试模板(可选)
│ └── test-connection.yaml
├── crds/ # CRD 定义(可选)
│ └── my-crd.yaml
└── .helmignore # 打包时忽略的文件模式(可选)
关键原则:
Chart.yaml、values.yaml、templates/ 是三个必选元素。缺少任意一个,helm lint 都会报错,且无法通过 helm package 打包。
3.2 Chart.yaml:Chart 的身份证
Chart.yaml 是每个 Chart 的元数据文件,Helm 通过它识别 Chart 的名称、版本、类型和依赖关系。以下是一个生产级 Chart.yaml 示例:
apiVersion: v2
name: my-app
description: A production-grade microservice for user management
type: application
version: 1.2.3
appVersion: "2.5.0"
kubeVersion: ">=1.21.0-0"
keywords:
- user
- management
- microservice
home: https://github.com/team/my-app
sources:
- https://github.com/team/my-app
maintainers:
- name: DevOps Team
email: devops@example.com
url: https://devops.example.com
icon: https://example.com/icon.svg
dependencies:
- name: redis
version: ">=16.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
tags:
- cache
- name: postgresql
version: "~12.1.0"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
tags:
- database
| 字段 | 必选 | 说明 | 典型值 / 约束 |
|---|---|---|---|
apiVersion |
是 | Chart API 版本,v2 为 Helm 3+ 标准 | v2 |
name |
是 | Chart 名称,必须符合 DNS-1123 子域名规则 | my-app |
version |
是 | Chart 语义化版本,每次变更需递增 | 1.2.3 |
type |
否 | Chart 类型:application 或 library |
application |
appVersion |
否 | 所部署应用的版本,与 Chart 版本独立 | "2.5.0" |
kubeVersion |
否 | 兼容的 Kubernetes 版本约束 | >=1.21.0-0 |
dependencies |
否 | 子 Chart 依赖列表,支持版本范围与条件 | 见上例 |
版本管理陷阱:
version 与 appVersion 是两个独立字段。前者标识 Chart 包本身的版本,后者标识被部署的应用版本。CI/CD 流水线中,通常每次构建都递增 version,而 appVersion 仅在应用代码版本变更时更新。
3.3 values.yaml:配置的默认值仓库
values.yaml 是 Chart 的配置入口,定义了所有模板变量在无覆盖时的默认值。良好的 values.yaml 应当结构清晰、注释完整,并遵循层级命名规范。
# 全局配置
global:
environment: production
imageRegistry: docker.io
# 应用副本与镜像配置
replicaCount: 3
image:
repository: my-app
tag: latest
pullPolicy: IfNotPresent
# 服务配置
service:
type: ClusterIP
port: 8080
targetPort: 8080
# 资源限制
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
# 自动扩缩容
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 80
# 依赖子 Chart 开关
redis:
enabled: true
architecture: standalone
postgresql:
enabled: false
最佳实践: 使用
values.schema.json 对 values.yaml 进行 JSON Schema 校验,可以在 helm install 或 helm upgrade 时提前捕获类型错误和缺失字段,避免运行时故障。
3.4 templates 目录:Kubernetes 清单的模板引擎
templates/ 目录存放 Go 模板文件,Helm 在渲染时会将 values.yaml 中的值注入这些模板,生成最终的 Kubernetes 资源清单。模板文件使用 .yaml 或 .tpl 扩展名,Helm 会递归处理该目录下的所有文件。
一个典型的 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.targetPort }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
| 模板语法 | 作用 | 示例 |
|---|---|---|
{{ .Values.xxx }} |
引用 values.yaml 中的值 |
{{ .Values.replicaCount }} |
{{ include "chart.name" . }} |
调用 _helpers.tpl 中定义的命名模板 |
{{ include "my-chart.labels" . }} |
{{- ... | nindent N }} |
管道操作 + 缩进控制,保持 YAML 格式 | {{- toYaml .Values.resources | nindent 12 }} |
{{ .Chart.Name }} |
引用 Chart.yaml 中的内置对象 |
{{ .Chart.Version }} |
{{ .Release.Name }} |
引用 Helm Release 名称 | {{ .Release.Namespace }} |
模板调试技巧: 使用
helm template . --debug 可以在不实际安装的情况下预览渲染后的 YAML 清单,是排查模板语法错误的利器。
3.5 charts 目录:子 Chart 依赖管理
charts/ 目录用于存放子 Chart 的打包文件(.tgz),这些子 Chart 通过 Chart.yaml 中的 dependencies 字段声明。Helm 提供了两种依赖管理方式:
- 手动管理: 将子 Chart 的
.tgz文件直接放入charts/目录。 - 自动管理: 使用
helm dependency update命令,Helm 会根据Chart.yaml中的dependencies自动下载并填充charts/目录,同时生成Chart.lock文件锁定版本。
依赖声明示例(Chart.yaml 中的 dependencies 字段):
dependencies:
- name: redis
version: ">=16.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: redis.enabled
tags:
- cache
- name: postgresql
version: "~12.1.0"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
tags:
- database
| 依赖字段 | 说明 | 示例 |
|---|---|---|
name |
子 Chart 名称,必须与子 Chart 的 Chart.yaml 中 name 一致 |
redis |
version |
版本范围,支持语义化版本约束 | >=16.0.0、~12.1.0 |
repository |
Chart 仓库 URL,或 @alias 引用本地仓库别名 |
https://charts.bitnami.com/bitnami |
condition |
条件控制,值为 values.yaml 中的布尔路径,为 false 时跳过该依赖 |
redis.enabled |
tags |
标签列表,可通过 --set tags.cache=false 批量禁用一组依赖 |
[cache] |
3.6 其他关键文件与目录
除了上述核心元素,一个完整的 Chart 还可能包含以下可选文件:
_helpers.tpl:存放可复用的命名模板(named templates),通过{{ include "templateName" . }}在多个模板文件中调用,避免重复代码。NOTES.txt:安装成功后打印的使用说明,支持模板语法,可动态显示 Release 名称、访问地址等信息。crds/:存放 CustomResourceDefinition(CRD)定义,Helm 会在安装时优先应用这些 CRD,且不会在helm uninstall时自动删除。.helmignore:类似.gitignore,在helm package时忽略指定文件或目录,避免将敏感信息或本地配置打包进 Chart。templates/tests/:存放测试 Pod 模板,通过helm test命令运行,用于验证部署后的服务是否正常。
生产建议: 在 CI/CD 流水线中,每次提交代码后应执行
helm lint 和 helm template --validate 进行静态校验,确保 Chart 结构正确且模板语法无误,避免将错误的 Chart 部署到集群。