Helm
常用命令
|
|
--set
定制安装
当你安装 Helm charts 时,你可以通过两种方式传递配置数据,让安装更符合你的需求:
- 使用
--values
参数(或者-f
简写):通过指定一个 YAML 文件来覆盖默认的 values,这个文件中可以指定多个值,最终会使用文件中最后出现的值。 - 使用
--set
参数:直接在命令行上指定要覆盖的配置。
如果你同时使用这两个参数,那么 --values
(或 -f
)的值会被合并到具有更高优先级的 --set
中。使用 --set
指定的值会被持久化在 ConfigMap 中,你可以通过运行 helm get values <release-name>
命令来查看已经设置的值。你也可以通过运行 helm upgrade
并指定 --reset
参数来清除已设置的值。
--set
选项可以接受零个或多个名/值对。最简单的用法是 --set name=value
,这相当于在 YAML 文件中写入:
|
|
你也可以用逗号分隔多个值,比如 --set a=b,c=d
,相当于在 YAML 文件中写入:
|
|
--set
还支持更复杂的表达式,比如 --set outer.inner=value
,对应的 YAML 结构为:
|
|
对于列表数组,可以使用大括号来包裹,比如 --set name={a, b, c}
,对应的 YAML 结构为:
|
|
从 Helm 2.5.0 开始,你还可以使用数组索引语法来访问列表中的某个项,比如 --set servers[0].port=80
,对应的 YAML 结构为:
|
|
你也可以一次设置多个值,比如 --set servers[0].port=80,servers[0].host=example
,对应的 YAML 结构为:
|
|
有时候你可能需要在 --set
选项中使用特殊字符,这时可以使用反斜杠来转义字符,比如 --set name=value1\,value2
,对应的 YAML 结构为:
|
|
同样地,你也可以转义点号(.)。这在 chart 模板中使用 toYaml
函数来解析 annotations、labels 以及 node selectors 等时非常有用。比如 --set nodeSelector."kubernetes\.io/role"=master
,对应的 YAML 结构为:
|
|
Chart 文件目录结构
|
|
Values
内置的 Values
Helm 有一些预定义的对象和值,这些可以在模板中使用。以下是一些主要的预定义值:
-
.Release
: 在 Helm 运行时自动提供的。这些值包括 Helm release 的详细信息,如名称、命名空间、是否为升级操作等。在你的示例中,{{ .Release.Name }}
将被替换为当前 Helm release 的名称。例如,如果你使用helm install my-release my-chart
命令安装 chart,那么{{ .Release.Name }}
将被替换为my-release
。这个对象描述了 release 本身。它有几个预定义的值,包括:.Release.Name
: release 的名称。.Release.Namespace
: release 被安装的命名空间。.Release.IsUpgrade
: 这是一个布尔值,表示当前操作是否是一个升级操作。.Release.IsInstall
: 这是一个布尔值,表示当前操作是否是一个安装操作。.Release.Revision
: 当前 release 的修订版本号。
-
.Values
: 这个对象包含了values.yaml
文件中定义的值。 -
.Chart
: 来自于 Helm chart 的Chart.yaml
文件。这个文件包含了 chart 的元数据,例如 chart 的名称、版本、描述等。它有几个预定义的值,包括:.Chart.Name
: chart 的名称。.Chart.Version
: chart 的版本。.Chart.AppVersion
: chart 的 app 版本。
-
.Files
: 来自 Helm chart 的文件系统。这个对象提供了一种方法,可以让你在模板中访问 chart 文件夹中的非模板文件。例如,如果你的 chart 文件夹中有一个名为config.ini
的文件,你可以在模板中使用{{ .Files.Get "config.ini" }}
来获取该文件的内容。 -
.Capabilities
: 来自 Helm 运行时环境,它提供了关于 Kubernetes 集群的信息。这些信息包括 Kubernetes 的版本、API 版本、Helm 版本等。例如,.Capabilities.KubeVersion
提供了 Kubernetes 的版本信息,.Capabilities.APIVersions.Has "batch/v1"
可以用来检查 Kubernetes 集群是否支持batch/v1
API 版本。 -
.Template
: 来自 Helm 的运行时环境。这个对象包含了关于当前正在执行的模板的信息。例如,.Template.Name
提供了当前模板的名称(包括路径),.Template.BasePath
提供了当前 chart 的模板目录的路径。
全局的 Values
- 全局值是可以从任何图表或子图表通过完全相同的名称访问的值。全局值需要明确声明,不能将现有的非全局值当作全局值使用。
- Values 数据类型有一个名为 Values.global 的保留部分,可以在其中设置全局值。例如,在
mychart/values.yaml
文件中设置一个全局值。 - 由于全局值的工作方式,
mychart/templates/configmap.yaml
和mysubchart/templates/configmap.yaml
都应该能够以{{ .Values.global.salad }}
的形式访问该值。 - 如果我们进行干运行安装,我们将在两个输出中看到相同的值。
- 全局值对于传递这样的信息很有用,尽管需要一些规划来确保正确的模板被配置为使用全局值。
- 父图表和子图表可以共享模板。任何图表中定义的块都可以供其他图表使用。
- 我们可以定义一个简单的模板,如
{{- define "labels" }}from: mychart{{ end }}
。请记住,模板上的标签是全局共享的。因此,标签图表可以从任何其他图表中包含。 - 虽然图表开发者可以在
include
和template
之间选择,但使用include
的一个优点是include
可以动态引用模板:{{ include $mytemplate }}
。上述将解引用$mytemplate
。相比之下,template
函数只接受字符串字面量。 - 避免使用块。Go 模板语言提供了一个
block
关键字,允许开发者提供一个默认实现,后续可以覆盖。在 Helm 图表中,块不是最好的覆盖工具,因为如果提供了同一块的多个实现,选择哪一个是不可预测的。建议使用include
。
Custom Resource Definitions
以下是关于 Helm 中自定义资源定义(CRDs)的一些关键点:
-
CRD 有两个部分:CRD 的声明(
kind: CustomResourceDefinition
的 YAML 文件)和使用 CRD 的资源(例如,如果 CRD 定义了foo.example.com/v1
,那么任何apiVersion: example.com/v1
和kind: Foo
的资源都是使用该 CRD 的资源)。 -
在使用 CRD 的资源之前,必须先安装 CRD 的声明。这是因为 Kubernetes 需要一些时间来注册 CRD。
-
Helm 3 提供了一个名为
crds
的特殊目录,你可以在这个目录中放置你的 CRDs。这些 CRDs 不会被模板化,但在运行 helm 安装 chart 时会默认安装。如果 CRD 已经存在,它将被跳过并给出警告。如果你希望跳过 CRD 的安装步骤,你可以传递--skip-crds
标志。 -
目前,Helm 不支持升级或删除 CRDs。这是经过社区讨论后的明确决定,因为这可能导致数据意外丢失。此外,目前社区对于如何处理 CRDs 及其生命周期还没有达成共识。随着这个问题的发展,Helm 将添加对这些用例的支持。
-
Helm 的
--dry-run
标志目前不支持 CRDs。这是因为 “Dry Run” 的目的是验证 chart 的输出是否可以在发送到服务器后正常工作。但是,CRDs 实际上是修改了服务器的行为。Helm 无法在 dry run 中安装 CRD,因此 discovery 客户端将不知道该自定义资源(CR),并且验证将失败。 -
另一种处理 CRD 的方法是将 CRD 定义放在一个 chart 中,然后将使用该 CRD 的任何资源放在另一个 chart 中。在这种方法中,每个 chart 必须单独安装。然而,这种工作流可能对具有集群管理员访问权限的集群运维人员更有用。
Chart 示例
|
|
函数库
Helm 模板支持以下函数库:
-
Sprig: Sprig 是一个 Go 语言的函数库,提供了一系列用于处理字符串、日期、字典、加密等常见任务的函数。例如,你可以使用
trim
函数来删除字符串的前导和尾随空格,或者使用upper
函数将字符串转换为大写。 -
Helm 内置函数: Helm 还提供了一些内置函数,例如
include
用于包含并解析其他模板,required
用于声明某个值是必需的,如果该值为空或不存在,Helm 将停止并返回错误。 -
Pipelines and flow control: Helm 模板支持 Go 语言的管道和流控制结构,例如
if
、else
、with
、range
等。 -
Values functions: Helm 还提供了一些函数用于处理 values 文件中的值,例如
.Values
用于访问 values 文件中的值,.Files
用于访问 chart 中的文件,.Capabilities
用于访问 Kubernetes 集群的功能。 -
Chart functions: Helm 还提供了一些函数用于处理 chart,例如
.Chart
用于访问 chart 的元数据,.Release
用于访问 release 的信息,.Template
用于访问当前模板的信息。
Named Templates
- Named Templates,也被称为 partials 或 subtemplates,是在文件中定义并赋予名称的模板。
- 在命名模板时,模板名称是全局的。如果声明了两个同名的模板,最后加载的那个将被使用。
- 为了避免命名冲突,一种常见的命名约定是在每个定义的模板前加上图表的名称,例如:
{{ define "mychart.labels" }}
。 - 文件名以下划线(_)开头的文件被认为不包含清单。这些文件不会被渲染为 Kubernetes 对象定义,但可以在其他图表模板中使用。
define
动作允许我们在模板文件中创建一个命名模板。例如,我们可以定义一个模板来封装 Kubernetes 的标签块。template
动作允许我们在现有的 ConfigMap 中嵌入这个模板,然后使用template
动作来包含它。include
函数允许我们将模板的内容导入到当前的管道中,其中它可以被传递给管道中的其他函数。- 在定义的模板中,我们可以包含图表名称和图表版本。如果我们在渲染时遇到错误,我们可以通过传递作用域给模板来解决这个问题。
- 在 Helm 模板中,使用
include
而不是template
是更好的选择,因为这样可以更好地处理输出格式化。
访问模板中的文件
在 Helm 中,你可以通过 .Files
对象访问文件。这使得你可以在模板中导入非模板文件,并在不通过模板渲染器处理内容的情况下注入其内容。以下是一些关键点:
- 你可以向 Helm 图表添加额外的文件,这些文件将被打包。但是要注意,由于 Kubernetes 对象的存储限制,图表的大小必须小于 1M。
- 出于安全原因,有些文件不能通过
.Files
对象访问,例如templates/
目录中的文件,被.helmignore
排除的文件,以及 Helm 应用子图表之外的文件。 - Helm 不保留 UNIX 模式信息,因此文件级权限对
.Files
对象可用文件的影响无效。 - 你可以使用
.Files
对象的方法,如Get
,Glob
,Lines
等,来读取文件内容或获取文件列表。 - 你可以使用
AsConfig
和AsSecrets
方法将文件内容放入 ConfigMaps 和 Secrets 中。 - 你可以使用
b64enc
函数将文件内容进行 base-64 编码,以确保成功传输。 - 在 Helm 安装期间,无法传递图表外部的文件。所以如果你要求用户提供数据,必须使用
helm install -f
或helm install --set
来加载。
子 Charts
Subcharts and Global Values 是 Helm 中的两个重要概念。
-
Subcharts:Subcharts 是 Helm chart 的依赖项,它们也有自己的值和模板。Subcharts 被视为 “stand-alone”,这意味着它们不能显式地依赖于其父 chart。因此,Subchart 不能访问其父 chart 的值。但是,父 chart 可以覆盖 Subcharts 的值。
-
Global Values:Helm 有一个全局值的概念,所有的 chart 都可以访问这些值。全局值需要显式声明,不能将现有的非全局值当作全局值使用。全局值可以在
Values.global
中设置。
创建 Subchart 的步骤如下:
- 在
mychart/charts
目录下创建一个新的 chart(例如,mysubchart
)。 - 删除所有基础模板,以便从头开始。
- 在
mysubchart
中创建一个简单的模板和值文件。
父 chart 可以覆盖 Subchart 的值。例如,我们可以在 mychart/values.yaml
中修改 mysubchart
的 dessert
值。
全局值可以被任何 chart 或 subchart 访问。例如,我们可以在 mychart/values.yaml
文件中设置一个全局值 salad
,然后在 mychart/templates/configmap.yaml
和 mysubchart/templates/configmap.yaml
中都可以访问这个值。
父 chart 和 subchart 可以共享模板。任何在任何 chart 中定义的块都可以被其他 chart 使用。例如,我们可以定义一个简单的模板 labels
,然后在任何其他 chart 中都可以包含这个模板。
注意,Go 模板语言提供了一个 block
关键字,允许开发者提供一个默认实现,然后在后面覆盖它。但在 Helm charts 中,block
不是覆盖的最佳工具,因为如果提供了多个相同的 block
实现,选择哪个是不可预测的。建议使用 include
。
Chart Hooks
Helm 提供了一个钩子机制,允许图表开发者在发布生命周期的某些点进行干预。例如,你可以使用钩子来:
- 在安装任何其他图表之前,加载 ConfigMap 或 Secret。
- 在安装新图表之前,执行一个 Job 来备份数据库,然后在升级后执行第二个 Job 来恢复数据。
- 在删除发布之前运行一个 Job,以便在删除服务之前优雅地将其从轮换中移除。
钩子就像常规模板一样工作,但是它们有特殊的注解,使 Helm 以不同的方式使用它们。在这一部分,我们将介绍钩子的基本使用模式。
钩子和发布生命周期 钩子允许你,图表开发者,在发布生命周期的关键点进行操作。例如,考虑 helm install 的生命周期。默认情况下,生命周期如下:
- 用户运行 helm install foo
- 调用 Helm 库安装 API
- 在一些验证之后,库渲染 foo 模板
- 库将生成的资源加载到 Kubernetes
- 库将发布对象(和其他数据)返回给客户端
- 客户端退出
Helm 为安装生命周期定义了两个钩子:pre-install 和 post-install。如果 foo 图表的开发者实现了这两个钩子,生命周期就会像这样改变:
- 用户运行 helm install foo
- 调用 Helm 库安装 API
- 在 crds/ 目录中安装 CRDs
- 在一些验证之后,库渲染 foo 模板
- 库准备执行 pre-install 钩子(将钩子资源加载到 Kubernetes)
- 库按权重(默认为 0)、资源类型和名称的升序对钩子进行排序。
- 然后,库首先加载权重最低的钩子(从负到正)
- 库等待直到钩子处于 “就绪” 状态(除了 CRDs)
- 库将生成的资源加载到 Kubernetes。注意,如果设置了 –wait 标志,库将等待所有资源处于就绪状态,并且在它们就绪之前不会运行 post-install 钩子。
- 库执行 post-install 钩子(加载钩子资源)
- 库等待直到钩子处于 “就绪” 状态
- 库将发布对象(和其他数据)返回给客户端
- 客户端退出
编写钩子 钩子只是带有特殊注解的 Kubernetes 清单文件。因为它们是模板文件,所以你可以使用所有的正常模板功能,包括读取 .Values、.Release 和 .Template。
例如,这个模板,存储在 templates/post-install-job.yaml 中,声明了一个在 post-install 运行的 job:
|
|
使这个模板成为钩子的是注解:
|
|
一个资源可以实现多个钩子:
|
|
同样,对于可以实现给定钩子的不同资源没有限制。例如,可以声明一个 secret 和一个 config map 作为 pre-install 钩子。
当子图表声明钩子时,这些也会被评估。顶级图表无法禁用子图表声明的钩子。
可以为钩子定义一个权重,这将有助于构建一个确定的执行顺序。权重是使用以下注解定义的:
|
|
钩子删除策略 可以定义决定何时删除相应钩子资源的策略。钩子删除策略是使用以下注解定义的:
|
|
你可以选择一个或多个定义的注解值:
注解值 描述 before-hook-creation 在启动新钩子之前删除之前的资源(默认) hook-succeeded 在钩子成功执行后删除资源 hook-failed 如果钩子在执行过程中失败,则删除资源 如果没有指定钩子删除策略注解,则默认应用 before-hook-creation 行为。
NOTES.txt
文件
NOTES.txt
文件会在用户安装或升级 Helm chart 时显示。在这个文件中,我们使用了一些内置的 Helm 模板变量,如 .Chart.Name
和 .Release.Name
,分别表示 chart 的名称和 release 的名称。用户可以通过运行 helm status
和 helm get all
命令来获取更多关于 release 的信息。
|
|
.helmignore
文件
.helmignore
文件用于指定你不希望包含在 Helm chart 中的文件。如果这个文件存在,helm package
命令在打包应用程序时,将忽略所有与.helmignore
文件中指定的模式匹配的文件。这可以帮助避免将不必要的或敏感的文件或目录添加到你的 Helm chart 中。.helmignore
文件支持 Unix shell glob 匹配、相对路径匹配和否定(以 ! 为前缀)。每行只考虑一个模式。
|
|