子图表和全局值
到目前为止,我们只处理了一个图表。但图表可以有依赖项,称为子图表,它们也有自己的值和模板。在本节中,我们将创建一个子图表,并了解在模板中访问值的几种不同方式。
在我们深入代码之前,需要了解一些关于应用程序子图表的重要细节。
- 子图表被认为是“独立的”,这意味着子图表永远不能显式地依赖于其父图表。
- 因此,子图表无法访问其父图表的值。
- 父图表可以覆盖子图表的值。
- 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.yaml
和mysubchart/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
图表可以从任何其他图表中包含。
虽然图表开发者可以在include
和template
之间进行选择,但使用include
的一个优势是,include
可以动态引用模板
{{ include $mytemplate }}
以上将取消引用$mytemplate
。相比之下,template
函数只能接受字符串字面量。
避免使用块
Go 模板语言提供了一个block
关键字,允许开发者提供一个默认实现,该实现将在稍后被覆盖。在 Helm 图表中,块不是覆盖的最佳工具,因为如果提供了相同块的多个实现,则选择的实现是不可预测的。
建议改用include
。