02 Helm模板之内置对象和 Value对象
调试模板可能会很棘手,因为渲染的模板已发送到Kubernetes apiserver,该服务器可能会出于格式化以外的其他原因而拒绝YAML文件。可以通过如下方式进行模板debug:
helm lint验证chart是否遵循最佳实践。helm install --dry-run --debugorhelm template --debug: 让服务器渲染模板,并返回资源清单。helm get manifest: 查看已经安装在k8s中的资源清单。helm template CHART:进行go-template渲染,注意该操作只能检查go-template渲染的语法。渲染成功并不一定能满足k8s的接口规范。
总结:模板指令要写在
{{ }}中
我们可以看到上⾯定义的 ConfigMap 名字是固定的,但往往这并不是⼀种很好的做法,我们可以通过插入 release 的名称来生成资源的名称,比如这里 ConfigMap 的名称我们希望是:values-release-configmap,这就需要用到 Chart 的模板定义方法了。Helm Chart 模板使用的是 Go 语⾔模板编写而成,并添加了 Sprig 库中的50多个附件模板函数以及⼀些其他特殊的函数。
注:需要注意的是 kubernetes 资源对象的 labels 和 name 定义被限制 63个字符,所以需要注意名称的定义。
现在我们来重新定义上面的 configmap.yaml 文件:
➜ ~ vim mychart/templates/configmap.yaml
➜ ~ cat mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
我们将名称替换成了 {{ .Release.Name }}-configmap ,其中包含在 {{ 和 }} 之中的就是模板指令, {{ .Release.Name }} 将 release 的名称注入到模板中来,这样最终生成的 ConfigMap 名称就是以 release 的名称开头的了。这里的 Release 模板对象属于 Helm 内置的⼀种对象,还有其他很多内置的对象,后面我们也会接触到。
现在我们来重新安装 Chart 包,注意观察 ConfigMap 资源对象的名称。为了快速测试chart,我们在使用helm install的时候可以使用--dry-run参数来运行,可以把对应的 values 值和生成的最终的资源清单文件打印出来,而不会真正的去部署⼀个 release 实例。
➜ ~ helm install mychart mychart/ --dry-run
NAME: mychart
LAST DEPLOYED: Tue Feb 23 11:31:25 2021
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"
已经生效了,当然我们也可以使用命令helm get manifest mychart查看最终生成的清单文件的样子。
➜ ~ helm get manifest mychart
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"
可以发现name: mychart-configmap中已经替换成了release的名字。
刚刚我们使用 {{.Release.Name}} 将 release 的名称插入到模板中。这里的 Release 就是 Helm 的内置对象,下⾯是⼀些常用的内置对象,在需要的时候直接使用就可以、当然我们也可以去查看官方文档中的详细描述:https://helm.sh/docs/chart_template_guide/builtin_objects/
Release:此对象描述发行版本身。它内部有几个对象:
- Release.Name:发行名称;
- Release.Namespace:release的名称空间(如果清单未覆盖);
- Release.IsUpgrade:如果当前操作是升级或回滚,则设置为true;
- Release.IsInstall:如果当前操作是安装,则设置为true;
- Release.Revision:此版本的修订号。在安装时,该值为1,并且每次升级和回滚时都会增加;
- Release.Service:呈现当前模板的服务。在Helm上,这始终是Helm。
Values:从values.yaml文件(和用户提供的文件)传递到模板的值,默认情况下Values为空。
Chart:Chart.yaml文件的内容。所有的chart对象都将从该文件中访问数据。
例如{{ .Chart.Name }}-{{ .Chart.Version }}将打印出mychart-0.1.0。Chart对象中的可用字段列表见:Charts Guide
Files:这提供对chart中所有非特殊文件的访问。虽然您不能使用它来访问模板,但是可以使用它来访问chart中的其他文件:
- Files.Get是用于通过名称(.Files.Get config.ini)获取文件的功能;
- Files.GetBytes是用于以字节数组而不是字符串形式获取文件内容的函数。这对于诸如图片之类的东西很有用;
- Files.Glob 是一个函数,该函数返回名称与给定的Shell Glob模式匹配的文件列表;
- Files.Lines是一种逐行读取文件的功能。这对于遍历文件中的每一行很有用;
- Files.AsSecrets 是将文件主体作为Base 64编码的字符串返回的函数;
- Files.AsConfig 是一个将文件正文作为YAML映射返回的函数。
Capabilities:这提供了有关Kubernetes集群支持哪些功能的信息:
- Capabilities.APIVersions 是一组版本;
- Capabilities.APIVersions.Has $version指示版本(例如 batch/v1)或资源(例如apps/v1/Deployment)在群集上是否可用;
- Capabilities.KubeVersion并且Capabilities.KubeVersion.Version是Kubernetes版本;
- Capabilities.KubeVersion.Major 是Kubernetes的主要版本;
- Capabilities.KubeVersion.Minor 是Kubernetes的次要版本。
Template:包含有关正在执行的当前模板的信息:
- Name:当前模板的命名空间文件路径(例如 mychart/templates/mytemplate.yaml);
- BasePath:当前图表的模板目录的命名空间路径(例如mychart/templates)。
上⾯这些值可用于任何顶级模板,要注意内置值始终以大写字母开头。这也符合 Go 的命名约定。当你创建自己的名字时,你可以自由地使用适合你的团队的惯例。
上⾯的内置对象中有⼀个对象就是 Values,该对象提供对传入 chart 的值的访问,Values 对象的值有4个来源:
- chart 包中的 values.yaml 文件;
- 父chart包的 values.yaml 文件;
- 通过 helm install 或者 helm upgrade 的 -f 或者 –values 参数传入的自定义的 yaml 文件;
- 通过–set 参数传⼊的值。chart 的 values.yaml 提供的值可以被用户提供的 values.yaml ⽂件覆盖,而该文件同样可以被 –set 提供的参数所覆盖;
这里我们来重新编辑 mychart/values.yaml文件,将默认的值全部清空,添加⼀个新的数据course: k8s;
➜ ~ echo 'course: k8s' > mychart/values.yaml
➜ ~ cat mychart/values.yaml
course: k8s
然后我们在上⾯的 templates/configmap.yaml 模板文件中就可以使用这个值了;可以看到最后⼀行我们是通过 {{ .Values.course }} 来获取 course 的值的。我们用–dry-run模式来查看模板会被如何渲染:
➜ ~ vim mychart/templates/configmap.yaml
➜ ~ cat mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
course: {{ .Values.course }}
➜ ~ helm install mychart mychart/ --dry-run
NAME: mychart
LAST DEPLOYED: Tue Feb 23 14:15:21 2021
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"
course: k8s
可以看到 ConfigMap 中 course 的值被渲染成了 k8s,这是因为在默认的 values.yaml 文件中该数值为 k8s,同样的我们可以通过 –set 参数来轻松的覆盖 course 的值:
➜ ~ helm install mychart mychart/ --dry-run --set course=python
NAME: mychart
LAST DEPLOYED: Tue Feb 23 14:19:24 2021
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"
course: python
values文件也可以包含更多结构化内容,例如,我们在 values.yaml 文件中可以创建 course 部分,然后在其中添加几个键:
➜ ~ vim mychart/values.yaml
➜ ~ cat mychart/values.yaml
course:
k8s: devops
python: django
然后我们把模板稍微修改一下:
➜ ~ vim mychart/templates/configmap.yaml
➜ ~ cat mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
k8s: {{ .Values.course.k8s }}
python: {{ .Values.course.python }}
我们同样可以使用–dry-run模式查看渲染结果:
➜ ~ helm install mychart mychart/ --dry-run
NAME: mychart
LAST DEPLOYED: Tue Feb 23 14:26:42 2021
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"
k8s: devops
python: django
可以看到模板中的参数已经被 values.yaml 文件中的值给替换掉了。虽然以这种方式构建数据是可以的,但还是建议保持 value 树浅⼀些,平⼀些,这样维护起来要简单⼀点。