Helm Chart仓库建设与容器网络交付集成 - 第3节
3.1 Chart 目录结构:从骨架到交付物
一个标准的 Helm Chart 是一个遵循特定目录约定的文件集合。理解这个骨架是编写、维护和分发 Chart 的基础。下面是一个典型 Chart 的完整目录结构及其职责说明。
| 路径 / 文件 | 必需 | 说明 |
|---|---|---|
mychart/ |
是 | Chart 顶层目录,名称即 Chart 名称 |
├── Chart.yaml |
是 | Chart 元数据文件:名称、版本、描述、API 版本等 |
├── values.yaml |
是 | 默认配置值文件,模板引擎的输入源 |
├── templates/ |
是 | Go 模板文件目录,最终生成 Kubernetes 资源清单 |
│ ├── NOTES.txt |
否 | Chart 安装成功后的使用提示文本 |
│ ├── _helpers.tpl |
否 | 模板辅助函数定义,以下划线开头表示不直接生成资源 |
│ ├── deployment.yaml |
否 | 示例:Deployment 资源模板 |
│ ├── service.yaml |
否 | 示例:Service 资源模板 |
│ └── ingress.yaml |
否 | 示例:Ingress 资源模板 |
├── charts/ |
否 | 子 Chart 依赖目录,存放被依赖的 Chart 包(.tgz) |
├── crds/ |
否 | 自定义资源定义(CRD)目录,Helm 会优先安装 |
└── .helmignore |
否 | 打包时忽略文件的模式列表,类似 .gitignore |
最佳实践: 始终将
NOTES.txt 和 _helpers.tpl 纳入模板目录。前者提升用户体验,后者避免模板逻辑重复。
3.2 Chart.yaml 文件规范:Chart 的身份证
Chart.yaml 是每个 Chart 的元数据核心。Helm 通过它识别 Chart 的身份、版本、依赖和兼容性。以下是最新 apiVersion: v2 的字段规范。
| 字段 | 类型 | 必需 | 说明与示例 |
|---|---|---|---|
apiVersion |
string | 是 | Chart API 版本,v2 表示 Helm 3+,v1 表示 Helm 2 |
name |
string | 是 | Chart 名称,必须与目录名一致,如 myapp |
version |
string | 是 | Chart 语义化版本,如 1.2.3 |
description |
string | <>否简短描述 Chart 功能 | |
type |
string | 否 | application(默认)或 library |
appVersion |
string | 否 | 应用版本,如 3.2.1,与 Chart 版本独立 |
dependencies |
list | 否 | 子 Chart 依赖列表,每个依赖包含 name、version、repository |
keywords |
list | 否 | 搜索关键词,如 [web, nginx] |
home |
string | 否 | 项目主页 URL |
sources |
list | 否 | 源代码仓库 URL 列表 |
maintainers |
list | 否 | 维护者信息,每个包含 name、email、url |
icon |
string | 否 | Chart 图标 URL(SVG/PNG) |
kubeVersion |
string | 否 | 兼容的 Kubernetes 版本约束,如 ^1.20.0-0 |
完整示例:
apiVersion: v2
name: myapp
description: A production-ready web application
type: application
version: 0.1.0
appVersion: "1.16.0"
kubeVersion: "^1.20.0-0"
home: https://example.com
sources:
- https://github.com/example/myapp
maintainers:
- name: DevOps Team
email: devops@example.com
dependencies:
- name: redis
version: "~17.0.0"
repository: "https://charts.bitnami.com/bitnami"
- name: postgresql
version: "~12.0.0"
repository: "https://charts.bitnami.com/bitnami"
condition: postgresql.enabled
版本管理陷阱:
version 是 Chart 自身的版本,appVersion 是打包的应用版本。升级应用时只改 appVersion,升级 Chart 模板或依赖时改 version。两者独立,但建议保持语义化一致。
3.3 values.yaml 与模板引擎基础:配置驱动的资源生成
Helm 的核心能力在于将 values.yaml 中的配置注入到 templates/ 目录下的 Go 模板文件中,动态生成 Kubernetes 资源清单。理解这个数据流是掌握 Helm 的关键。
3.3.1 values.yaml 的结构设计
values.yaml 是一个纯 YAML 文件,定义所有可配置参数。良好的结构设计能提升 Chart 的可维护性和用户体验。
推荐的分层结构:
# 全局配置
global:
imageRegistry: "docker.io"
imagePullSecrets: []
# 应用副本与镜像
replicaCount: 3
image:
repository: nginx
tag: "1.25.3"
pullPolicy: IfNotPresent
# 服务配置
service:
type: ClusterIP
port: 80
targetPort: 8080
# 资源限制
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
# 探针配置
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
# 持久化存储
persistence:
enabled: true
storageClass: "standard"
accessMode: ReadWriteOnce
size: 10Gi
3.3.2 模板引擎核心语法
Helm 使用 Go 模板引擎,并扩展了 Sprig 函数库。模板文件以 {{ }} 作为分隔符,通过 .Values 对象访问 values.yaml 中的数据。
| 语法 | 说明 | 示例 |
|---|---|---|
{{ .Values.replicaCount }} |
直接取值 | 输出 3 |
{{ .Values.image.repository }}:{{ .Values.image.tag }} |
嵌套取值与拼接 | 输出 nginx:1.25.3 |
{{ default "default-value" .Values.someKey }} |
提供默认值 | 若 someKey 未定义,输出 default-value |
{{- if .Values.persistence.enabled }} |
条件判断 | 根据布尔值决定是否渲染 PVC 块 |
{{- range .Values.containers }} |
循环遍历 | 遍历容器列表,生成多个容器定义 |
{{ .Chart.Name }}-{{ .Release.Name }} |
内置对象 | 输出 myapp-release-1 |
{{ include "mychart.labels" . }} |
模板引用 | 调用 _helpers.tpl 中定义的命名模板 |
调试技巧: 使用
helm template . --debug 可以预览渲染后的 YAML 清单,而不实际安装。结合 helm lint 检查模板语法错误。
3.3.3 模板中的内置对象
Helm 模板引擎提供了多个内置对象,用于访问 Chart 元数据、Release 信息和集群上下文。
| 对象 | 类型 | 常用字段 | 示例输出 |
|---|---|---|---|
.Values |
map | 所有 values.yaml 中的键 | .Values.replicaCount → 3 |
.Chart |
map | .Name, .Version, .AppVersion |
.Chart.Name → myapp |
.Release |
map | .Name, .Namespace, .IsInstall, .IsUpgrade |
.Release.Name → my-release |
.Files |
map | .Get, .GetBytes |
.Files.Get "config.toml" |
.Capabilities |
map | .KubeVersion, .APIVersions |
检测集群支持的 API 版本 |
.Template |
map | .Name, .BasePath |
当前模板文件路径 |
实战模板片段:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-{{ .Chart.Name }}
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ .Chart.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ .Chart.Name }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- containerPort: {{ .Values.service.targetPort }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
缩进陷阱: YAML 对缩进敏感。在模板中使用
nindent 或 indent 函数控制动态内容的缩进层级。例如 {{- toYaml .Values.resources | nindent 12 }} 确保生成的 resources 块缩进 12 个空格,与父级对齐。
3.4 本章小结
- 目录结构:
Chart.yaml、values.yaml、templates/是三大必需组件,charts/和crds/按需添加。 - Chart.yaml:定义 Chart 元数据,
version与appVersion独立管理,dependencies字段实现模块化。 - values.yaml:采用分层结构,将镜像、服务、资源、探针等配置分离,提升可读性和覆盖灵活性。
- 模板引擎:通过
{{ .Values }}访问配置,利用if、range、include实现逻辑控制,使用nindent解决 YAML 缩进问题。