helm的template语法学习

一、Chart文件结构

chart名称必须是小写字母数字。单词之间可以使用横杠分隔(-):
示例:

drupal
nginx-lego
aws-cluster-autoscaler

1.1、chart文件组成结构

[root@master ~]# helm create my-nginx
Creating my-nginx

[root@master ~]# tree my-nginx/
my-nginx/
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── NOTES.txt
│   ├── serviceaccount.yaml
│   ├── service.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml

templates/        存放k8s的部署资源模板,通过渲染变量得到部署文件
values.yaml       用来存放templates默认值
Chart.yaml        对chart的版本、名称等信息描述文件
deployment.yaml   一个基础deployment描述文件
_helpers.tpl      存放能够复用的模板
NOTES.txt         为用户提供一个关于chart部署后使用说明的文件

示例变量使用

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

$ helm install clunky-serval ./mychart

$ helm get manifest clunky-serval
---
# Source: my-nginx/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: clunky-serval-configmap
data:
  myvalue: "Hello World"

二、内置对象

内置对象始终是大写字母开头,符合Go的命名约定

{{ .Release.Name }}

Release.Name:      chart的实例名,release name
Release.Namespace: 实例要安装的命名空间
Release.IsUpgrade: This is set to true if the current operation is an upgrade or rollback.
Release.IsInstall: This is set to true if the current operation is an install.
Release.Revision: 此版本的修订号。在安装时,该值为1,并且每次升级和回滚时都会增加
Release.Service: The service that is rendering the present template. On Helm, this is always Helm.

#参数传递,覆盖values.yaml的值
$ helm install --set foo=bar ./mychart

{{ .Values.image.pullPolicy }}

{{ template “openvpn.fullname” . }}

三、管道、常用函数

3.1、quote 函数,将值渲染模板时候,以字符串方式引用

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {{ .Values.favorite.drink | quote }}
  food: {{ .Values.favorite.food | upper | quote }}
============================================================================
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: trendsetting-p-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"

3.2、upper 函数,将小写字母转换为大写

3.3、repeat 函数,写法repeat n 是将参数复制n遍

3.4、default 函数,用法default "tee" 给一个默认的参数,建议将静态的参数都写入values.yaml

drink: {{ .Values.favorite.drink | default "tea" | quote }}

3.5、title 函数,首字母大写

3.6、indent 函数,缩进字符,以空格为单位

{{ toYaml .Values.strategy | indent 4 }}

四、流程控制

1.1、helm的模板语言提供以下几种控制结构

  • if/ else用于创建条件块,以下值的内容,被认为flase

    • 布尔值false

    • 数字零

    • 一个空字符串

    • 一个nil(空或空)

    • 一个空的集合(mapslicetupledictarray

  • with 指定范围

    {{ with PIPELINE }}
      # restricted scope
    {{ end }}
    
  • range,提供“针对每个”样式的循环

除此之外,它还提供了一些声明和使用命名模板段的操作:

  • define 在模板中声明一个新的模板
  • template 导入指定名称模板
  • block 声明一种特殊的可填充模板区域

1.2、if/else的基本结构

{{ if PIPELINE }}
  # Do something
{{ else if OTHER PIPELINE }}
  # Do something else
{{ else }}
  # Default case
{{ end }}

通过以下例子发现模板引擎在运行 {{ if eq .Values.favorite.drink “coffee” }} 里面的流程控制时会删除掉所有内容,但是会完全保留空白

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {{ .Values.favorite.drink | default "tea" | quote }}
  food: {{ .Values.favorite.food | upper | quote }}
  {{ if eq .Values.favorite.drink "coffee" }}
  mug: true
  {{ end }}
 
=========================================================================
helm install --debug --dry-run my-config ../my-nginx/

# Source: my-nginx/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: aaaa-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"

  mug: true

添加特殊字符,告诉模板引擎压缩移除空白行

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {{ .Values.favorite.drink | default "tea" | quote }}
  food: {{ .Values.favorite.food | upper | quote }}
  {{- if eq .Values.favorite.drink "coffee" }}
  mug: true
  {{- end }}
  
===============================================================================
helm install --debug --dry-run my-config ../my-nginx/

# Source: my-nginx/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: aaaa-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"
  mug: true
  
===============================================================================
#使用*代表将要移除的换行符
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {{ .Values.favorite.drink | default "tea" | quote }}
  food: {{ .Values.favorite.food | upper | quote }}*
**{{- if eq .Values.favorite.drink "coffee" }}
  mug: true*
**{{- end }}

通过使用在模板标识{{后面添加破折号和空格{{-来表示将左边空白删除,而在}}前面添加一个空格和破折号-}}表示应该删除右边的空格,另外需要注意的是换行符也是空格!

1.3、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 }}
  
   
 #以下使用会出现错误,Release.Name不在with的作用范围,在受限范围内,将无法使用从父范围访问其他对象
 {{- with .Values.favorite }}
 drink: {{ .drink | default "tea" | quote }}
 food: {{ .food | upper | quote }}
 release: {{ .Release.Name }}
 {{- end }}

1.4、range用法示例

cat values.yaml

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

==========================================================================
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 }}
  toppings: |-
    {{- range .Values.pizzaToppings }}
    - {{ . | title | quote }}
    {{- end }}
    
=============================================================================
# Source: my-nginx/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: aaaa-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"
  toppings: |-
    - "Mushrooms"
    - "Cheese"
    - "Peppers"
    - "Onions"

五、定义和使用模板

{{ define "MY.NAME" }}
  # body of template here
{{ end }}

Helm charts 将模板写入到一个特定的文件里面, 通常用 _helpers.tpl.

按照惯例,define函数应该有一个简单的文档块({{/* ... */}})描述它们的作用
{{/* test labels */}}
{{- define "mychart.labels" }}
  labels:
    generator: helm
    date: {{ now | htmlDate }}
{{- end }}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
  {{- template "mychart.labels" }}
data:
  myvalue: "Hello World"
  {{- range $key, $val := .Values.favorite }}
  {{ $key }}: {{ $val | quote }}
  {{- end }}
=============================================================================  
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: running-panda-configmap
  labels:
    generator: helm
    date: 2016-11-02
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "pizza"

六、模板调试

调试模板可能会很棘手,因为渲染完成的模板已发送到Kubernetes API服务器,该服务器可能会因为格式化错误的原因而拒绝执行YAML文件或者执行发生错误,所以在执行前最好调试一下模板内容。

  • helm lint <chart-name> 检查chart包可能存在的问题
  • helm install <releas——name> --dry-run --debug or helm template --debug: 不安装chart,让服务渲染模板后,返回清单文件
  • helm get manifest <RELEASE_NAME>: 检索和查看release加载的实际模板

下面给个示例说明,部分冗余代码使用省略号代替

[root@jxy-master helm-chart]# helm install test-nginx --dry-run --debug my-nginx/
install.go:158: [debug] Original chart version: ""
install.go:175: [debug] CHART PATH: /root/helm-chart/my-nginx

NAME: test-nginx
LAST DEPLOYED: Fri May 29 11:10:49 2020
NAMESPACE: default
STATUS: pending-install
REVISION: 1
USER-SUPPLIED VALUES:
{}

COMPUTED VALUES:
...

HOOKS:
---
# Source: my-nginx/templates/tests/test-connection.yaml
...
MANIFEST:
---
# Source: my-nginx/templates/serviceaccount.yaml
...
---
# Source: my-nginx/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: test-nginx-my-nginx
  labels:
    helm.sh/chart: my-nginx-0.1.0
    ...
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: my-nginx
    app.kubernetes.io/instance: test-nginx
---
# Source: my-nginx/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-nginx-my-nginx
  labels:
    helm.sh/chart: my-nginx-0.1.0
    ...
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: my-nginx
      app.kubernetes.io/instance: test-nginx
  template:
    metadata:
      labels:
        app.kubernetes.io/name: my-nginx
        app.kubernetes.io/instance: test-nginx
    spec:
      serviceAccountName: test-nginx-my-nginx
      securityContext:
        {}
      containers:
        - name: my-nginx
          securityContext:
            {}
          image: "nginx:1.16.0"
          imagePullPolicy: IfNotPresent
          ...
            {}

NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=my-nginx,app.kubernetes.io/instance=test-nginx" -o jsonpath="{.items[0].metadata.name}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace default port-forward $POD_NAME 8080:80

创建NOTES.txt文件

Helm可以为用户打印出一些有用的信息。使用模板可以高度自定义此信息,在安装完release后打印一些帮助信息,来帮助我们更好的使用该chart

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值