charts 编写介绍
开始
快速创建一个 chart 模板, helm create mychart, 执行命令后本地生成一个 mychart 目录.
chart 目录结构
Chart.YAML: 该 chart 的描述文件, 包括 ico 地址, 版本信息等
vakues.YAML: 给模板文件使用的变量
charts: 依赖其他包的 charts 文件
requirements.YAML: 依赖的 charts
README.md: 开发人员自己阅读的文件
templates: 存放 k8s 模板文件目录
NOTES.txt 说明文件, helm install 之后展示给用户看的内容
deployment.YAML 创建 k8s 资源的 YAML 文件
_helpers.tpl: 下划线开头的文件, 可以被其他模板引用.
一个最小的 chart 目录, 只需要包含一个 Chart.YAML, 和 templates 目录下一个 k8s 资源文件. 如:
- # mychart/Chart.YAML
- apiVersion: v1
- appVersion: 2.9.0
- version: 1.1.1
- # mychart/templates/configmap.YAML
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: mychart-configmap
- data:
- myvalue: "Hello World"
helm 的模板语法实现原理:
- go-template 双
- sprig
helm 模板语法
模板引用方式,{{ .Release.Name }}, 通过双括号注入, 小数点开头表示从最顶层命名空间引用.
helm 内置对象
- # Release, release 相关属性
- # Chart, Chart.YAML 文件中定义的内容
- # Values, values.YAML 文件中定义的内容
模板中使用管道
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: {
- {
- .Release.Name
- }
- }-configmap
- data:
- myvalue: "Hello World"
- drink: {
- {
- .Values.favorite.drink | repeat 5 | quote
- }
- }
- food: {
- {
- .Values.favorite.food | upper | quote
- }
- }
if 语句
- {
- {
- if PIPELINE
- }
- }
- # Do something
- {
- {
- else if OTHER PIPELINE
- }
- }
- # Do something else
- {
- {
- else
- }
- }
- # Default case
- {
- {
- end
- }
- }
操作符, and/eq/or/not
- {
- {
- /* include the body of this if statement when the variable .Values.fooString exists and is set to "foo" */
- }
- }
- {
- {
- if and .Values.fooString (eq .Values.fooString "foo")
- }
- }
- {
- {
- ...
- }
- }
- {
- {
- end
- }
- }
- {
- {
- /* do not include the body of this if statement because unset variables evaluate to false and .Values.setVariable was negated with the not function. */
- }
- }
- {
- {
- if or .Values.anUnsetVariable (not .Values.aSetVariable)
- }
- }
- {
- {
- ...
- }
- }
- {
- {
- end
- }
- }
控制语句块在渲染后生成模板会多出空行, 需要使用 {{- if ...}} 的方式消除此空行. 如:
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: {
- {
- .Release.Name
- }
- }-configmap
- data:
- myvalue: "Hello World"
- {
- {
- - if eq .Values.favorite.drink "coffee"
- }
- }
- mug: true
- {
- {
- - end
- }
- }
引入相对命名空间, with 命令:
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: {
- {
- .Release.Name
- }
- }-configmap
- data:
- myvalue: "Hello World"
- {
- {
- - with .Values.favorite
- }
- }
- drink: {
- {
- .drink | default "tea" | quote
- }
- }
- food: {
- {
- .food | upper | quote
- }
- }
- {
- {
- - end
- }
- }
range 命令实现循环, 如:
- # values.YAML
- favorite:
- drink: coffee
- food: pizza
- pizzaToppings:
- - mushrooms
- - cheese
- - peppers
- - onions
- #configmap.YAML
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: {
- {
- .Release.Name
- }
- }-configmap
- data:
- myvalue: "Hello World"
- toppings: |-
- {
- {
- - range .Values.pizzaToppings
- }
- }
- - {
- {
- .
- }
- }
- # . 表示 range 的命令空间下的取值
- {
- {
- - end
- }
- }
- {
- {
- - range $key, $val := .Values.favorite
- }
- }
- {
- {
- $key
- }
- }: {
- {
- $val | quote
- }
- }
- {
- {
- - end
- }
- }
变量赋值
- ApiVersion: v1
- Kind: ConfigMap
- Metadata:
- name: {
- {
- .Release.Name
- }
- }-configmap
- Data:
- myvalue: "Hello World"
- # 由于下方的 with 语句引入相对命令空间, 无法通过. Release 引入, 提前定义 relname 变量
- {
- {
- - $relname := .Release.Name -
- }
- }
- {
- {
- - with .Values.favorite
- }
- }
- food: {
- {
- .food
- }
- }
- release: {
- {
- $relname
- }
- }
- # 或者可以使用 $ 符号, 引入全局命名空间
- release: {
- {
- $.Release.Name
- }
- }
- {
- {
- - end
- }
- }
公共模板, define 定义, template 引入, 在 templates 目录中默认下划线_开头的文件为公共模板(_helpers.tpl)
- # _helpers.tpl 文件
- {
- {
- - define "mychart.labels"
- }
- }
- labels:
- generator: helm
- date: {
- {
- now | htmlDate
- }
- }
- {
- {
- - end
- }
- }
- # configmap.YAML 文件
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: {
- {
- .Release.Name
- }
- }-configmap
- {
- {
- - template "mychart.labels"
- }
- }
- data:
- myvalue: "Hello World"
template 语句的升级版本 include,template 是语句无法在后面接管道符来对引入变量做定义,
include 实现了此功能.
- # _helpers.tpl 文件
- {
- {
- - define "mychart.app" -
- }
- }
- app_name: {
- {
- .Chart.Name
- }
- }
- app_version: "{{ .Chart.Version }}+{{ .Release.Time.Seconds }}"
- {
- {
- - end -
- }
- }
- # configmap.YAML
- apiVersion: v1
- kind: ConfigMap
- metadata:
- name: {
- {
- .Release.Name
- }
- }-configmap
- labels:
- {
- {
- - include "mychart.app" . | nindent 4
- }
- }
- data:
- myvalue: "Hello World"
- {
- {
- - range $key, $val := .Values.favorite
- }
- }
- {
- {
- $key
- }
- }: {
- {
- $val | quote
- }
- }
- {
- {
- - end
- }
- }
- {
- {
- - include "mychart.app" . | nindent 2
- }
- }
- # 如果使用 template 只能手动空格, 不能使用管道后的 nindent 函数来做缩进
一个坑
helm install stable/Drupal --set image=my-registry/Drupal:0.1.0 --set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt] --set livenessProbe.httpGet=null<br/>
,livenessProbe 在 values.YAML 中定义了 httpGet, 需要手动设置为 null, 然后设置 exec 的探针.
来源: http://blog.51cto.com/qujunorz/2421328