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         # 打包时忽略的文件列表(可选)
Helm Chart 目录结构全景图 Helm Chart 目录结构全景图 my-chart/ Chart.yaml values.yaml charts/ templates/ .helmignore 子 Chart 包 NOTES.txt _helpers.tpl ⚠️ 核心文件 Chart.yaml + values.yaml + templates/ 为必需项

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 }}
_helpers.tpl 数据流与复用关系图 _helpers.tpl 数据流与复用关系图 values.yaml (默认配置) Chart.yaml (元数据) Release 对象 (运行时信息) _helpers.tpl 命名模板定义 (标签/名称/逻辑) deployment.yaml (引用命名模板) service.yaml (引用命名模板) NOTES.txt (引用命名模板) 复用逻辑:一处定义,多处引用,避免模板代码重复

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。