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 纳入模板目录。前者提升用户体验,后者避免模板逻辑重复。
Helm Chart 标准目录结构 mychart/ Chart.yaml values.yaml templates/ NOTES.txt _helpers.tpl deployment.yaml service.yaml ingress.yaml charts/ crds/ .helmignore 说明: • 绿色节点为必需文件,红色节点为核心目录,橙色为资源模板示例。 • charts/ 和 crds/ 仅在需要依赖或 CRD 时创建。

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 检查模板语法错误。
Helm 模板引擎数据流 values.yaml 默认配置值 templates/ Go 模板文件 Helm 模板引擎 渲染 + 函数执行 (Sprig + 内置对象) Kubernetes 清单 Deployment/Service Ingress/ConfigMap 数据流说明: 1. Helm 读取 values.yaml 和用户提供的 --set / -f 覆盖值。 2. 模板引擎将 .Values 注入到 templates/ 中的 Go 模板,执行条件、循环、函数。

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 缩进问题。