3. Chart 结构详解
Helm Chart 是 Kubernetes 应用的打包格式,其目录结构、元数据文件、模板引擎和依赖管理共同构成了 Helm 的资源模型基础。理解 Chart 的每一层结构,是编写可维护、可参数化 Helm 包的前提。
3.1 标准 Chart 目录结构
一个标准的 Helm Chart 遵循以下目录布局。每个文件和目录都有明确的职责:
| 路径 / 文件 | 必需 | 说明 |
|---|---|---|
mychart/ |
是 | Chart 根目录,名称与 Chart 名称一致 |
Chart.yaml |
是 | Chart 元数据文件,包含名称、版本、描述等 |
values.yaml |
是 | 默认配置值文件,定义所有可参数化的变量 |
templates/ |
是 | Go 模板文件目录,渲染后生成 Kubernetes 资源清单 |
charts/ |
否 | 子 Chart 依赖目录,存放被依赖的 Chart 包 |
crds/ |
否 | 自定义资源定义(CRD)目录,优先于模板安装 |
README.md |
否 | Chart 使用说明文档 |
.helmignore |
否 | 打包时忽略的文件模式列表,类似 .gitignore |
最佳实践:即使
charts/ 和 crds/ 不是必需目录,但任何生产级 Chart 都应至少包含 charts/ 来管理依赖,或使用 crds/ 来安装 CRD。
3.2 Chart.yaml 文件
Chart.yaml 是 Chart 的“身份证”,Helm 通过它识别 Chart 的身份、版本和依赖关系。以下是一个标准示例:
apiVersion: v2
name: mychart
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "1.16.0"
kubeVersion: ">=1.19.0-0"
keywords:
- web
- database
home: https://example.com
sources:
- https://github.com/example/mychart
maintainers:
- name: John Doe
email: john@example.com
url: https://example.com
dependencies:
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
tags:
- database
alias: db
icon: https://example.com/icon.svg
annotations:
category: Infrastructure
| 字段 | 说明 | 示例值 |
|---|---|---|
apiVersion |
Chart API 版本,v2 是当前标准 | v2 |
name |
Chart 名称,必须与目录名一致 | mychart |
version |
Chart 语义化版本,用于发布和回滚 | 0.1.0 |
appVersion |
所打包应用的版本,与 Chart 版本独立 | "1.16.0" |
dependencies |
依赖的子 Chart 列表,支持条件、标签、别名 | 见上例 |
type |
Chart 类型:application 或 library |
application |
注意:
version 和 appVersion 是两个不同的概念。version 控制 Chart 本身的迭代,appVersion 标记内部应用的版本。升级应用代码时只改 appVersion,修改 Chart 模板或配置时改 version。
3.3 values.yaml 文件
values.yaml 是 Chart 的配置中心,定义了所有可被模板引用的默认参数。Helm 通过 .Values 对象在模板中访问这些值。
# values.yaml
replicaCount: 3
image:
repository: nginx
tag: "1.25.3"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 80
ingress:
enabled: false
className: ""
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
Values 的层级结构直接映射到模板中的访问路径:
.Values.replicaCount→ 3.Values.image.repository→ nginx.Values.service.port→ 80.Values.ingress.enabled→ false
参数映射原则:模板中所有可变的值都应在
values.yaml 中定义默认值。用户通过 --set 或自定义 values 文件覆盖这些默认值,实现“一次编写,多处部署”。
3.4 templates 目录
templates/ 目录存放 Go 模板文件,Helm 将 values.yaml 中的参数注入模板,渲染出最终的 Kubernetes 资源清单。模板文件使用 .yaml 或 .tpl 扩展名。
一个典型的 Deployment 模板示例:
# templates/deployment.yaml
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 }}
模板中常用的内置对象:
| 对象 | 来源 | 示例 |
|---|---|---|
.Values |
values.yaml + 用户覆盖 |
.Values.replicaCount |
.Chart |
Chart.yaml |
.Chart.Name, .Chart.Version |
.Release |
Helm 命令行参数 | .Release.Name, .Release.Namespace |
.Files |
Chart 中的非模板文件 | .Files.Get "config.ini" |
.Capabilities |
目标 Kubernetes 集群信息 | .Capabilities.KubeVersion |
3.5 charts 依赖目录
charts/ 目录用于存放子 Chart 依赖。当你在 Chart.yaml 的 dependencies 中声明依赖后,执行 helm dependency update 会将依赖 Chart 下载到此目录。
依赖管理的三种方式:
- 直接存放:手动将子 Chart 的
.tgz包或目录放入charts/ - 声明式管理:在
Chart.yaml的dependencies中声明,通过helm dep update自动下载 - 条件依赖:使用
condition和tags控制依赖是否启用
依赖声明示例:
# Chart.yaml 中的 dependencies 段
dependencies:
- name: postgresql
version: "12.x.x"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
tags:
- database
alias: db
对应的 values.yaml 控制:
# values.yaml
postgresql:
enabled: true
postgresqlDatabase: myapp
postgresqlUsername: admin
依赖别名(alias)的作用:当同一个 Chart 需要被多次引用时(例如两个不同的数据库实例),使用
alias 可以避免命名冲突。子 Chart 的所有值将通过别名访问,如 .Values.db.postgresqlDatabase。
3.6 Chart 结构全景图
下图展示了 Chart 各组件之间的数据流和依赖关系:
3.7 参数映射流程
下图展示了从 values.yaml 到最终 Kubernetes 资源的完整参数映射链路:
3.8 关键实践要点
- 目录命名一致性:Chart 目录名必须与
Chart.yaml中的name字段完全一致,否则 Helm 会报错。 - 模板文件组织:按 Kubernetes 资源类型拆分模板文件(如
deployment.yaml、service.yaml、ingress.yaml),避免将所有资源写在一个大文件中。 - Values 层级扁平化:避免过深的嵌套层级(超过 3 层),否则会降低可读性。使用
--set覆盖时,深层路径容易出错。 - 依赖版本锁定:执行
helm dependency update后会生成Chart.lock文件,锁定所有依赖的精确版本,确保可重复构建。 - 忽略非必要文件:使用
.helmignore排除.git/、.DS_Store、测试文件等,减小 Chart 包体积。
总结:Chart 结构是 Helm 资源模型的骨架。
Chart.yaml 定义身份,values.yaml 提供参数,templates/ 负责渲染,charts/ 管理依赖。掌握这四者的协作关系,是编写高质量 Helm Chart 的基础。