子图表和全局值

到目前为止,我们只处理了一个图表。但图表可以有依赖项,称为子图表,它们也有自己的值和模板。在本节中,我们将创建一个子图表,并了解在模板中访问值的几种不同方式。

在我们深入代码之前,需要了解一些关于应用程序子图表的重要细节。

  1. 子图表被认为是“独立的”,这意味着子图表永远不能显式地依赖于其父图表。
  2. 因此,子图表无法访问其父图表的值。
  3. 父图表可以覆盖子图表的值。
  4. Helm 有一个全局值的概念,所有图表都可以访问这些值。

这些限制并不一定都适用于库图表,库图表旨在提供标准化的辅助功能。

在我们逐步了解本节中的示例时,许多这些概念将变得更加清晰。

创建子图表

对于这些练习,我们将从本指南开头创建的mychart/图表开始,并在其中添加一个新图表。

$ cd mychart/charts
$ helm create mysubchart
Creating mysubchart
$ rm -rf mysubchart/templates/*

请注意,与之前一样,我们删除了所有基本模板,以便从头开始。在本指南中,我们重点介绍模板的工作方式,而不是管理依赖项。但图表指南中包含有关子图表工作方式的更多信息。

向子图表添加值和模板

接下来,让我们为我们的mysubchart图表创建一个简单的模板和值文件。mychart/charts/mysubchart中应该已经存在一个values.yaml。我们将这样设置它

dessert: cake

接下来,我们在mychart/charts/mysubchart/templates/configmap.yaml中创建一个新的 ConfigMap 模板

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-cfgmap2
data:
  dessert: {{ .Values.dessert }}

因为每个子图表都是一个独立的图表,所以我们可以单独测试mysubchart

$ helm install --generate-name --dry-run --debug mychart/charts/mysubchart
SERVER: "localhost:44134"
CHART PATH: /Users/mattbutcher/Code/Go/src/helm.sh/helm/_scratch/mychart/charts/mysubchart
NAME:   newbie-elk
TARGET NAMESPACE:   default
CHART:  mysubchart 0.1.0
MANIFEST:
---
# Source: mysubchart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: newbie-elk-cfgmap2
data:
  dessert: cake

从父图表覆盖值

我们最初的图表mychart现在是mysubchart图表。这种关系完全基于mysubchart位于mychart/charts中这一事实。

因为mychart是父图表,所以我们可以在mychart中指定配置,并将该配置推送到mysubchart。例如,我们可以像这样修改mychart/values.yaml

favorite:
  drink: coffee
  food: pizza
pizzaToppings:
  - mushrooms
  - cheese
  - peppers
  - onions

mysubchart:
  dessert: ice cream

注意最后两行。mysubchart部分中的任何指令都将发送到mysubchart图表。因此,如果我们运行helm install --generate-name --dry-run --debug mychart,我们将看到其中的一项是mysubchart ConfigMap

# Source: mychart/charts/mysubchart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: unhinged-bee-cfgmap2
data:
  dessert: ice cream

顶层的值现在已经覆盖了子图表的值。

这里有一个重要的细节需要注意。我们没有更改mychart/charts/mysubchart/templates/configmap.yaml的模板以指向.Values.mysubchart.dessert。从该模板的角度来看,该值仍然位于.Values.dessert中。当模板引擎传递值时,它会设置范围。因此,对于mysubchart模板,只有专门针对mysubchart的值才能在.Values中获得。

但是,有时您确实希望某些值对所有模板都可用。这是通过使用全局图表值来实现的。

全局图表值

全局值是可以从任何图表或子图表以完全相同的名称访问的值。全局值需要显式声明。您不能将现有非全局值用作全局值。

Values 数据类型有一个名为Values.global的保留部分,可以在其中设置全局值。让我们在我们的mychart/values.yaml文件中设置一个全局值。

favorite:
  drink: coffee
  food: pizza
pizzaToppings:
  - mushrooms
  - cheese
  - peppers
  - onions

mysubchart:
  dessert: ice cream

global:
  salad: caesar

由于全局值的工作方式,mychart/templates/configmap.yamlmysubchart/templates/configmap.yaml都应该能够以{{ .Values.global.salad }}访问该值。

mychart/templates/configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  salad: {{ .Values.global.salad }}

mysubchart/templates/configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-cfgmap2
data:
  dessert: {{ .Values.dessert }}
  salad: {{ .Values.global.salad }}

现在,如果我们运行一个模拟安装,我们将看到这两个输出中的值都相同

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: silly-snake-configmap
data:
  salad: caesar

---
# Source: mychart/charts/mysubchart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: silly-snake-cfgmap2
data:
  dessert: ice cream
  salad: caesar

全局值对于传递此类信息很有用,尽管这确实需要一些计划,以确保正确配置了使用全局值的模板。

与子图表共享模板

父图表和子图表可以共享模板。任何图表中定义的块都可以供其他图表使用。

例如,我们可以像这样定义一个简单的模板

{{- define "labels" }}from: mychart{{ end }}

回想一下,模板上的标签是全局共享的。因此,labels图表可以从任何其他图表中包含。

虽然图表开发者可以在includetemplate之间进行选择,但使用include的一个优势是,include可以动态引用模板

{{ include $mytemplate }}

以上将取消引用$mytemplate。相比之下,template函数只能接受字符串字面量。

避免使用块

Go 模板语言提供了一个block关键字,允许开发者提供一个默认实现,该实现将在稍后被覆盖。在 Helm 图表中,块不是覆盖的最佳工具,因为如果提供了相同块的多个实现,则选择的实现是不可预测的。

建议改用include