kubernetes(k8s)helm模板之内置函数和values

定义 chart

一个 chart 包就是一个文件夹的集合,文件夹名称就是 chart 包的名称,比如创建一个 mychart 的 chart 包:

$ helm create mychart
Creating mychart
$ tree mychart/
mychart/
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── NOTES.txt
│   └── service.yaml
└── values.yaml

2 directories, 7 files

chart 包templates 目录下面的文件:

  • NOTES.txt:chart 的 “帮助文本”。这会在用户运行 helm install 时显示给用户
  • deployment.yaml:创建 Kubernetes deployment 的基本 manifest
  • service.yaml:为 deployment 创建 service 的基本 manifest
  • ingress.yaml: 创建 ingress 对象的资源清单文件
  • _helpers.tpl:放置模板助手的地方,可以在整个 chart 中重复使用

这里我们明白每一个文件是干嘛的就行,然后把 templates 目录下面所有文件全部删除掉,这里我们自己来创建模板文件:

$ rm -rf mychart/templates/*.*

创建模板

这里我们来创建一个非常简单的模板 ConfigMap,在 templates 目录下面新建一个configmap.yaml文件:

apiVersion: v1
kind: ConfigMap
metadata:
  name: mychart-configmap
data:
  myvalue: "Hello World"

实际上现在我们就有一个可安装的 chart 包了,通过helm install命令来进行安装:

$ helm install ./mychart/
NAME:   ringed-lynx
LAST DEPLOYED: Fri Sep  7 22:59:22 2018
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME               DATA  AGE
mychart-configmap  1     0s

在上面的输出中,我们可以看到我们的 ConfigMap 资源对象已经创建了。然后使用如下命令我们可以看到实际的模板被渲染过后的资源文件:

$ helm get manifest ringed-lynx

---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mychart-configmap
data:
  myvalue: "Hello World"

现在我们看到上面的 ConfigMap 文件是不是正是我们前面在模板文件中设计的,现在我们删除当前的release:

$ helm delete ringed-lynx
release "ringed-lynx" deleted

添加一个简单的模板

我们可以看到上面我们定义的 ConfigMap 的名字是固定的,但往往这并不是一种很好的做法,我们可以通过插入 release 的名称来生成资源的名称,比如这里 ConfigMap 的名称我们希望是:ringed-lynx-configmap,这就需要用到 Chart 的模板定义方法了。

Helm Chart 模板使用的是Go语言模板编写而成,并添加了Sprig中的50多个附件模板函数以及一些其他特殊的函

需要注意的是kubernetes资源对象的 labels 和 name 定义被限制 63个字符,所以需要注意名称的定义。

现在我们来重新定义下上面的 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 资源对象的名称:

$ helm install ./mychart
helm install ./mychart/
NAME:   quoting-zebra
LAST DEPLOYED: Fri Sep  7 23:20:12 2018
NAMESPACE: default
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME                     DATA  AGE
quoting-zebra-configmap  1     0s

可以看到现在生成的名称变成了quoting-zebra-configmap,证明已经生效了,当然我们也可以使用命令helm get manifest quoting-zebra查看最终生成的清单文件的样子。

调试

Helm 提供了--dry-run --debug这个参数,在执行helm install的时候带上这两个参数就可以把对应的 values 值和生成的最终的资源清单文件打印出来,而不会真正的去部署一个release实例,比如我们来调试上面创建的 chart 包:

$ helm install . --dry-run --debug ./mychart
[debug] Created tunnel using local port: '35286'

[debug] SERVER: "127.0.0.1:35286"

[debug] Original chart version: ""
[debug] CHART PATH: /root/course/kubeadm/helm/mychart

NAME:   wrapping-bunny
REVISION: 1
RELEASED: Fri Sep  7 23:23:09 2018
CHART: mychart-0.1.0
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
...
HOOKS:
MANIFEST:

---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: wrapping-bunny-configmap
data:
  myvalue: "Hello World"

现在我们使用--dry-run就可以很容易地测试代码了,不需要每次都去安装一个 release 实例了,但是要注意的是这不能确保 Kubernetes 本身就一定会接受生成的模板,在调试完成后,还是需要去安装一个实际的 release 实例来进行验证的。

内置对象

刚刚我们使用{{.Release.Name}}将 release 的名称插入到模板中。这里的 Release 就是 Helm 的内置对象,下面是一些常用的内置对象,在需要的时候直接使用就可以:

  • Release:这个对象描述了 release 本身。它里面有几个对象:

    • Release.Name:release 名称
    • Release.Time:release 的时间
    • Release.Namespace:release 的 namespace(如果清单未覆盖)
    • Release.Service:release 服务的名称(始终是 Tiller)。
    • Release.Revision:此 release 的修订版本号,从1开始累加。
    • Release.IsUpgrade:如果当前操作是升级或回滚,则将其设置为 true。
    • Release.IsInstall:如果当前操作是安装,则设置为 true。
  • Values:从values.yaml文件和用户提供的文件传入模板的值。默认情况下,Values 是空的。

  • Chart:Chart.yaml文件的内容。所有的 Chart 对象都将从该文件中获取。chart 指南中Charts Guide列出了可用字段,可以前往查看。

  • Files:这提供对 chart 中所有非特殊文件的访问。虽然无法使用它来访问模板,但可以使用它来访问 chart 中的其他文件。请参阅 "访问文件" 部分。

    • Files.Get 是一个按名称获取文件的函数(.Files.Get config.ini)
    • Files.GetBytes 是将文件内容作为字节数组而不是字符串获取的函数。这对于像图片这样的东西很有用。
  • Capabilities:这提供了关于 Kubernetes 集群支持的功能的信息。

    • Capabilities.APIVersions 是一组版本信息。
    • Capabilities.APIVersions.Has $version 指示是否在群集上启用版本(batch/v1)。
    • Capabilities.KubeVersion 提供了查找 Kubernetes 版本的方法。它具有以下值:Major,Minor,GitVersion,GitCommit,GitTreeState,BuildDate,GoVersion,Compiler,和 Platform。
    • Capabilities.TillerVersion 提供了查找 Tiller 版本的方法。它具有以下值:SemVer,GitCommit,和 GitTreeState。
  • Template:包含有关正在执行的当前模板的信息

  • Name:到当前模板的文件路径(例如 mychart/templates/mytemplate.yaml)

  • BasePath:当前 chart 模板目录的路径(例如 mychart/templates)。

上面这些值可用于任何顶级模板,要注意内置值始终以大写字母开头。这也符合Go的命名约定。当你创建自己的名字时,你可以自由地使用适合你的团队的惯例。

values 文件

上面的内置对象中有一个对象就是 Values,该对象提供对传入 chart 的值的访问,Values 对象的值有4个来源:

chart 包中的 values.yaml 文件
父 chart 包的 values.yaml 文件
通过 helm install 或者 helm upgrade 的-f或者--values参数传入的自定义的 yaml 文件(上节课我们已经学习过)
通过--set 参数传入的值
chart 的 values.yaml 提供的值可以被用户提供的 values 文件覆盖,而该文件同样可以被--set提供的参数所覆盖。

这里我们来重新编辑 mychart/values.yaml 文件,将默认的值全部清空,添加一个新的数据:(values.yaml)

course: k8s

然后我们在上面的 templates/configmap.yaml 模板文件中就可以使用这个值了:(configmap.yaml)

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  course: {{ .Values.course }}

可以看到最后一行我们是通过{{ .Values.course }}来获取 course 的值的。现在我们用 debug 模式来查看下我们的模板会被如何渲染:

$ helm install --dry-run --debug ./mychart
helm install --dry-run --debug .
[debug] Created tunnel using local port: '33509'

[debug] SERVER: "127.0.0.1:33509"

[debug] Original chart version: ""
[debug] CHART PATH: /root/course/kubeadm/helm/mychart

NAME:   nasal-anaconda
REVISION: 1
RELEASED: Sun Sep  9 17:37:52 2018
CHART: mychart-0.1.0
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
course: k8s

HOOKS:
MANIFEST:

---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nasal-anaconda-configmap
data:
  myvalue: "Hello World"
  course: k8s

我们可以看到 ConfigMap 中 course 的值被渲染成了 k8s,这是因为在默认的 values.yaml 文件中该参数值为 k8s,同样的我们可以通过--set参数来轻松的覆盖 course 的值:

$ helm install --dry-run --debug --set course=python ./mychart
[debug] Created tunnel using local port: '44571'

......

---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: named-scorpion-configmap
data:
  myvalue: "Hello World"
  course: python

由于--set 比默认 values.yaml 文件具有更高的优先级,所以我们的模板生成为 course: python。

values 文件也可以包含更多结构化内容,例如,我们在 values.yaml 文件中可以创建 course 部分,然后在其中添加几个键:

course:
  k8s: devops
  python: django

现在我们稍微修改模板:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  k8s: {{ .Values.course.k8s }}
  python: {{ .Values.course.python }}

同样可以使用 debug 模式查看渲染结果:

$ helm install --dry-run --debug ./mychart
[debug] Created tunnel using local port: '33801'
......
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: exhaling-turtle-configmap
data:
  myvalue: "Hello World"
  k8s: devops
  python: django

可以看到模板中的参数已经被 values.yaml 文件中的值给替换掉了。虽然以这种方式构建数据是可以的,但我们还是建议保持 value 树浅一些,平一些,这样维护起来要简单一点。

到这里,我们已经看到了几个内置对象的使用方法,并用它们将信息注入到了模板之中。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,794评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,050评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,587评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,861评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,901评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,898评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,832评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,617评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,077评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,349评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,483评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,199评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,824评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,442评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,632评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,474评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,393评论 2 352

推荐阅读更多精彩内容