4. Chart 包结构:Chart.yaml、values.yaml、templates 目录、charts 依赖、NOTES.txt、helpers.tpl

一个标准的 Helm Chart 包遵循固定的目录与文件约定。理解这些核心构件是编写可维护、可复用的 Kubernetes 应用描述文件的基础。本章逐一拆解 Chart 包的六大组成部分,并说明它们在资源模型适配中的角色。

4.1 Chart 包顶层结构一览

执行 helm create mychart 后生成的标准骨架如下:

mychart/
├── Chart.yaml          # Chart 元数据定义
├── values.yaml         # 默认配置值
├── charts/             # 子 Chart 依赖(手动或 helm dependency 管理)
├── templates/          # Go 模板 + Kubernetes 资源清单
│   ├── NOTES.txt       # 安装后的使用提示
│   ├── _helpers.tpl    # 模板辅助函数(命名模板)
│   ├── deployment.yaml
│   ├── service.yaml
│   └── ...
└── .helmignore         # 打包时忽略的文件模式
核心原则:Chart 包本质是一个“模板引擎 + 默认值 + 依赖管理”的打包单元。templates 目录下的 YAML 经过 values.yaml 渲染后,生成最终的 Kubernetes 资源对象。
Helm Chart 包结构全景图 Helm Chart 包结构全景图 mychart/ (Chart 根目录) Chart.yaml values.yaml charts/ (依赖) templates/ NOTES.txt _helpers.tpl deployment.yaml service.yaml 说明: Chart.yaml 定义元数据;values.yaml 提供默认值;templates/ 存放 Kubernetes 资源模板; charts/ 管理子依赖;NOTES.txt 输出安装后提示;_helpers.tpl 封装可复用的命名模板。

4.2 Chart.yaml — Chart 的身份证

Chart.yaml 是每个 Chart 必须存在的元数据文件。Helm 通过它识别 Chart 的名称、版本、API 兼容性以及依赖声明。

字段 必填 说明 示例
apiVersion 是 Chart API 版本,v2 用于 Helm 3+ v2
name 是 Chart 名称,用于 release 标识 myapp
version 是 Chart 语义化版本,遵循 SemVer 2 1.2.3
appVersion 否 所封装应用的版本,与 Chart 版本独立 3.0.1
description 否 简短描述 Chart 功能 A microservice for user management
dependencies 否 子 Chart 依赖列表(见 4.5 节) —
type 否 application 或 library application
icon 否 Chart 图标的 URL https://example.com/icon.svg
适配要点:在资源模型适配场景中,apiVersion 必须为 v2 才能使用 dependencies 和 type: library。version 与 appVersion 分离设计,允许 Chart 升级而不影响应用版本标识。

4.3 values.yaml — 配置的默认值锚点

values.yaml 是 Chart 的默认配置入口。它定义了模板渲染时使用的变量初始值,用户可通过 --set 或自定义 values 文件覆盖。

# values.yaml 典型结构
replicaCount: 3

image:
  repository: nginx
  tag: "1.25"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 250m
    memory: 256Mi

ingress:
  enabled: false
  host: myapp.example.com
层级 访问方式(模板中) 说明
顶层标量 {{ .Values.replicaCount }} 直接取值
嵌套对象 {{ .Values.image.repository }} 点号路径访问
条件开关 {{- if .Values.ingress.enabled }} 控制资源是否生成
列表 {{ range .Values.ports }} 迭代生成多个资源
常见陷阱:values.yaml 中的键名不要使用连字符(-),Go 模板会将 .Values.my-key 解析为减法表达式。推荐使用驼峰或下划线命名。

4.4 templates 目录 — 资源模板的核心战场

templates/ 目录存放所有 Kubernetes 资源清单的 Go 模板文件。Helm 会递归渲染该目录下所有 .yaml、.tpl、.txt 文件,并将结果发送给 Kubernetes API。

模板文件的核心语法要素:

  • 模板指令:{{ .Values.replicaCount }} 引用 values 值
  • 管道函数:{{ .Values.name | default "default-name" | quote }}
  • 流程控制:if/else、range、with
  • 命名模板调用:{{ include "mychart.labels" . }}
  • 内置对象:.Values、.Release、.Chart、.Files、.Capabilities
{{- /* 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 }}"
          ports:
            - containerPort: {{ .Values.service.port }}

4.5 charts 依赖 — 子 Chart 管理

charts/ 目录存放 Chart 的依赖子 Chart。依赖关系在 Chart.yaml 的 dependencies 字段中声明,通过 helm dependency update 下载。

# Chart.yaml 中的依赖声明
dependencies:
  - name: redis
    version: "17.3.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
依赖字段 说明
name 子 Chart 名称
version 子 Chart 版本范围(支持 SemVer 约束)
repository Chart 仓库 URL 或本地路径(file://)
condition 条件控制,值为 true/false 时决定是否安装该依赖
tags 标签分组,可批量启用/禁用一组依赖
import-values 从子 Chart 的 values 中导入特定值到父 Chart
资源模型适配技巧:使用 condition 和 tags 实现依赖的按需加载。例如,在开发环境禁用 redis 和 postgresql,仅启用内存模拟服务,避免资源浪费。

4.6 NOTES.txt — 安装后的用户指引

NOTES.txt 是一个特殊的模板文件,在 helm install 或 helm upgrade 成功后自动渲染并输出给用户。它通常包含:

  • 应用访问地址(Service IP、Ingress 域名)
  • 默认凭据(用户名/密码)及获取方式
  • 后续操作步骤(如数据库迁移命令)
  • 故障排查提示
{{- /* 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 "mychart.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 }}

2. Default credentials:
   Username: admin
   Password: {{ .Values.adminPassword | default "changeme" }}

4.7 _helpers.tpl — 命名模板的复用工厂

_helpers.tpl 是约定俗成的命名模板文件(文件名以下划线开头,不会生成 Kubernetes 资源)。它定义可复用的模板片段,通过 define 和 include 机制在多个模板间共享。

{{- /* _helpers.tpl 典型内容 */ -}}
{{- define "mychart.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{- define "mychart.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 "mychart.labels" -}}
helm.sh/chart: {{ include "mychart.name" . }}-{{ .Chart.Version | replace "+" "_" }}
{{ include "mychart.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{- define "mychart.selectorLabels" -}}
app.kubernetes.io/name: {{ include "mychart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
命名模板 用途 输出示例
mychart.name 生成应用名称(Chart 名或自定义覆盖) myapp
mychart.fullname 生成全局唯一资源名(Release + Chart) release-myapp
mychart.labels 生成标准 Kubernetes 标签集 helm.sh/chart: myapp-1.0.0
mychart.selectorLabels 生成 Selector 匹配标签 app.kubernetes.io/name: myapp
最佳实践:所有 Chart 都应包含 _helpers.tpl,并将资源命名、标签生成、通用格式化逻辑集中于此。这确保 Deployment、Service、Ingress 等资源使用一致的命名和标签体系,便于 Kubernetes 资源模型中的选择器匹配与运维管理。
Helm 模板渲染与资源生成流程 Helm 模板渲染与资源生成流程 values.yaml (默认配置值) templates/*.yaml (Go 模板 + 资源骨架) _helpers.tpl (命名模板复用) Helm 模板引擎 渲染 + 值注入 + 函数执行 Deployment (完整 YAML) Service (完整 YAML) Ingress / ConfigMap (完整 YAML) 流程:values.yaml 提供数据 → templates 中的 Go 模板引用数据并调用 _helpers.tpl 命名模板 → Helm 引擎渲染出完整 Kubernetes 资源 YAML。

4.8 六大组件在资源模型适配中的协作关系

组件 在资源模型适配中的角色 关键约束
Chart.yaml 声明 Chart 身份、版本、依赖拓扑 apiVersion 必须为 v2;version 遵循 SemVer
values.yaml 定义资源参数的默认值(副本数、镜像、端口、资源限制) 键名避免连字符;嵌套层级不宜过深
templates/ 将 values 数据注入 Kubernetes 资源清单,生成最终 YAML 使用 include 而非 template 以支持上下文传递
charts/ 引入外部子 Chart(如数据库、缓存),组合成完整应用栈 使用 condition 控制依赖启停,避免资源冲突
NOTES.txt 输出安装后的访问指引和运维提示 模板中可引用 .Release、.Values 动态生成 URL
_helpers.tpl 封装命名规范、标签生成、通用格式化逻辑,确保资源一致性 命名模板以 Chart 名称为前缀,避免全局命名冲突
适配总结:一个设计良好的 Chart 包,其 values.yaml 提供清晰的参数化接口,_helpers.tpl 保证资源命名和标签的标准化,charts/ 管理外部依赖的生命周期。这三者共同构成了 Helm 控制平面与 Kubernetes 资源模型之间的适配层,使应用描述从“硬编码 YAML”进化为“可配置、可组合、可版本化的模板单元”。