3. Chart 基础结构:目录结构、Chart.yaml、values.yaml 与模板文件组织
一个标准的 Helm Chart 是 Kubernetes 资源的打包单元,其目录结构与核心文件的设计直接决定了 Release 的可维护性与可治理性。本节将深入剖析 Chart 的物理布局、Chart.yaml 的元数据定义、values.yaml 的设计原则以及模板文件的组织策略。
3.1 Chart 标准目录结构
Helm 强制要求 Chart 遵循固定的目录布局。以下是一个典型 Chart 的完整结构:
my-chart/
├── Chart.yaml # Chart 元数据(必需)
├── values.yaml # 默认配置值(必需)
├── values.schema.json # values.yaml 的 JSON Schema 校验文件(可选)
├── charts/ # 子 Chart 依赖目录(可选)
│ └── sub-chart-1.0.0.tgz
├── templates/ # Kubernetes 资源模板目录(必需)
│ ├── NOTES.txt # 安装后的使用说明(可选)
│ ├── _helpers.tpl # 模板辅助函数(可选)
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml
│ └── hpa.yaml
├── crds/ # 自定义资源定义目录(可选)
│ └── my-crd.yaml
└── README.md # Chart 说明文档(推荐)
治理要点:在发布治理场景中,
crds/ 目录中的 CRD 文件仅在 helm install 时安装,helm upgrade 不会更新 CRD。建议将 CRD 生命周期与 Chart 分离,由集群管理员独立管理。
3.2 Chart.yaml 元数据详解
Chart.yaml 是 Chart 的“身份证”,定义了 Chart 的名称、版本、描述、依赖等关键信息。以下是一个生产级 Chart.yaml 示例:
apiVersion: v2
name: my-application
description: 一个生产级微服务应用 Chart
type: application
# Chart 版本,遵循 SemVer 2
version: 1.2.3
# 应用版本,与 Chart 版本独立
appVersion: "2.5.0"
# 维护者信息
maintainers:
- name: devops-team
email: devops@company.com
url: https://devops.company.com
# 关键词,用于搜索分类
keywords:
- microservice
- web
- production
# 来源仓库地址
sources:
- https://git.company.com/helm-charts/my-application
# 依赖声明
dependencies:
- name: redis
version: ">=17.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
# 废弃标记
deprecated: false
# 图标 URL(可选)
icon: https://company.com/icons/my-app.png
版本治理关键字段:
- version:Chart 包版本,每次模板或 values 变更必须递增。
- appVersion:被部署的应用版本,仅当应用镜像或代码变更时更新。
- dependencies:声明子 Chart 依赖,支持
condition和tags实现条件启用。
3.3 values.yaml 设计原则
values.yaml 是 Chart 的配置入口,其设计质量直接影响 Release 的可配置性与治理复杂度。以下是经过生产验证的设计原则:
| 原则 | 说明 | 反例 |
|---|---|---|
| 扁平化优先 | 避免超过 3 层嵌套,降低覆盖复杂度 | spec.template.spec.containers[0].resources.limits.cpu |
| 默认值安全 | 所有字段必须提供生产可用的默认值 | 留空或填写 null |
| 类型明确 | 使用 YAML 类型(字符串、数字、布尔、列表)而非字符串化 | replicas: "3" 而非 replicas: 3 |
| 注释完备 | 每个字段上方添加 # 注释说明用途与取值范围 |
无注释的裸字段 |
| 环境分离 | 使用 values-{env}.yaml 覆盖,而非在 values.yaml 中写环境分支 |
if eq .Values.env "prod" 模板逻辑 |
一个符合设计原则的 values.yaml 示例:
# 全局配置
global:
# 环境标签,可选值:dev / staging / prod
environment: dev
# 镜像仓库地址
registry: docker.company.com
# 应用副本数
replicaCount: 2
# 镜像配置
image:
repository: my-application
tag: "2.5.0"
pullPolicy: IfNotPresent
# 服务配置
service:
type: ClusterIP
port: 8080
# 资源限制
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 1000m
memory: 1Gi
# 依赖组件开关
redis:
enabled: true
postgresql:
enabled: false
治理红线:禁止在
values.yaml 中写入密码、、证书等敏感信息。敏感数据应通过 --set 参数、外部 Secret 存储或 Helm Secrets 插件注入。
3.4 模板文件组织策略
templates/ 目录是 Go 模板引擎的工作区,合理的组织方式能大幅提升可读性与可维护性。
3.4.1 文件命名规范
- 资源类型前缀:
deployment.yaml、service.yaml、ingress.yaml,一目了然。 - 辅助文件:
_helpers.tpl存放可复用的模板函数,文件名以下划线_开头,Helm 不会将其渲染为 Kubernetes 资源。 - NOTES.txt:安装成功后打印的使用说明,支持模板语法。
3.4.2 模板分层架构
推荐将模板逻辑分为三层:
3.4.3 命名模板最佳实践
在 _helpers.tpl 中定义命名模板,避免在资源文件中重复逻辑:
{{- /* 生成统一的资源名称 */ -}}
{{- define "my-chart.fullname" -}}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- /* 生成通用标签 */ -}}
{{- define "my-chart.labels" -}}
app.kubernetes.io/name: {{ include "my-chart.fullname" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{- /* 条件判断:是否启用 Ingress */ -}}
{{- define "my-chart.ingress.enabled" -}}
{{- if and .Values.ingress.enabled (eq .Values.global.environment "prod") -}}
true
{{- else -}}
false
{{- end -}}
{{- end -}}
治理建议:将命名模板视为“API 契约”,团队内统一使用
include "chart-name.xxx" 模式。避免在多个模板文件中重复定义相同逻辑,减少升级时的冲突风险。
3.5 目录结构治理清单
在 Release 发布治理流程中,每次提交 Chart 前应检查以下清单:
| 检查项 | 标准 | 违规后果 |
|---|---|---|
| Chart.yaml 存在 | 必填字段完整,version 与 appVersion 分离 | Helm 拒绝安装 |
| values.yaml 存在 | 所有字段有默认值,类型正确 | 模板渲染失败 |
| templates/ 非空 | 至少包含一个 Kubernetes 资源模板 | 安装后无资源创建 |
| 敏感信息 | values.yaml 中无明文密码/密钥 | 安全审计不通过 |
| 命名模板 | 资源名称通过 _helpers.tpl 生成 |
命名不一致,升级冲突 |
| 依赖声明 | dependencies 使用版本范围而非固定版本 | 依赖无法自动更新 |
通过以上对 Chart 基础结构的深入理解,你可以在团队中建立统一的 Chart 编写规范,为后续的 Release 版本管理与发布流水线打下坚实基础。