图表

Helm 使用一种名为*图表*的打包格式。图表是描述一组相关 Kubernetes 资源的文件集合。单个图表可用于部署一些简单的东西,如 memcached pod,或一些复杂的东西,如带有 HTTP 服务器、数据库、缓存等的完整 Web 应用堆栈。

图表被创建为按特定目录树排列的文件。它们可以打包成版本化的归档文件以供部署。

如果您想下载并查看已发布图表的 文件,而不进行安装,可以使用 helm pull chartrepo/chartname

本文档介绍了图表格式,并提供使用 Helm 构建图表的 基本指南。

图表文件结构

图表被组织为目录内的文件集合。目录名称是图表的名称(不含版本信息)。因此,描述 WordPress 的图表将存储在 wordpress/ 目录中。

在此目录内,Helm 将期望一个与以下结构匹配的结构

wordpress/
  Chart.yaml          # A YAML file containing information about the chart
  LICENSE             # OPTIONAL: A plain text file containing the license for the chart
  README.md           # OPTIONAL: A human-readable README file
  values.yaml         # The default configuration values for this chart
  values.schema.json  # OPTIONAL: A JSON Schema for imposing a structure on the values.yaml file
  charts/             # A directory containing any charts upon which this chart depends.
  crds/               # Custom Resource Definitions
  templates/          # A directory of templates that, when combined with values,
                      # will generate valid Kubernetes manifest files.
  templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes

Helm 保留对 charts/crds/templates/ 目录以及列出文件名的使用。其他文件将保留原样。

Chart.yaml 文件

Chart.yaml 文件对于图表是必需的。它包含以下字段

apiVersion: The chart API version (required)
name: The name of the chart (required)
version: A SemVer 2 version (required)
kubeVersion: A SemVer range of compatible Kubernetes versions (optional)
description: A single-sentence description of this project (optional)
type: The type of the chart (optional)
keywords:
  - A list of keywords about this project (optional)
home: The URL of this projects home page (optional)
sources:
  - A list of URLs to source code for this project (optional)
dependencies: # A list of the chart requirements (optional)
  - name: The name of the chart (nginx)
    version: The version of the chart ("1.2.3")
    repository: (optional) The repository URL ("https://example.com/charts") or alias ("@repo-name")
    condition: (optional) A yaml path that resolves to a boolean, used for enabling/disabling charts (e.g. subchart1.enabled )
    tags: # (optional)
      - Tags can be used to group charts for enabling/disabling together
    import-values: # (optional)
      - ImportValues holds the mapping of source values to parent key to be imported. Each item can be a string or pair of child/parent sublist items.
    alias: (optional) Alias to be used for the chart. Useful when you have to add the same chart multiple times
maintainers: # (optional)
  - name: The maintainers name (required for each maintainer)
    email: The maintainers email (optional for each maintainer)
    url: A URL for the maintainer (optional for each maintainer)
icon: A URL to an SVG or PNG image to be used as an icon (optional).
appVersion: The version of the app that this contains (optional). Needn't be SemVer. Quotes recommended.
deprecated: Whether this chart is deprecated (optional, boolean)
annotations:
  example: A list of annotations keyed by name (optional).

v3.3.2 开始,不允许添加其他字段。建议的方法是在 annotations 中添加自定义元数据。

图表和版本控制

每个图表都必须有一个版本号。版本必须遵循 SemVer 2 标准。与 Helm Classic 不同,Helm v2 及更高版本使用版本号作为发布标记。仓库中的包通过名称加版本进行标识。

例如,nginx 图表的版本字段设置为 version: 1.2.3,将被命名为

nginx-1.2.3.tgz

也支持更复杂的 SemVer 2 名称,例如 version: 1.2.3-alpha.1+ef365。但系统明确禁止使用非 SemVer 名称。

注意: Helm Classic 和 Deployment Manager 在图表方面都非常面向 GitHub,而 Helm v2 及更高版本并不依赖于或要求 GitHub 甚至 Git。因此,它根本不使用 Git SHA 进行版本控制。

Chart.yaml 内部的 version 字段被许多 Helm 工具使用,包括 CLI。在生成包时,helm package 命令将使用它在 Chart.yaml 中找到的版本作为包名称中的标记。系统假定图表包名称中的版本号与 Chart.yaml 中的版本号匹配。不满足此假设将导致错误。

apiVersion 字段

对于至少需要 Helm 3 的 Helm 图表,apiVersion 字段应为 v2。支持先前 Helm 版本的图表具有设置为 v1apiVersion,并且仍然可以由 Helm 3 安装。

v1v2 的变化

  • 一个 dependencies 字段,定义图表依赖项,这些依赖项位于 v1 图表的单独 requirements.yaml 文件中(请参阅 图表依赖项)。
  • type 字段,区分应用程序和库图表(请参阅 图表类型)。

appVersion 字段

请注意,appVersion 字段与 version 字段无关。它是一种指定应用程序版本的方法。例如,drupal 图表可能具有 appVersion: "8.2.1",表示图表中包含的 Drupal 版本(默认情况下)为 8.2.1。此字段仅供参考,不会影响图表版本计算。强烈建议将版本包含在引号中。它强制 YAML 解析器将版本号视为字符串。在某些情况下,不加引号会导致解析问题。例如,YAML 将 1.0 解释为浮点值,并将类似 1234e10 的 git 提交 SHA 解释为科学计数法。

从 Helm v3.5.0 开始,helm create 将默认的 appVersion 字段包含在引号中。

kubeVersion 字段

可选的 kubeVersion 字段可以定义对支持的 Kubernetes 版本的 semver 约束。Helm 在安装图表时将验证版本约束,如果集群运行的是不支持的 Kubernetes 版本,则会失败。

版本约束可以包含空格分隔的 AND 比较,例如

>= 1.13.0 < 1.15.0

它们本身可以使用 OR || 运算符组合在一起,例如在以下示例中

>= 1.13.0 < 1.14.0 || >= 1.14.1 < 1.15.0

在这个例子中,版本 1.14.0 被排除,如果已知某些版本的错误会阻止图表正常运行,这可能是有意义的。

除了使用运算符 = != > < >= <= 的版本约束外,还支持以下简写符号

  • 连字符范围用于闭区间,其中 1.1 - 2.3.4 等效于 >= 1.1 <= 2.3.4
  • 通配符 xX*,其中 1.2.x 等效于 >= 1.2.0 < 1.3.0
  • 波浪号范围(允许修补版本更改),其中 ~1.2.3 等效于 >= 1.2.3 < 1.3.0
  • 插入符号范围(允许次要版本更改),其中 ^1.2.3 等效于 >= 1.2.3 < 2.0.0

有关支持的 semver 约束的详细说明,请参阅 Masterminds/semver.

弃用图表

在管理图表仓库中的图表时,有时需要弃用图表。Chart.yaml 中的可选 deprecated 字段可用于将图表标记为已弃用。如果仓库中最新版本的图表被标记为已弃用,则整个图表被视为已弃用。图表名称稍后可以被重新使用,方法是发布一个未被标记为已弃用的较新版本。弃用图表的流程是

  1. 更新图表的 Chart.yaml 以将图表标记为已弃用,并增加版本号
  2. 在图表仓库中发布新图表版本
  3. 从源仓库(例如 git)中删除图表

图表类型

type 字段定义图表的类型。有两种类型:applicationlibrary。Application 是默认类型,它是可以完全操作的标准图表。 库图表 为图表构建者提供实用程序或函数。库图表不同于应用程序图表,因为它不可安装,通常不包含任何资源对象。

注意:应用程序图表可以用作库图表。这可以通过将类型设置为 library 来实现。然后,图表将被呈现为库图表,其中所有实用程序和函数都可以被利用。图表的全部资源对象将不会被呈现。

图表许可证、自述文件和注释

图表还可以包含描述图表的安装、配置、使用和许可证的文件。

LICENSE 是一个纯文本文件,包含图表的 许可证。图表可以包含许可证,因为它在模板中可能包含编程逻辑,因此它不只是配置。如果需要,还可以为图表安装的应用程序提供单独的许可证(s)。

图表的自述文件应以 Markdown 格式(README.md)编写,通常应包含

  • 图表提供的应用程序或服务的描述
  • 运行图表所需的任何先决条件或要求
  • values.yaml 中选项的描述和默认值
  • 可能与图表的安装或配置相关的任何其他信息

当中心和其他用户界面显示有关图表的详细信息时,这些详细信息将从 README.md 文件中的内容中提取。

图表中还可以包含一个简短的纯文本 `templates/NOTES.txt` 文件,该文件将在安装后以及查看版本状态时打印出来。此文件被评估为一个 模板,可用于显示使用说明、后续步骤或与版本发布相关的任何其他信息。例如,可以提供有关连接到数据库或访问 Web UI 的说明。由于此文件在运行 `helm install` 或 `helm status` 时打印到 STDOUT,因此建议将内容保持简短,并将更多详细信息指向 README。

图表依赖项

在 Helm 中,一个图表可以依赖于任意数量的其他图表。这些依赖项可以使用 `Chart.yaml` 中的 `dependencies` 字段进行动态链接,或者导入到 `charts/` 目录并手动管理。

使用 `dependencies` 字段管理依赖项

当前图表所需的图表在 `dependencies` 字段中定义为一个列表。

dependencies:
  - name: apache
    version: 1.2.3
    repository: https://example.com/charts
  - name: mysql
    version: 3.2.1
    repository: https://another.example.com/charts
  • `name` 字段是您想要的图表的名称。
  • `version` 字段是您想要的图表的版本。
  • `repository` 字段是图表存储库的完整 URL。请注意,您还必须使用 `helm repo add` 在本地添加该存储库。
  • 您可以使用存储库的名称代替 URL
$ helm repo add fantastic-charts https://charts.helm.sh/incubator
dependencies:
  - name: awesomeness
    version: 1.0.0
    repository: "@fantastic-charts"

定义好依赖项后,您可以运行 `helm dependency update`,它将使用您的依赖项文件将所有指定的图表下载到您的 `charts/` 目录中。

$ helm dep up foochart
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "local" chart repository
...Successfully got an update from the "stable" chart repository
...Successfully got an update from the "example" chart repository
...Successfully got an update from the "another" chart repository
Update Complete. Happy Helming!
Saving 2 charts
Downloading apache from repo https://example.com/charts
Downloading mysql from repo https://another.example.com/charts

当 `helm dependency update` 获取图表时,它会将它们作为图表存档存储在 `charts/` 目录中。因此,对于上面的示例,您应该在 charts 目录中看到以下文件

charts/
  apache-1.2.3.tgz
  mysql-3.2.1.tgz

依赖项中的别名字段

除了上面的其他字段之外,每个需求条目还可以包含可选字段 `alias`。

为依赖图表添加别名将使用别名作为新依赖的名称将图表放入依赖项中。

当需要使用其他名称访问图表时,可以使用 `alias`。

# parentchart/Chart.yaml

dependencies:
  - name: subchart
    repository: https://127.0.0.1:10191
    version: 0.1.0
    alias: new-subchart-1
  - name: subchart
    repository: https://127.0.0.1:10191
    version: 0.1.0
    alias: new-subchart-2
  - name: subchart
    repository: https://127.0.0.1:10191
    version: 0.1.0

在上面的示例中,我们将为 `parentchart` 获取所有 3 个依赖项

subchart
new-subchart-1
new-subchart-2

手动实现此操作的方法是将同一个图表复制/粘贴到 `charts/` 目录中多次,并使用不同的名称。

依赖项中的标签和条件字段

除了上面的其他字段之外,每个需求条目还可以包含可选字段 `tags` 和 `condition`。

默认情况下加载所有图表。如果存在 `tags` 或 `condition` 字段,它们将被评估并用于控制对其应用的图表(s)的加载。

Condition - `condition` 字段包含一个或多个 YAML 路径(用逗号分隔)。如果此路径存在于父级顶层的 `values` 中并解析为布尔值,则图表将根据该布尔值启用或禁用。仅评估列表中找到的第一个有效路径,如果不存在路径,则条件不起作用。

Tags - `tags` 字段是与该图表关联的标签的 YAML 列表。在父级顶层的 `values` 中,可以通过指定标签和布尔值来启用或禁用具有标签的所有图表。

# parentchart/Chart.yaml

dependencies:
  - name: subchart1
    repository: https://127.0.0.1:10191
    version: 0.1.0
    condition: subchart1.enabled,global.subchart1.enabled
    tags:
      - front-end
      - subchart1
  - name: subchart2
    repository: https://127.0.0.1:10191
    version: 0.1.0
    condition: subchart2.enabled,global.subchart2.enabled
    tags:
      - back-end
      - subchart2
# parentchart/values.yaml

subchart1:
  enabled: true
tags:
  front-end: false
  back-end: true

在上面的示例中,所有带有 `front-end` 标签的图表都将被禁用,但由于 `subchart1.enabled` 路径在父级 `values` 中的值为 'true',因此该条件将覆盖 `front-end` 标签,`subchart1` 将被启用。

由于 `subchart2` 被标记为 `back-end` 并且该标签的值为 `true`,因此 `subchart2` 将被启用。还要注意,尽管 `subchart2` 指定了条件,但在父级的 `values` 中没有相应的路径和值,因此该条件不起作用。

使用带有标签和条件的 CLI

`--set` 参数可以像往常一样用于更改标签和条件的值。

helm install --set tags.front-end=true --set subchart2.enabled=false
标签和条件解析
  • **条件(在 `values` 中设置时)始终覆盖标签。** 存在的第一条条件路径获胜,后续路径将被忽略。
  • 标签的评估方式为“如果图表的任何标签为真,则启用该图表”。
  • 标签和条件值必须在父级顶层的 `values` 中设置。
  • `values` 中的 `tags:` 键必须是顶级键。目前不支持全局和嵌套 `tags:` 表。

通过依赖项导入子级 `values`

在某些情况下,希望允许子级图表的 `values` 传播到父级图表并作为公共默认值共享。使用 `exports` 格式的另一个好处是它将使未来的工具能够内省用户可设置的值。

可以使用 `import-values` 字段在父级图表的 `dependencies` 中指定包含要导入的值的键,该字段使用 YAML 列表。列表中的每个项目都是从子级图表的 `exports` 字段中导入的键。

要导入 `exports` 键中未包含的值,请使用 子级-父级 格式。下面介绍了两种格式的示例。

使用 `exports` 格式

如果子级图表的 `values.yaml` 文件在根目录中包含 `exports` 字段,则可以通过指定要导入的键(如以下示例所示)将其内容直接导入父级 `values` 中。

# parent's Chart.yaml file

dependencies:
  - name: subchart
    repository: https://127.0.0.1:10191
    version: 0.1.0
    import-values:
      - data
# child's values.yaml file

exports:
  data:
    myint: 99

由于我们在导入列表中指定了 `data` 键,因此 Helm 会在子级图表的 `exports` 字段中查找 `data` 键并导入其内容。

最终的父级 `values` 将包含我们的导出字段

# parent's values

myint: 99

请注意,父级键 `data` 不包含在父级的最终 `values` 中。如果您需要指定父级键,请使用“子级-父级”格式。

使用子级-父级格式

要访问子级图表 `values` 中 `exports` 键中未包含的值,您需要指定要导入的值的源键(`child`)和父级图表 `values` 中的目标路径(`parent`)。

以下示例中的 `import-values` 指示 Helm 将在 `child:` 路径中找到的任何值复制到父级 `values` 中 `parent:` 中指定的路径。

# parent's Chart.yaml file

dependencies:
  - name: subchart1
    repository: https://127.0.0.1:10191
    version: 0.1.0
    ...
    import-values:
      - child: default.data
        parent: myimports

在上面的示例中,在 `subchart1` 的 `values` 中找到的 `default.data` 中的值将被导入到父级图表的 `values` 中的 `myimports` 键中,如下所示

# parent's values.yaml file

myimports:
  myint: 0
  mybool: false
  mystring: "helm rocks!"
# subchart1's values.yaml file

default:
  data:
    myint: 999
    mybool: true

父级图表的结果 `values` 将是

# parent's final values

myimports:
  myint: 999
  mybool: true
  mystring: "helm rocks!"

父级最终 `values` 现在包含从 `subchart1` 导入的 `myint` 和 `mybool` 字段。

通过 `charts/` 目录手动管理依赖项

如果需要对依赖项进行更多控制,可以通过将依赖图表复制到 `charts/` 目录中来明确表示这些依赖项。

依赖项应该是一个解压缩的图表目录,但其名称不能以 `_` 或 `.` 开头。图表加载器会忽略此类文件。

例如,如果 WordPress 图表依赖于 Apache 图表,则 Apache 图表(正确版本)将被提供在 WordPress 图表的 `charts/` 目录中

wordpress:
  Chart.yaml
  # ...
  charts/
    apache/
      Chart.yaml
      # ...
    mysql/
      Chart.yaml
      # ...

上面的示例显示了 WordPress 图表如何通过在其 `charts/` 目录中包含这些图表来表示其对 Apache 和 MySQL 的依赖关系。

**提示:**要将依赖项放到您的 `charts/` 目录中,请使用 `helm pull` 命令

使用依赖项的操作方面

以上部分解释了如何指定图表依赖关系,但这如何影响使用 `helm install` 和 `helm upgrade` 安装图表?

假设一个名为“A”的图表创建了以下 Kubernetes 对象

  • 命名空间“A-Namespace”
  • 有状态集“A-StatefulSet”
  • 服务“A-Service”

此外,A 依赖于创建对象的图表 B

  • 命名空间“B-Namespace”
  • 副本集“B-ReplicaSet”
  • 服务“B-Service”

安装/升级图表 A 后,将创建/修改单个 Helm 版本。该版本将按以下顺序创建/更新所有上述 Kubernetes 对象

  • A-Namespace
  • B-Namespace
  • A-Service
  • B-Service
  • B-ReplicaSet
  • A-StatefulSet

这是因为当 Helm 安装/升级图表时,来自图表及其所有依赖项的 Kubernetes 对象将被

  • 聚合到一个集合中;然后
  • 按类型排序,然后按名称排序;然后
  • 按此顺序创建/更新。

因此,将创建包含图表及其所有依赖项的所有对象的单个版本。

Kubernetes 类型安装顺序由 `kind_sorter.go` 中的枚举 `InstallOrder` 给出(请参阅 Helm 源代码文件)。

模板和值

Helm 图表模板是用 Go 模板语言 编写的,并添加了 50 多个来自 Sprig 库 的附加模板函数和一些其他 专用函数

所有模板文件都存储在图表的 `templates/` 文件夹中。当 Helm 渲染图表时,它将通过模板引擎传递该目录中的每个文件。

模板值以两种方式提供

  • 图表开发者可以在图表中提供一个名为 `values.yaml` 的文件。此文件可以包含默认值。
  • 图表用户可以提供一个包含值的 YAML 文件。这可以通过 `helm install` 在命令行中提供。

当用户提供自定义值时,这些值将覆盖图表 `values.yaml` 文件中的值。

模板文件

模板文件遵循编写 Go 模板的标准约定(有关详细信息,请参阅 text/template Go 包文档)。示例模板文件可能如下所示

apiVersion: v1
kind: ReplicationController
metadata:
  name: deis-database
  namespace: deis
  labels:
    app.kubernetes.io/managed-by: deis
spec:
  replicas: 1
  selector:
    app.kubernetes.io/name: deis-database
  template:
    metadata:
      labels:
        app.kubernetes.io/name: deis-database
    spec:
      serviceAccount: deis-database
      containers:
        - name: deis-database
          image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }}
          imagePullPolicy: {{ .Values.pullPolicy }}
          ports:
            - containerPort: 5432
          env:
            - name: DATABASE_STORAGE
              value: {{ default "minio" .Values.storage }}

以上示例(松散地基于 https://github.com/deis/charts)是 Kubernetes 复制控制器的模板。它可以使用以下四个模板值(通常在 `values.yaml` 文件中定义)

  • `imageRegistry`:Docker 镜像的源注册表。
  • `dockerTag`:Docker 镜像的标签。
  • `pullPolicy`:Kubernetes 拉取策略。
  • `storage`:存储后端,其默认值为 `“minio”`

所有这些值都是由模板作者定义的。Helm 不需要或规定参数。

要查看许多工作图表,请查看 CNCF Artifact Hub

预定义值

通过 `values.yaml` 文件(或通过 `--set` 标志)提供的值可以通过模板中的 `.`Values` 对象访问。但是,您可以在模板中访问其他预定义的数据。

以下值是预定义的,对每个模板都可用,并且不可覆盖。与所有值一样,名称区分大小写。

  • `Release.Name`:版本名称(不是图表名称)
  • `Release.Namespace`:图表发布到的命名空间。
  • `Release.Service`:执行发布的服务。
  • `Release.IsUpgrade`:如果当前操作是升级或回滚,则将其设置为 true。
  • `Release.IsInstall`:如果当前操作是安装,则将其设置为 true。
  • `Chart`:`Chart.yaml` 的内容。因此,图表版本可以通过 `Chart.Version` 获取,维护者在 `Chart.Maintainers` 中。
  • `Files`:一个类似地图的对象,包含图表中所有非特殊文件。这不会让您访问模板,但会让您访问存在的其他文件(除非使用 `.helmignore` 排除)。可以使用 `{{ index .Files "file.name" }}` 或 `{{.Files.Get name }}` 函数访问文件。您还可以使用 `{{ .Files.GetBytes }}` 作为 `[]byte` 访问文件内容
  • `Capabilities`:一个类似地图的对象,包含有关 Kubernetes 版本(`{{ .Capabilities.KubeVersion }}`)和支持的 Kubernetes API 版本(`{{ .Capabilities.APIVersions.Has "batch/v1" }}`)的信息

注意:任何未知的 `Chart.yaml` 字段将被丢弃。它们在 `Chart` 对象内部将不可访问。因此,`Chart.yaml` 不能用来将任意结构化的数据传递到模板中。不过,可以使用 values 文件来实现。

Values 文件

考虑到上一节中的模板,一个提供必要值的 `values.yaml` 文件将如下所示

imageRegistry: "quay.io/deis"
dockerTag: "latest"
pullPolicy: "Always"
storage: "s3"

Values 文件使用 YAML 格式。图表可能包含一个默认的 `values.yaml` 文件。Helm install 命令允许用户通过提供额外的 YAML 值来覆盖值

$ helm install --generate-name --values=myvals.yaml wordpress

当以这种方式传递值时,它们将被合并到默认的 values 文件中。例如,考虑一个名为 `myvals.yaml` 的文件,它看起来像这样

storage: "gcs"

当它与图表中的 `values.yaml` 合并时,生成的最终内容将是

imageRegistry: "quay.io/deis"
dockerTag: "latest"
pullPolicy: "Always"
storage: "gcs"

注意,只有最后一个字段被覆盖了。

注意:图表中包含的默认 values 文件 *必须* 命名为 `values.yaml`。但是,在命令行上指定的任何文件都可以用任意名称。

注意:如果在 `helm install` 或 `helm upgrade` 上使用了 `--set` 标记,那么这些值将在客户端简单地转换为 YAML。

注意:如果 values 文件中存在任何必需的条目,则可以通过使用 'required' 函数 在图表模板中声明它们是必需的

然后,这些值可以在模板中使用 `。Values` 对象访问

apiVersion: v1
kind: ReplicationController
metadata:
  name: deis-database
  namespace: deis
  labels:
    app.kubernetes.io/managed-by: deis
spec:
  replicas: 1
  selector:
    app.kubernetes.io/name: deis-database
  template:
    metadata:
      labels:
        app.kubernetes.io/name: deis-database
    spec:
      serviceAccount: deis-database
      containers:
        - name: deis-database
          image: {{ .Values.imageRegistry }}/postgres:{{ .Values.dockerTag }}
          imagePullPolicy: {{ .Values.pullPolicy }}
          ports:
            - containerPort: 5432
          env:
            - name: DATABASE_STORAGE
              value: {{ default "minio" .Values.storage }}

范围、依赖项和 Values

Values 文件可以为顶层图表以及该图表 `charts/` 目录中包含的任何图表声明值。或者,换句话说,一个 values 文件可以为图表以及它的任何依赖项提供值。例如,上面的演示 WordPress 图表既有 `mysql` 也有 `apache` 作为依赖项。Values 文件可以为所有这些组件提供值

title: "My WordPress Site" # Sent to the WordPress template

mysql:
  max_connections: 100 # Sent to MySQL
  password: "secret"

apache:
  port: 8080 # Passed to Apache

更高级别的图表可以访问所有在它之下的定义的变量。因此,WordPress 图表可以访问 MySQL 密码作为 `。Values.mysql.password`。但较低级别的图表不能访问父图表中的内容,因此 MySQL 将无法访问 `title` 属性。同样,它也不能访问 `apache.port`。

Values 是有命名空间的,但命名空间会被修剪。因此,对于 WordPress 图表,它可以访问 MySQL 密码字段作为 `。Values.mysql.password`。但是对于 MySQL 图表,值的范围已经缩小,并且命名空间前缀被删除,所以它只会看到密码字段为 `。Values.password`。

全局 Values

从 2.0.0-Alpha.2 版本开始,Helm 支持特殊的 "全局" 值。考虑下面这个修改后的示例

title: "My WordPress Site" # Sent to the WordPress template

global:
  app: MyWordPress

mysql:
  max_connections: 100 # Sent to MySQL
  password: "secret"

apache:
  port: 8080 # Passed to Apache

上面添加了一个 `global` 部分,其值为 `app: MyWordPress`。这个值对 *所有* 图表都是可用的,作为 `。Values.global.app`。

例如,`mysql` 模板可以像 `{{ .Values.global.app}}` 那样访问 `app`,`apache` 图表也可以访问。实际上,上面的 values 文件会像这样重新生成

title: "My WordPress Site" # Sent to the WordPress template

global:
  app: MyWordPress

mysql:
  global:
    app: MyWordPress
  max_connections: 100 # Sent to MySQL
  password: "secret"

apache:
  global:
    app: MyWordPress
  port: 8080 # Passed to Apache

这提供了一种与所有子图表共享一个顶层变量的方法,这对于设置 `metadata` 属性(如标签)等操作非常有用。

如果子图表声明了一个全局变量,那么这个全局变量将被传递 *向下*(到子图表的子图表),但不会传递 *向上* 到父图表。子图表无法影响父图表的值。

此外,父图表的全局变量优先于子图表的全局变量。

Schema 文件

有时,图表维护者可能希望在他们的 values 上定义一个结构。这可以通过在 `values.schema.json` 文件中定义一个 schema 来实现。Schema 以 JSON Schema 的形式表示。它可能看起来像这样

{
  "$schema": "https://json-schema.fullstack.org.cn/draft-07/schema#",
  "properties": {
    "image": {
      "description": "Container Image",
      "properties": {
        "repo": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      },
      "type": "object"
    },
    "name": {
      "description": "Service name",
      "type": "string"
    },
    "port": {
      "description": "Port",
      "minimum": 0,
      "type": "integer"
    },
    "protocol": {
      "type": "string"
    }
  },
  "required": [
    "protocol",
    "port"
  ],
  "title": "Values",
  "type": "object"
}

这个 schema 将被应用到 values 来验证它。当执行以下任何命令时,都会进行验证

  • helm install
  • helm upgrade
  • helm lint
  • helm template

满足这个 schema 要求的 `values.yaml` 文件示例可能如下所示

name: frontend
protocol: https
port: 443

注意,schema 被应用于最终的 `。Values` 对象,而不仅仅是 `values.yaml` 文件。这意味着下面的 `yaml` 文件是有效的,前提是图表是以下面显示的适当 `--set` 选项安装的。

name: frontend
protocol: https
helm install --set port=443

此外,最终的 `。Values` 对象会针对 *所有* 子图表 schema 进行检查。这意味着子图表上的限制不能被父图表绕过。这反过来也是有效的 - 如果子图表有一个在子图表的 `values.yaml` 文件中没有满足的 requirement,那么父图表 *必须* 满足这些限制才能有效。

参考资料

在编写模板、values 和 schema 文件时,有几个标准的参考资料可以帮助你。

自定义资源定义 (CRD)

Kubernetes 提供了一种机制来声明新的 Kubernetes 对象类型。使用自定义资源定义 (CRD),Kubernetes 开发人员可以声明自定义资源类型。

在 Helm 3 中,CRD 被视为一种特殊的对象类型。它们在图表中的其余部分之前被安装,并且有一些限制。

CRD YAML 文件应该放在图表内部的 `crds/` 目录中。多个 CRD(由 YAML 开始和结束标记分隔)可以放在同一个文件中。Helm 将尝试将 `CRD` 目录中的 *所有* 文件加载到 Kubernetes 中。

CRD 文件 *不能被模板化*。它们必须是纯 YAML 文档。

当 Helm 安装一个新的图表时,它将上传 CRD,暂停直到 CRD 被 API 服务器提供,然后启动模板引擎,渲染图表中的其余部分,并将其上传到 Kubernetes。由于这种顺序,CRD 信息在 Helm 模板中的 `。Capabilities` 对象中可用,并且 Helm 模板可以创建在 CRD 中声明的对象的新实例。

例如,如果你的图表在 `crds/` 目录中有一个 `CronTab` 的 CRD,那么你可以在 `templates/` 目录中创建 `CronTab` 类型的实例

crontabs/
  Chart.yaml
  crds/
    crontab.yaml
  templates/
    mycrontab.yaml

`crontab.yaml` 文件必须包含没有模板指令的 CRD

kind: CustomResourceDefinition
metadata:
  name: crontabs.stable.example.com
spec:
  group: stable.example.com
  versions:
    - name: v1
      served: true
      storage: true
  scope: Namespaced
  names:
    plural: crontabs
    singular: crontab
    kind: CronTab

然后,模板 `mycrontab.yaml` 可以创建一个新的 `CronTab`(使用模板作为通常的方法)

apiVersion: stable.example.com
kind: CronTab
metadata:
  name: {{ .Values.name }}
spec:
   # ...

Helm 将确保 `CronTab` 类型的 CRD 已经安装,并且可以在 Kubernetes API 服务器上使用,然后它才会继续安装 `templates/` 中的内容。

CRD 的限制

与 Kubernetes 中的大多数对象不同,CRD 是全局安装的。出于这个原因,Helm 在管理 CRD 时非常谨慎。CRD 受到以下限制

  • CRD 从不重新安装。如果 Helm 确定 `crds/` 目录中的 CRD 已经存在(无论版本如何),Helm 不会尝试安装或升级。
  • CRD 从不在升级或回滚时安装。Helm 只有在安装操作时才会创建 CRD。
  • CRD 从不删除。删除 CRD 会自动删除群集中所有命名空间中的所有 CRD 内容。因此,Helm 不会删除 CRD。

希望升级或删除 CRD 的操作者应手动操作,并格外小心。

使用 Helm 管理图表

`helm` 工具有几个用于处理图表的命令。

它可以为你创建一个新的图表

$ helm create mychart
Created mychart/

编辑完图表后, `helm` 可以将其打包成一个图表归档文件

$ helm package mychart
Archived mychart-0.1.-.tgz

你还可以使用 `helm` 来帮助你找到图表格式或信息中的问题

$ helm lint mychart
No issues found

图表仓库

一个 *图表仓库* 是一个 HTTP 服务器,它包含一个或多个打包的图表。虽然 `helm` 可以用来管理本地图表目录,但在共享图表时,首选的机制是图表仓库。

任何可以提供 YAML 文件和 tar 文件并且可以回答 GET 请求的 HTTP 服务器都可以用作仓库服务器。Helm 团队测试了一些服务器,包括启用了网站模式的 Google Cloud Storage,以及启用了网站模式的 S3。

一个仓库的主要特征是存在一个名为 `index.yaml` 的特殊文件,其中包含仓库提供的所有包的列表,以及用于检索和验证这些包的元数据。

在客户端,仓库使用 `helm repo` 命令进行管理。但是,Helm 没有提供将图表上传到远程仓库服务器的工具。这是因为这样做会对实现服务器增加大量的要求,从而提高了设置仓库的门槛。

图表启动包

`helm create` 命令接受一个可选的 `--starter` 选项,它允许你指定一个 "启动图表"。此外,`starter` 选项还有一个简短的别名 `-p`。

使用示例

helm create my-chart --starter starter-name
helm create my-chart -p starter-name
helm create my-chart -p /absolute/path/to/starter-name

启动器只是普通的图表,但它们位于 `$XDG_DATA_HOME/helm/starters` 中。作为图表开发者,你可以创建专门设计为启动器使用的图表。这些图表在设计时应考虑到以下因素

  • `Chart.yaml` 将被生成器覆盖。
  • 用户希望修改这种图表的內容,所以文档应该说明用户如何做到这一点。
  • 所有出现的 `<CHARTNAME>` 将被指定的图表名称替换,以便启动图表可以用作模板,但某些变量文件除外。例如,如果你在 `vars` 目录或某些 `README.md` 文件中使用自定义文件,那么 `<CHARTNAME>` 不会在它们内部被覆盖。此外,图表描述不会被继承。

目前,将图表添加到 `$XDG_DATA_HOME/helm/starters` 的唯一方法是手动将其复制到那里。你可能希望在图表的文档中解释这个过程。