管理 Helm 发布

已完成

如何在 Helm 模板中使用函数

可以使用 Helm 模板语言定义用于转换 values.yaml 文件中的值的函数。 函数的语法遵循 {{ functionName arg1 arg2 ... }} 结构。 让我们以 quote 函数为例,看看如何使用此语法。

quote 函数使用引号将值括起来,以指示使用了 string。 假设你定义了下面的 values.yaml 文件:

apiVersion: v2
name: webapp
description: A Helm chart for Kubernetes
ingress:
  enabled: true

在确定是否应生成入口清单时,你决定将 ingress.enabled 值用作布尔值。 若要将 enabled 值用作布尔值,请使用 {{ .Values.ingress.enabled }} 引用该值。

稍后,你决定将该字段显示为 templates/Notes.txt 文件中的字符串。 由于 YAML 类型强制转换规则可能会导致难以找到模板中的 bug,因此你决定按照指南操作,并在模板中包含字符串时明确说明。 例如,enabled: false 不等于 enabled: "false"

若要将值显示为字符串,请使用 {{ quote .Values.ingress.enabled }} 将布尔值作为字符串进行引用。

如何在 Helm 模板中使用管道

当多个函数需要对某个值执行操作时,可以使用管道。 管道允许将值或将函数结果发送给另一个函数。 例如,你可以将上面的 quote 函数重新编写为 {{ .Values.ingress.enabled | quote }}。 请注意 | 如何指示将该值发送给 quote 函数。

再提供一个示例。 假设你要将值转换为大写,并用引号引起来。 你可以将语句编写为 {{ .Values.ingress.enabled | upper | quote }}。 请注意值如何依次由 upper 函数和 quote 函数进行处理。

模板语言包括了 60 多个函数,你可以使用它们在模板中公开、查找以及转换值和对象。

如何在 Helm 模板中使用条件流控制

条件流控制允许你决定生成的清单文件中包含的结构或数据。 例如,你可能想要根据部署目标包括不同的值,或者控制是否生成清单文件。

if / else 块是这样的一个控制流结构,它符合以下布局:

{{ if | pipeline | }}
  # Do something
{{ else if | other pipeline | }}
  # Do something else
{{ else }}
  # Default case
{{ end }}

假设你决定仅在特定情况下创建图表的入口清单文件。 以下示例演示如何使用 if 语句来实现此任务:

{{ if .Values.ingress.enabled }}
apiVersion: extensions/v1
kind: Ingress
metadata:
  name: ...
  labels:
    ...
  annotations:
    ...
spec:
  rules:
    ...
{{ end }}

请记住,你可以使用占位符填充模板中的元数据。 模板文件按模板语言以从上到下的顺序进行分析和评估。 在上面的示例中,模板引擎仅在 .Values.ingress.enabled 值为 true 时才生成清单文件的内容。

当模板引擎处理该语句时,它会移除在 {{ }} 语法中声明的内容,并且会保留空格。 此语法导致模板引擎为 if 语句行包括一个换行符。 如果保留上述文件的内容不变,则 YAML 中会出现空行,并且会生成入口清单文件。

YAML 认为空格是有意义的。 这就是制表符、空格和换行符非常重要的原因。 若要修复不需要的空格的问题,可以重新编写此文件,如下所示:

{{- if .Values.ingress.enabled -}}
apiVersion: extensions/v1
kind: Ingress
metadata:
  name: ...
  labels:
    ...
  annotations:
    ...
spec:
  rules:
    ...
{{- end }}

请注意,在语句的 {{- 开始序列和 -}} 结束序列中使用了 - 字符。 - 字符会指示分析器删除空白字符。 {{- 删除行开头的空格和行末尾的 -}}(包括换行符)。

如何循环访问 Helm 模板中的值集合

YAML 允许你定义项的集合,并将各个项用作模板中的值。 可以使用索引器访问集合中的项。 但是,Helm 模板语言支持使用 range 运算符循环访问值集合。

假设你在 values.yaml 文件中定义了值的列表来指示其他入口主机。 下面是值的示例:

ingress:
  enabled: true
  extraHosts:
    - name: host1.local
      path: /
    - name: host2.local
      path: /
    - name: host3.local
      path: /

你使用 range 运算符允许模板引擎循环访问 .Values.ingress.extraHosts。 以下代码片段显示了一个使用 range 运算符的简化示例:

{{- if .Values.ingress.enabled -}}
apiVersion: extensions/v1
kind: Ingress
metadata:
  ...
spec:
  rules:
    ...
    {{- range .Values.ingress.extraHosts }}
    - host: {{ .name }}
      http:
        paths:
          - path: {{ .path }}
            ...
    {{- end }}
  ...
{{- end }}

如何控制 Helm 模板中的值的范围

如果在多个层中定义了值,则在模板中包括这些值时,语法可能会变得冗长且繁琐。 with 操作允许你限制模板中的变量的作用域。

请记住,Helm 模板中使用的 . 会引用当前范围。 例如,.Values 指示模板引擎在当前作用域中查找 Values 对象。 假设你正在使用前面的 values.yaml 文件来创建配置映射清单文件:

ingress:
  enabled: true
  extraHosts:
    - name: host1.local
      path: /
    - name: host2.local
      path: /
    - name: host3.local
      path: /

你可以使用 with 操作,而不是使用 {{ .Values.ingress.extraHosts.path }} 来访问每个项的路径值。 下面的代码片段显示了一个示例,该示例使用 range 运算符生成配置映射清单文件:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  {{- with .Values.ingress.extraHosts }}
  hostname: {{ .name }}
  path: {{ .path }}
  {{ end }}

{{- with .Values.ingress.extraHosts }} 将值的作用域限制为 .Values.ingress.extraHosts 数组。

with 操作限制作用域。 你无法从父作用域访问其他对象。 假设你还想在 with 代码块中访问图表的 {{ .Release.Name }}。 若要访问父对象,需要使用 $ 字符来指示根作用域,或者重新编写代码。 下面是更新后的代码,展示了如何使用 $ 字符来包括父对象:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  {{- with .Values.ingress.extraHosts }}
  hostname: {{ .name }}
  path: {{ .path }}
  release: {{ $.Release.Name}}
  {{ end }}

注意

Helm 模板语言提供了几个用来控制流的构造。 此模块的总结单元的一个部分中包含指向 Helm 文档的链接,可以用来了解详细信息。

Helm 如何定义图表依赖项

图表允许声明依赖项以支持主要应用程序,构成已安装版本的一部分。

A diagram shows how Helm deploys all subcharts as dependencies of the main chart to a Kubernetes cluster.

你可以使用 helm create 命令创建一个子图表,在 /charts 文件夹中指定新图表的位置,也可以使用 helm dependency 命令。 请记住,/charts 文件夹可能包含在主图表发布过程中部署的子图表。

helm dependency 命令允许你管理从 Helm 存储库包括的依赖项。 此命令使用在图表的值文件的 dependencies 节中定义的元数据。 你需要指定名称、版本号和从中安装子图表的存储库。 下面是 values.yaml 文件的摘录,其中包含作为依赖项列出的一个 MongoDB 图表:

apiVersion: v2
name: my-app
description: A Helm chart for Kubernetes
...
dependencies:
  - name: mongodb
    version: 10.27.2
    repository: https://marketplace.azurecr.io/helm/v1/repo

定义依赖项元数据后,你将运行 helm dependency build 命令来提取 tar 打包图表。 图表 build 命令将图表下载到 charts/ 文件夹中。

helm dependency build ./app-chart

子图表与主图表分开管理,在有新版本可用时可能需要更新。 用于更新子图表的命令是 helm dependency update。 此命令会在删除过时的包时提取子图表的新版本。

helm dependency update ./app-chart

请记住,图表依赖项不限于其他应用程序。 你可能决定跨图表重复使用模板逻辑,并创建一个依赖项,专门用于将此逻辑作为图表依赖项进行管理。 在下一个练习中,你会看到此策略的示例。

如何升级 Helm 发布

Helm 允许将现有发布升级为应用于图表及其依赖项的所有更改的增量。

A diagram shows how the Helm upgrade command creates a delta of all changed items in a Helm chart to upgrade a release and create a new release revision on a Kubernetes cluster.

例如,假设本单元中 webapp 示例的开发团队进行仅影响网站功能的代码更改。 该团队对 Chart.yaml 文件进行了以下更新来反映应用程序的新版本:

  • 在将 Web 应用的容器映像推送到容器注册表时更新该映像,并将映像标记为 webapp: linux-v2
  • 在图表的值文件中将 dockerTag 值更新为 linux-v2,将图表版本值更新为 0.2.0

下面是已更新的 values.yaml 文件示例:

apiVersion: v2
name: my-app
description: A Helm chart for Kubernetes

type: application

version: 0.2.0
appVersion: 1.0.0

registry: "my-acr-registry.azurecr.io"
dockerTag: "linux-v2"
pullPolicy: "Always"

你将使用 helm upgrade 命令来升级现有的 Helm 版本,而不是卸载当前版本。

helm upgrade my-app ./app-chart

请记住,在升级版本时,Helm 会生成对 Helm 图表所做更改的增量。 因此,Helm 升级将仅升级增量中标识的组件。 在此示例中,只会重新部署网站。

升级完成后,可使用 helm history 命令和版本名称查看版本的部署历史记录。

helm history my-app

history 命令返回描述版本的多个字段,如以下示例输出中所示:

REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION
1               Mon Oct 11 17:25:33 2021        deployed        aspnet-core-1.3.18      3.1.19          Install complete

请注意结果中的 revision 字段。 Helm 跟踪为 Helm 图表完成的所有发布的发布信息。 安装新版本的 Helm 图表时,修订版计数将增加 1,新发布信息将与该修订匹配。

下面是在安装 Web 应用的新版本后运行相同的 history 命令的示例:

REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION
1               Mon Oct 11 17:25:33 2021        superseded      aspnet-core-1.3.18      3.1.19          Install complete
2               Mon Oct 11 17:35:13 2021        deployed        aspnet-core-1.3.18      3.1.19          Upgrade complete

如何回滚 Helm 发布

Helm 允许将现有的 Helm 发布回滚到以前安装的发布。 如前所述,Helm 会跟踪 Helm 图表的所有版本的版本信息。

可以使用 helm rollback 命令回滚到特定的 Helm 发布修订版。 此命令使用两个参数。 第一个参数标识发布名称,第二个参数标识发布修订号。

helm rollback my-app 2

helm rollback 命令会将该应用的发布版本回滚到指定的修订版,并更新应用版本历史记录。 helm history 命令的后续运行会将最新的有效修订号显示为最新的版本条目。

例如,假设本单元中 webapp 示例的开发团队发现无人机跟踪 Web 应用程序中有一个 bug,需要回滚到以前的版本。 你可以回滚到正常工作的版本,而不必卸载当前版本,然后再安装以前的版本。

helm rollback my-app 1

回滚完成后,可以使用 helm history 命令查看部署历史记录。

REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION
1               Mon Oct 11 17:25:33 2021        superseded      aspnet-core-1.3.18      3.1.19          Install complete
2               Mon Oct 11 17:35:13 2021        superseded      aspnet-core-1.3.18      3.1.19          Rolled back to 1
3               Mon Oct 11 17:38:13 2021        deployed        aspnet-core-1.3.18      3.1.19          Upgrade complete

请注意 description 字段如何显示回滚的修订号以使你可以更轻松地跟踪更改。

知识检查

1.

假设你有一个软件解决方案,其中包含两个关键组件:一个 Web 应用程序和一个处理在线订单的服务。 这两个组件都是在线订单处理管道的一部分,但它们并不相互依赖。 使用 Helm 部署这两个应用程序的最合适策略是什么?

2.

假设你有一个软件解决方案,它的其中一个关键组件是网站。 网站是依赖于缓存服务的唯一组件。 使用 Helm 部署这两个应用程序的最合适策略是什么?