2. Chart 仓库核心概念:Chart 包结构、Chart.yaml、values.yaml、模板文件、依赖管理(Chart.lock)

Chart 是 Helm 的打包单元,本质是一个按照特定规范组织的文件目录集合。理解 Chart 的内部结构是掌握 Helm 控制平面与仓库数据交互的基础。本节将深入剖析 Chart 包的物理布局、核心元数据文件、值注入机制、模板渲染引擎以及依赖锁定协议。

2.1 Chart 包标准目录结构

一个标准的 Chart 包在打包前表现为一个目录,其顶层文件与子目录具有严格的命名约定。下表列出了核心组件及其职责:

路径 / 文件 必需 说明
Chart.yaml 是 Chart 的元数据文件,包含名称、版本、API 版本、描述等。
values.yaml 是 默认配置值文件,为模板提供可注入的变量。
templates/ 是 存放 Go 模板文件,渲染后生成 Kubernetes 资源清单。
charts/ 否 存放子 Chart 的打包文件(.tgz),用于依赖管理。
Chart.lock 否 依赖锁定文件,记录精确的依赖版本与校验和。
crds/ 否 自定义资源定义(CRD)清单,在模板渲染前安装。
README.md 否 Chart 的使用说明与文档。
.helmignore 否 打包时忽略的文件模式列表,类似 .gitignore。
关键路径规则: templates/ 目录下的所有文件都会被 Helm 引擎解析为 Kubernetes 资源模板。非模板文件(如 ConfigMap 中的静态配置)应放置在 templates/ 之外,或使用 .helmignore 排除。

2.2 Chart.yaml:元数据声明文件

Chart.yaml 是 Chart 的身份证明。Helm 控制平面在仓库索引、依赖解析、版本校验时,首先读取该文件。以下是一个生产级 Chart.yaml 示例:

apiVersion: v2
name: my-application
description: A production-grade microservice chart
type: application
version: 1.2.3
appVersion: "3.0.0"
kubeVersion: ">=1.21.0-0"
keywords:
  - microservice
  - web
home: https://example.com
sources:
  - https://github.com/example/my-application
maintainers:
  - name: DevOps Team
    email: devops@example.com
dependencies:
  - name: redis
    version: ">=16.0.0"
    repository: https://charts.bitnami.com/bitnami
    condition: redis.enabled
    tags:
      - cache
icon: https://example.com/icon.svg

字段说明:

  • apiVersion:v2 表示 Helm 3 及以上版本,v1 为 Helm 2 遗留格式。
  • type:application 表示可部署应用,library 表示工具库 Chart(仅提供模板,不生成资源)。
  • version:Chart 包的语义化版本,用于仓库索引和升级比较。
  • appVersion:所包含应用的版本号,仅作信息展示,不参与依赖解析。
  • dependencies:声明外部 Chart 依赖,Helm 在 helm dependency update 时据此下载。

2.3 values.yaml:默认值注入层

values.yaml 是 Chart 的配置入口,定义了所有可被模板引用的默认变量。Helm 采用三层值合并策略:

  1. 内置值:Helm 自动注入的全局对象(如 .Release.Name、.Chart.Version)。
  2. Chart 默认值:来自 values.yaml 的静态定义。
  3. 用户覆盖值:通过 --set 或自定义 values 文件传入,优先级最高。

典型 values.yaml 结构:

replicaCount: 3

image:
  repository: nginx
  tag: "1.25.0"
  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.yaml 中,避免在模板内硬编码。使用 --dry-run 参数预览渲染结果,验证值注入是否正确。

2.4 模板文件:Go 模板引擎与资源生成

templates/ 目录下的文件使用 Go 模板语法,结合 values.yaml 和内置对象动态生成 Kubernetes YAML。Helm 在渲染时执行以下步骤:

  • 解析所有 templates/*.yaml、templates/*.tpl 文件。
  • 加载 values.yaml 及用户覆盖值,合并为全局 .Values 对象。
  • 执行模板函数(如 include、required、default)。
  • 输出合法的 Kubernetes 资源清单,发送至 API Server。

以下是一个 Deployment 模板片段:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "my-application.fullname" . }}
  labels:
    {{- include "my-application.labels" . | nindent 4 }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "my-application.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "my-application.selectorLabels" . | nindent 8 }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          ports:
            - containerPort: {{ .Values.service.port }}
注意: 模板中的缩进控制至关重要。使用 nindent 和 indent 函数保持 YAML 格式正确。错误的缩进会导致 Helm 渲染出无效的 Kubernetes 资源。

2.5 依赖管理:Chart.lock 与依赖解析

当 Chart 声明了 dependencies 后,Helm 通过 helm dependency update 命令解析并下载依赖。该过程生成两个关键产物:

  • charts/ 目录:存放下载后的子 Chart .tgz 包。
  • Chart.lock 文件:记录依赖的精确版本、仓库 URL 和校验和(SHA-256)。

Chart.lock 示例:

dependencies:
- name: redis
  repository: https://charts.bitnami.com/bitnami
  version: 16.13.2
digest: sha256:3a6f8e4c9b1d2e5f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0
generated: "2024-01-15T10:30:00Z"

依赖解析流程:

  1. 读取 Chart.yaml:获取 dependencies 列表及版本约束。
  2. 查询仓库索引:从声明的 repository URL 获取 index.yaml,匹配满足约束的最新版本。
  3. 下载 Chart 包:将匹配的 .tgz 文件保存至 charts/ 目录。
  4. 生成锁定文件:计算每个依赖包的 SHA-256 摘要,写入 Chart.lock。
  5. 校验一致性:后续 helm install 或 helm upgrade 时,Helm 对比 Chart.lock 与 charts/ 中的实际包,确保依赖未被篡改或版本漂移。
版本锁定策略: 将 Chart.lock 纳入版本控制(Git),确保团队所有成员和 CI/CD 流水线使用完全相同的依赖版本,避免“在我机器上能跑”的问题。

2.6 Chart 包结构总览图

下图展示了 Chart 包内部各组件之间的数据流与依赖关系:

Chart 包内部结构及数据流 Chart 根目录 Chart.yaml 元数据声明 values.yaml 默认配置值 templates/ Go 模板文件 charts/ 子 Chart 包 helm dependency update Chart.lock 版本锁定 + 校验和 charts/*.tgz 下载的子 Chart 渲染输出 Kubernetes YAML 说明:Chart.yaml 声明依赖 → helm dependency update 下载子 Chart 并生成 Chart.lock → 模板引擎合并 values.yaml 渲染最终 YAML

2.7 依赖解析与锁定流程

为了更清晰地展示依赖管理的执行顺序,下图聚焦于 Chart.lock 的生成与校验过程:

依赖解析与 Chart.lock 生成流程 1. 读取 Chart.yaml 获取依赖声明列表 2. 查询仓库索引 匹配版本约束 3. 下载子 Chart 保存至 charts/ 4. 计算校验和 SHA-256 摘要 5. 生成 Chart.lock 写入版本 + 校验和

2.8 核心概念对比表

概念 文件/目录 控制平面角色 仓库交互
Chart 元数据 Chart.yaml 版本校验、依赖声明 仓库索引读取
默认配置 values.yaml 值注入与合并 本地文件,不直接与仓库交互
资源模板 templates/ Go 模板渲染引擎 本地文件,不直接与仓库交互
子 Chart 包 charts/ 依赖加载与合并 从仓库下载 .tgz
依赖锁定 Chart.lock 版本一致性校验 记录仓库 URL 与校验和
生产建议: 在 CI/CD 流水线中执行 helm dependency build 而非 helm dependency update。build 命令仅读取 Chart.lock 下载指定版本,不重新解析版本约束,确保构建可重现。