02-Helm Chart 开发

参考官网文档:https://helm.sh/zh/docs/howto/charts_tips_and_tricks/

参考中文学习博客:https://www.cnblogs.com/ssgeek/p/15511387.html#1%E6%A6%82%E8%BF%B0

调试

Helm也提供了--dry-run --debug调试参数,帮助验证模板正确性。在执行helm install时候带上这两个参数就可以把对应的values值和渲染的资源清单打印出来,而不会真正的去部署一个release

例如:helm install web --dry-run /root/mychart

内置对象

使用 {{.Release.Name}}将release的名称插入到模板中
Release.Name: release 名字
Release.Namespace: release 命名空间
Release.Service: release 服务的名称
Release.Revision: release 修订版本号,从1开始累加

Values

Values对象是为Chart模板提供值,这个对象的值有4个来源

  • chart包中的values.yaml文件
  • chart包的values.yaml文件
  • 通过helm install或者helm upgrade的 -f或者 --values参数传入的自定义的yaml文件
  • 通过 --set 参数传入的值

chartvalues.yaml提供的值可以被用户提供的values文件覆盖,而该文件同样可以被 --set提供的参数所覆盖(优先级:--set>-f/--values > values.yaml > 父chart包的values.yaml

编辑mychart/values.yaml文件,将默认的值全部清空,然后添加一个副本数

# cat values.yaml 
replicas: 3
image: "nginx"
imageTag: "1.17"

# cat templates/deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-deployment
spec:
  replicas: {{ .Values.replicas }}
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: {{ .Values.image }}:{{ .Values.imageTag }}
        name: nginx

查看渲染结果:

# helm install --dry-run web ../mychart/

values文件也可以包含结构化内容,例如

# cat values.yaml 
...
label:
  project: ms
  app: nginx

# cat templates/deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-deployment 
spec:
  replicas: {{ .Values.replicas }} 
  selector:
    matchLabels:
      project: {{ .Values.label.project }}
      app: {{ .Values.label.app }}
  template:
    metadata:
      labels:
        project: {{ .Values.label.project }}
        app: {{ .Values.label.app }}
    spec:
      containers:
      - image: {{ .Values.image }}:{{ .Values.imageTag }} 
        name: nginx

查看渲染结果:

# helm install --dry-run web ../mychart/

管道与函数

前面讲的相关模块,其实就是将值传给模板引擎进行渲染,模板引擎还支持对拿到数据进行二次处理

  • 字符串函数quote: {{ quote .Values.label.app }}
  • 默认值函数default {{ .Values.name | default "nginx" }}
  • 缩进indent::{{ .Values.resources | indent 12 }}
  • 大写:{{ upper .Values.resources }}
  • 首字母大写:{{ title .Values.resources }}
# cat values.yaml 
...
label:
  project: ms
  app: "nginx"
# vi templates/deployment.yaml
app: {{ quote .Values.label.app }}
# helm install --dry-run web ../mychart/ 

quote .Values.label.app将后面的值作为参数传递给quote函数

经常使用一个default函数,该函数允许在模板中指定默认值,以防止该值被忽略掉

例如忘记定义,执行helm install会因为缺少字段无法创建资源,这时就可以定义一个默认值

# cat values.yaml 
replicas: 2
# cat templates/deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
- name: {{ .Values.name | default "nginx" }}

流程控制

if/else 条件块

1、语法结构:

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

运算符判断:eq、ne、 lt、 gt、 and、 or

示例:

# cat values.yaml 
devops: k8

# cat templates/deployment.yaml 
...
  template:
    metadata:
      labels:
        app: nginx
        {{ if eq .Values.devops "k8s" }}
        devops: 123
        {{ else }}
        devops: 456
        {{ end }}
# helm install --dry-run web ../mychart/ 
...
      labels:
        app: nginx

        devops: 456

2、消除空行

可以看到渲染出来会有多余的空行,这是因为当模板引擎运行时,会将控制指令删除,所有之前占的位置也就空白了,需要使用{{- if ...}}的方式消除此空行

# cat values.yaml 
devops: k8

# cat templates/deployment.yaml 
...
  template:
    metadata:
      labels:
        app: nginx
        {{- if eq .Values.devops "k8s" }}
        devops: 123
        {{- else }}
        devops: 456
        {{- end }}

3、真假条件判断

  • 一个布尔类型的 假
  • 一个数字 零
  • 一个 空的字符串
  • 一个 nil(空或 null)
  • 一个空的集合( map、 slice、 tuple、 dict、 array)

除了上面的这些情况外,其他所有条件都为 

4、样例:

# cat values.yaml 
label:
  project: ms
  app: nginx
devops: k8
resources: {}
  # limits:
  #   cpu: 100m
  #   memory: 128Mi
  # requests:
  #   cpu: 100m
  #   memory: 128Mi
ingress:
  enabled: true 
  host: example.a.com


# cat templates/deployment.yaml 
...
  template:
    metadata:
      labels:
        app: nginx
        {{- if eq .Values.devops "k8s"}}
        devops: 123
        {{- else }}
        devops: 456
        {{- end }}
    spec:
      containers:
      - image: {{ .Values.image }}:{{ .Values.imageTag | default "1.16" }}
        name: nginx
        {{- if .Values.resources }}
        resources:
{{ toYaml .Values.resources | indent 10 }}
        {{- end }}

# cat templates/ingress.yaml
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: {{ .Release.Name }}-ingress
spec:
  rules:
  - host: {{ .Values.ingress.host }}
    http:
      paths:
      - path: /
        backend:
          serviceName: {{ .Release.Name }}
          servicePort: {{ .Values.service.port }}
{{ end }}

with 指定范围

with :控制变量作用域

之前的 {{.Release.xxx}}或者 {{.Values.xxx}},其中的 .就是表示对当前范围的引用, .Values就是告诉模板在当前范围中查找 Values对象的值。而 with语句就可以来控制变量的作用域范围

1、语法结构:

{{ with PIPELINE }}
  #  restricted scope
{{ end }}

2、样例:

# cat values.yaml
replicas: 3
label:
  team: team1
  gpu: 2

# cat templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      {{- with .Values.label }}
      nodeSelector:
        {{- toYaml . | nindent 8}}
      {{- end }}
      containers:
      - image: nginx:1.16
        name: nginx
  • with是一个循环构造。使用Values.label中的值:将其转换为Yaml
  • toYaml之后的点是循环中.Values.label的当前值

range 循环块

在Helm模板语言中,使用 range关键字来进行循环操作

#cat values.yaml
test:
  - 1
  - 2
  - 3
#cat  templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}
data:
  test: |
  {{- range .Values.test }}
    {{ . }}
  {{- end }}

循环内部使用的是一个 .,这是因为当前的作用域就在当前循环内,这个 .引用的当前读取的元素

变量

这是语言中基本的概念:变量,在模板中,使用变量的场合不多,但可以看到如何使用它来简化代码,并更好地利用with和range,举例如下

range循环中使用 $key和 $value两个变量来接收后面列表循环的键和值

# cat ../values.yaml
env:
  NAME: "gateway"
  JAVA_OPTS: "-Xmx1G"
  
# cat deployment.yaml 
...
        env:
        {{- range $k, $v := .Values.env }}
           - name: {{ $k }}
             value: {{ $v | quote }}
        {{- end }}

结果如下
    env:
       - name: JAVA_OPTS
         value: "-Xmx1G"
       - name: NAME
         value: "gateway"

命名模板

使用define定义,template引入,在templates目录中默认下划线_开头的文件为公共模板(_helpers.tpl)

template指令是将一个模板包含在另一个模板中的方法。但是,template函数不能用于Go模板管道。为了解决该问题,增加include功能

# cat _helpers.tpl
{{- define "demo.fullname" -}}
{{- .Chart.Name -}}-{{ .Release.Name }}
{{- end -}}

{{- define "demo.labels" -}}
app: {{ template "demo.fullname" . }}
chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
release: "{{ .Release.Name }}"
{{- end -}}

# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "demo.fullname" . }}
  labels:
    {{- include "demo.labels" . | nindent 4 }}
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      {{- with .Values.label }}
      nodeSelector:
        {{- toYaml . | nindent 8}}
      {{- end }}
      containers:
      - image: nginx:1.16
        name: nginx

开发Chart的流程

  1. 先创建模板
  2. helm create demo
  3. 修改Chart.yaml,Values.yaml,添加常用的变量
  4. 在templates目录下创建部署镜像所需要的yaml文件,并变量引用yaml里经常变动的字段

发布者:LJH,转发请注明出处:https://www.ljh.cool/37671.html

(0)
上一篇 2023年6月29日 上午10:59
下一篇 2023年8月13日 下午8:44

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注