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 字段管理。
Helm Chart 标准目录结构 Helm Chart 标准目录结构 mychart/ Chart.yaml values.yaml templates/ charts/ deployment.yaml service.yaml _helpers.tpl NOTES.txt tests/ subchart-1/ subchart-2/ 说明: • Chart.yaml、values.yaml、templates/ 是 Chart 的三大核心组件,缺一不可。 • charts/ 用于管理依赖,crds/ 用于管理 CRD,均为可选但推荐的结构。

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 提供安装后的使用说明,如访问地址、默认密码获取方式等,提升用户体验。
Helm 模板渲染与配置覆盖流程 Helm 模板渲染与配置覆盖流程 values.yaml (默认配置) templates/ (Go 模板文件) -f custom-values.yaml (用户自定义覆盖) --set key=value (命令行参数覆盖) 合并后的 Values (优先级:--set > -f > 默认) 渲染后的 YAML (最终 Kubernetes 资源)

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 默认值,理解此优先级有助于调试多环境部署问题。