2.chart函数及流程控制

发布时间 2023-12-11 18:19:53作者: 老夫聊发少年狂88

1. chart内置对象

1.1 什么是内置对象

1.2 创建chart模板

1.3 内置对象chart

1.4 内置对象Release

1.5 内置对象values

1.6 内置对象Capabilities

2. chart函数与管道

2.1 函数介绍

2.2 函数管道

3. Chart常用函数

3.1 default函数

3.2 quote函数

3.3 required函数

3.4 include函数

3.5 toYaml函数

3.6 b64enc函数

4. Chart流程控制

4.1 为何需要流程控制

4.2 if/else判断

4.3 range循环

4.4 with控制

4.5 变量

=================================================================

1. chart内置对象

1.1 什么是内置对象

Helm Chart中,内置对象是一组预定义的变量,它们可以在模版文件中使用。这些变量提供了Helm和Kubernetes的运行环境信息,这些信息包括Chart的名称、chart的版本、release的名称,以及用户在values.yaml文件中定义的值等。通过使用这些内置对象,模板文件可以变得更加灵活和动态,因此理解这些内置对象以及如何在模板中使用它们,是掌握Chart开发的关键。
helm中常用的内置对象有: chart、release、values、files、capabilities、template等,以下是对部分内置对象的简要说明:

  • Chart: 提供了chart的信息,例如chart的名称、版本和描述等。
  • Release: 提供了关于当前release的信息,例如release的名称和时间戳等。
  • Values: 包含了用户在values.yaml配置文件中定义的值
  • Files: 提供了Chart模版文件访问其他普通文件的方法
  • Capabilities: 提供Kubernetes集群API的版本信息
  • Template: 提供了当前模板的信息,例如模版的名称和基本路径等。

1.2 创建chart模板

1.创建chart包所需的目录结构,然后删除里面的所有内容

[root@MF-01 helm]# helm create app
Creating app
[root@MF-01 helm]# rm -rf app/templates/*.yaml
[root@MF-01 helm]# rm -rf app/templates/tests/ app/templates/NOTES.txt 
[root@MF-01 helm]# tree app/
app/
├── charts
├── Chart.yaml
├── templates
│   └── _helpers.tpl
└── values.yaml

2 directories, 3 files

2.创建app/templates/deployment.yaml的文件

cat app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demoapp-deploy
  labels:
    app: demoapp
spec:
  replicas: 3
  selector:
    matchLabels:
      role: web
  template:
    metadata:
      labels:
        role: web
    spec:
      containers:
      - name: demoapp
        image: uhub.service.ucloud.cn/oldxu/demoapp:v1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:
          limits:
            memory: 100Mi
          requests:
            memory: 100Mi

1.3 内置对象chart

Chart: 此对象包含了当前Chart的信息

  • .Chart.Name: Chart的名称
  • .Chart.Version: Chart的版本
  • .Chart.Description: Chart的描述
    1.编译app/templates/deployment.yaml的文件
cat app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demoapp-deploy
  labels:
    chartname: {{ .Chart.Name }}   #修改标签的值为内置对象
    version: {{ .Chart.Version }}
spec:
  replicas: 3
  selector:
    matchLabels:
      role: web
  template:
    metadata:
      labels:
        role: web
    spec:
      containers:
      - name: demoapp
        image: uhub.service.ucloud.cn/oldxu/demoapp:v1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:
          limits:
            memory: 100Mi
          requests:
            memory: 100Mi
  1. 检查渲染后的结果
[root@MF-01 helm]# helm install --generate-name ./app --dry-run
NAME: app-1702274555
LAST DEPLOYED: Mon Dec 11 14:02:35 2023
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demoapp-deploy
  labels:
    chartname: app   #修改标签的值为内置对象
    version: 0.1.0
spec:
  replicas: 3
  selector:
    matchLabels:
      role: web
  template:
    metadata:
      labels:
        role: web
    spec:
      containers:
      - name: demoapp
        image: uhub.service.ucloud.cn/oldxu/demoapp:v1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:
          limits:
            memory: 100Mi
          requests:
            memory: 100Mi

1.4 内置对象Release

Release: 对象包含了当前发布release的信息

  • .Release.Name: 发布的名称
  • .Release.Namespace: 发布的命名空间
  • .Release.Revision: 发布的修订号,它从1开始,然后递增
  • .Release.IsInstall: 如果当前操作是安装,则此值为true
  • .Release.IsUpgrade: 如果当前操作是升级,则此值为true
cat app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-deploy
  labels:
    namespace: {{ .Release.Namespace }}
    chartname: {{ .Chart.Name }}   #修改标签的值为内置对象
    version: {{ .Chart.Version }}
spec:
  replicas: 3
  selector:
    matchLabels:
      role: web
  template:
    metadata:
      labels:
        role: web
    spec:
      containers:
      - name: demoapp
        image: uhub.service.ucloud.cn/oldxu/demoapp:v1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:
          limits:
            memory: 100Mi
          requests:
            memory: 100Mi
  1. 检查渲染后的结果
[root@MF-01 helm]# helm install --generate-name ./app --dry-run
NAME: app-1702274954
LAST DEPLOYED: Mon Dec 11 14:09:14 2023
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-1702274954-deploy
  labels:
    namespace: default
    chartname: app   #修改标签的值为内置对象
    version: 0.1.0
spec:
  replicas: 3
  selector:
    matchLabels:
      role: web
  template:
    metadata:
      labels:
        role: web
    spec:
      containers:
      - name: demoapp
        image: uhub.service.ucloud.cn/oldxu/demoapp:v1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:
          limits:
            memory: 100Mi
          requests:
            memory: 100Mi

1.5 内置对象values

Values: 在values.yaml配置文件中定义变量的值,而后在模版文件中调用该变量,就可以将文件中的变量对应的值提取出来,然后完成模版文件的渲染。

  1. 编辑app/templates/deployment.yaml的文件
cat app/templates/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-deploy
  labels:
    namespace: {{ .Release.Namespace }}
    chartname: {{ .Chart.Name }}   #修改标签的值为内置对象
    version: {{ .Chart.Version }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      role: web
  template:
    metadata:
      labels:
        role: web
    spec:
      containers:
      - name: {{ .Release.Name}}
        image: {{ .Values.image.name }}:{{  .Values.image.tags }}
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:
          limits:
            memory: 100Mi
          requests:
            memory: 100Mi
  1. 编辑app/values.yaml的文件
cat app/values.yaml
replicaCount: 5

image:
  name: uhub.service.ucloud.cn/oldxu/demoapp
  tags: "v1.0"
  1. 检查渲染后的结果
[root@MF-01 helm]# helm  install --generate-name ./app/ --dry-run 
NAME: app-1702275897
LAST DEPLOYED: Mon Dec 11 14:24:57 2023
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-1702275897-deploy
  labels:
    namespace: default
    chartname: app   #修改标签的值为内置对象
    version: 0.1.0
spec:
  replicas: 5
  selector:
    matchLabels:
      role: web
  template:
    metadata:
      labels:
        role: web
    spec:
      containers:
      - name: app-1702275897
        image: uhub.service.ucloud.cn/oldxu/demoapp:v1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:
          limits:
            memory: 100Mi
          requests:
            memory: 100Mi

[1.6 内置对象Capabilities
不同版本的kubernetes,可能使用的apversion都不尽相同,为了让开发的chart包兼容新老版本。我们可以利用.Capabilities来获取集群支持的API版本,然后根据这个信息来决定资源清单使用哪个版本的API.这样能够确保Chart在不同版本的Kubernetes集群上正常工作。

  • .Capabilities.APIVersions.Has $version:判断某个版本是否可用apps/v1
  • .Capabilities.Kube.Version: 这是一个对象,包含了kubernetes集群的版本信息,主要用于获取完整的版本字符串。
  • .Capabilities.KubeVersion.GitVersion: 获取Kubernetes集群的Git版本
  • .Capabilities.Kube.Major: 获取 Kubernetes的主版本号
  • .Capabilities.Kube.Minor: 获取 Kubernetes的次版本号

Helm创建出来的Chart中,Ingress资源大量的使用了Capabilities判断逻辑
1.编辑app/templates/deployment.yaml的文件

{{- if .Capabilities.APIVersions.Has "apps/v1" -}}
apiVersion: apps/v1
{{ else }}
apiVersion: extensions/v1beta1
{{- end -}}
kind: Deployment

2.当前kubernetes的apps/v1是可用的,因此会渲染apiVersion为apps/v1,如果不可用则会渲染为extensions/v1beta1

[root@MF-01 helm]# helm template app
---
# Source: app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:

2. chart函数与管道

[2.1 函数介绍

在Helm中,我们已经知道如何将信息传递到模板文件,但是传递到模板文件的内容无法被修改,因此,我们会使用函数来操作或者转换对应的数据。例如,给传递的值添加引号、转换大小写、设定默认值等。

  • 函数的基本语法是 functionName arg1 arg2...,其中 functionName 是函数的名称,arg1, arg2... 是传递给该函数的参数。

  • 例如,{{ quote .Values.version }} 会调用 quote 函数并传递一个参数(.Values.version),这个函数会将传递的参数值转换为字符串并添加引号。

Helm 提供了超过 60 个可用的函数,其中一些是由 Go 模板语言本身定义的,而大部分则来自 Sprig 模板库
2.2 函数管道
在模板语言中还提供了管道技术,它借鉴了UNIX中的管道概念,将前一个表达式的结果传递给后面的函数。也就是说,我们可以使用管道符(|)来连接我们的函数。

例如,.Values.version | quote 会先获取 .Values.version 的值,然后将这个值作为参数传递给 quote 函数。

其次我们还可以使用管道符将多个函数链接在一起,形成一个函数链。例如:{{ .Values.version | default "oldxu" | upper | quote }}。在这个例子中,default "oldxu" 函数会检查 .Values.version 的值是否存在,如果不存在,它会返回默认值 "oldxu",然后交给 upper 函数将其转为大写 "OLDXU",最后交给 quote 函数的结果转换为带有引号的字符串。
3. Chart常用函数
3.1 default函数
default: 这个函数可以提供一个默认值。如果指定的值不存在(或者为空),就会使用默认值。

  1. 修改app/templates/deployment.yaml文件中replicas字段:
replicas: {{ .Values.replicaCount|default 1 }}

2.这个模版会尝试使用values.ayml文件中replicaCount的值,如果这个值不存在或者为空,就会使用默认值1.

# 设定值为2
helm install app-demo ./app/ --set replicaCount=2 --dry-run
replicas: 2
# 将值至为空
helm install app-demo ./app/ --set replicaCount=null --dry-run
replicas: 1

3.2 quote函数
quote: 这个函数可以将一个值转换为字符串,并添加双引号,squote函数添加单引号。

  1. 修改app/templates/deployment.yaml文件中labels字段
labels:
  version: {{ .Values.version | default "oldxu" |upper|quote }}
  1. 这个模版会尝试使用values.yaml文件中replicaCount的值,如果这个值不存在或者为空,就会使用默认值"oldxu",同时会将其转换为大写,并为其添加双引号
[root@master01 helm]# helm install app-demo ./app/ --set version=null --dry-run # 设定值为空
 labels:
   version: "OLDXU"
[root@master01 helm]# helm install app-demo ./app/ --set version=hello --dry-run # 传递字符串hello
 labels:
   version: "HELLO"

3.3 required函数
required: 这个函数可以确保一个值必须存在。如果这个值不存在(或者为空),helm会返回一个错误并停止部署。

  1. 修改app/templates/deployment.yaml文件中image字段
image: {{ .Values.image.name | required "ImageName is required!" }}:{{ .Values.image.tags }}
  1. 这个模版会尝试使用values.yaml文件中image.name的值,如果这个值不存在或者为空,则会报错
[root@master01 helm]# helm install app-demo ./app/ --set image.name=null --dry-run # 如果image.name这个没有值,则会报错
Error: INSTALLATION FAILED: execution error at (app/templates/deployment.yaml:26:39): ImageName is required!

3.4 include函数
include: 这个函数允许在一个模版中引用另一个模版,这样可以复用代码,使模版结构更加清晰。include函数接受两个参数:

  • 第一个是: 要包含的模版的名称
  • 第二个是: 传递给该模版的上下文,用来访问传递的值
    • .表示从顶层开始查找内容
    • .Values.image 表示从values文件中images下查找对应内容的值
  1. 修改app/templates/deployment.yaml文件中name字段
apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "app.fullname" . }}
  1. 检查渲染结果
# Source: app/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-1702280659
  labels:

3.5 toYaml函数
toYaml: 这个函数可以将一个列表或一个字典转换为YAML根式的字符串。在往模版中添加一个复杂的数据结构(如列表或字典)时非常有用

  1. 修改app/templates/deployment.yaml文件中resources字段
resources:
          limits:
            memory: 100Mi
          requests:
            memory: 100Mi
#修改后(toYaml表示读取values文件中的resources字段下的内容,而后转为yaml,nindent 10表示在字符串前面添加10个空格)
resources:
  {{-  toYaml .Values.resources|nindent 10 }}

2.编写app/values.yaml资源文件

[root@MF-01 helm]# cat app/values.yaml 
replicaCount: 5
image:
  name: uhub.service.ucloud.cn/oldxu/demoapp
  tags: "v1.0"
resources:
  limits:
    cpu: 10m
    memory: 100Mi
  requests:
    cpu: 10m
    memory: 100Mi

3.检查最终渲染的结果

spec:
  replicas: 5
  selector:
    matchLabels:
      role: web
  template:
    metadata:
      labels:
        role: web
    spec:
      containers:
      - name: app-1702281213
        image: uhub.service.ucloud.cn/oldxu/demoapp:v1.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: 10m
            memory: 100Mi
          requests:
            cpu: 10m
            memory: 100Mi

3.6 b64enc函数

b64enc: 这个函数主要用来将字符串进行Base64编码。当需要敏感信息(如密码或秘钥)存储在Secrets中时,就非常有用了,因为Secrets要求所有的数据都是Base64编码的。
1.创建app/templates/secret.yaml文件,填写一下内容

apiVersion: v1
kind: Secret
metadata:
  name: {{ .Release.Name }}-secret
type: Opaque
data:
  MYSQL_ROOT_PASSWORD: {{ "oldxu.net" | b64enc }}
  MYSQL_DATABASE: {{ "helm" | b64enc }}

2.验证渲染的结果

[root@MF-01 helm]# helm template app
---
# Source: app/templates/secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: release-name-secret
type: Opaque
data:
  MYSQL_ROOT_PASSWORD: b2xkeHUubmV0
  MYSQL_DATABASE: aGVsbQ== 

4. Chart流程控制

4.1 为何需要流程控制

helm中的流程控制是一种功能,它允许在创建模版时,可以根据特定的条件(比如values文件中的配置)来决定模版的生成过程。
例如,我们可以根据values文件中的一个值,来决定是否在模版中启动ingress的资源、或者通过values文件中的值来决定Pod的存储是否使用emptyDir还是pvc等。为了实现这样的功能,helm的模版语言提供了一些流程控制工具,如 if/else、with和range。

4.2 if/else判断
在helm模版中,if/else结构就像一个开关,用来控制是否要包含某些代码。其基本框架如下:

{{ if CONDITION }}
#做一些事情
{{ else if DIFFERENT_CONDITION }}
#做其他一些事情
{{ else }}
#如果以上条件都不满足,执行这里的代码
{{ end }}

当结果是: 布尔值 false、数字 0 、空字符串、nil(空或者null)、空集合(例如空的map、slice、tuple、dict、array),都会被认为false,在所有其他情况下,结果都会被认为是true。
示例1: 使用if条件语句和values.yaml文件中的某个值,来动态改变ConfigMap的内容。
1.创建app/templates/configmap.yaml,添加如下内容

cat app/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  username: "oldxu"
  {{- if eq .Values.configmap.password "oldxu" }} # 如果values⽂件中的configmap.password=oldxu,则注⼊mug=true字段
  mug: "true"
  {{- end }} # {{- end }} 左侧的-,表示删除左侧空格

2.根据values.yaml文件中的configmap.password值,来决定该configmap的配置文件是啥样子;

helm install --generate-name ./app  --set configmap.password=test --dry-run
---
# Source: app/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-1702285764-configmap
data:
  myvalue: "Hello World"
  username: "oldxu"
==============================================================================
helm  install --generate-name ./app --set configmap.password=oldxu --dry-run
# Source: app/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-1702285890-configmap
data:
  myvalue: "Hello World"
  username: "oldxu"
  mug: "true"

示例2: 使用 values.yaml文件和if条件语句来动态决定是否应用Ingress资源。
1.创建app/templates/ingress.yaml资源文件,添加一个if判断,由用户定义是否启用该资源

cat app/templates/ingress.yaml
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  ingressClassName: "nginx"
  rules:
  - host: app.oldxu.net
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-svc
            port:
              number: 80
{{- end }}

2.根据values.yaml文件中的ingress.enabled值决定是否生成ingress资源

helm install --generate-name --set ingress.enabled=true ./app  --dry-run 
---
# Source: app/templates/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  ingressClassName: "nginx"
  rules:
  - host: app.oldxu.net
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app-svc
            port:
              number: 80

4.3 range循环
很多编程语言支持使用for、while等关键字进行循环操作。在helm中循环使用的range操作符
示例1: 使用values.yaml文件和range函数来动态生成Deployment中的环境变量。
1、修改 app/templates/deployment.yaml ,然后增加 env 字段;

[root@master01 helm]# cat app/templates/deployment.yaml
env:
{{- range .Values.env }} # 这个模板会遍历 values.yaml ⽂件中的env 数组,并⽣成环境变量列表。注意:此时提取变量的作⽤域就限定在.Values.env下,⽽不是全局
- name: {{ .name | quote }} # 通过.name 拿到name的值
  value: {{ .value | quote }} # 通过.value拿到value的值
{{- end }}

2、修改values.yaml文件,添加env环境变量相关信息。

cat app/values.yaml
# Pod环境变量
env:
- name: username
  value: "oldxu"
- name: password
  value: "oldxu"

3.渲染结果

[root@k8s-master01 helm]# helm install --generate-name ./app/ --dry-run
env:
- name: "username"
  value: "oldxu"
- name: "password"
  value: "oldxu"

示例2:使⽤ values.yaml ⽂件和循环来动态⽣成 ConfigMap
1、编辑 app/values.yaml ,编写与configmap相关的字段,让 nginx.conf 作为key,⽂件的内容的作为 value ; nginx-status.conf ⽂件作为key,内容作为 value

 cat app/values.yaml
# Pod相关的ConfigMap配置
AppConfig:
  nginx.conf: |-
    server {
      listen 80;
      server_name app.oldxu.net;
      location / {
        index index.html;
      }
    }
  nginx-status.conf: |-
    server {
    listen 8899;
    stub_status;
    }

2.编辑app/templates/configmap.yaml,然后通过循环方式传递对应的key和value

[root@k8s-master01 helm]# cat app/templates/configmap.yaml
{{- if .Values.AppConfig }}
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  {{- range $key, $val := .Values.AppConfig }}
  {{- $key | nindent 2 }}: |-
    {{- $val | nindent 4 }}
  {{- end }}
{{- end -}}

3.渲染对应的结果

helm install --generate-name ./app/ --dry-run 
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-1691656699-configmap
data:
  nginx-status.conf: |-
    server {
      listen 8899;
    }
  nginx.conf: |-
    server {
      listen 80;
      server_name app.oldxu.net;
      location / {
        index index.html;
      }
    }

4.4 with控制
withif/else 类似,它也可以实现判断逻辑,但是,除了判断以外,with 还会改变模板中后续的上下⽂(或者说 "作⽤域")。这意味着,在 with 块内部可以直接使⽤ . 来访问 with 后⾯的表达式的值,⽽不需要写完整的路径。这个功能可以让你的模板更简洁、更易读。
1、如下示例: . 被重新定义为 .Values.SecurityContext 。因此,在 with 块内部写 .runAsUser 时,实际上是指的 .Values.SecurityContext.runAsUser 。同样, .runAsGroup 实际上是指的 .Values.SecurityContext.runAsGroup

[root@master01 helm]# cat app/templates/deployment.yaml
{{- with .Values.SecurityContext }}
securityContext:
  runAsUser: {{ .runAsUser }}
  runAsGroup: {{ .runAsGroup }}
{{- end }}

2、 values.yaml 配置⽂件内容
这种特性⾮常有⽤,特别是当我们要访问的对象的路径很⻓,或者我们需要多次访
问同⼀个对象的不同属性时。使⽤ with 可以让我们的模板更简洁、更易读。
在模板中,变量的使⽤频率较低,但是我们还是可以使⽤它来简化代码,以便更好
地使⽤ with 和 range。
1、编写 app/templates/configmap.yaml

[root@master01 helm]# cat app/templates/deployment.yaml
{{- with .Values.SecurityContext }}
securityContext:
  runAsUser: {{ .runAsUser }}
  runAsGroup: {{ .runAsGroup }}
{{- end }}

2.values.yaml配置文件内容

[root@master01 helm]# cat app/values.yaml
SecurityContext:
  runAsUser: 1000
  runAsGroup: 1000

这种特性非常有用,特别是当我们要访问的对象路径很长,或者我们需要多次访问同一个对象的不同属性时。使用with可以让我们的模版更简洁,更易读。

4.5 变量

在模板中,变量的使⽤频率较低,但是我们还是可以使⽤它来简化代码,以便更好地使⽤ with 和 range。
1、编写 app/templates/configmap.yaml

[root@k8s-master01 helm]# cat app/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  {{- with .Values.configmap }}
  username: {{ .username | quote }}
  password: {{ .password | quote }}
  release: {{ .Release.Name | quote }}
  {{- end }}

2.编写app/values.yaml

[root@k8s-master01 helm]# cat app/values.yaml
# Pod ConfigMap
configmap:
  username: oldxu
  password: hello

3.渲染对应的配置文件会出现错误,因为Release.Name不在with语句限制的范围之内。

[root@k8s-master01 helm]# helm template app
Error: template: app/templates/configmap.yaml:9:22: executing "app/templates/configmap.yaml" at <.Release.Name>: nil pointer evaluating interface {}.Name
Use --debug flag to render out invalid YAML

4.可以在模版中为Release.Name声明一个变量。变量是对另外一个对象的引用。它使用特殊的方式进行变量赋值$name := values

[root@k8s-master01 helm]# cat app/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  {{- $releasename := .Release.Name -}}
  {{- with .Values.configmap }}
  username: {{ .username | quote }}
  password: {{ .password | quote }}
  release: {{ $releasename | quote }}
  {{- end }}

5、在with语句之前,我们先分配了 $relname := .Release.Name 然后在 with 语句块中, $relname 变量仍然表示 release 的名称 ,因此模板可以得到正确结果

[root@k8s-master01 helm]# helm install --generate-name ./app/ --dry-run
---
# Source: app/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-1691661307-configmap
data:
  username: "oldxu"
  password: "hello"
  release: "app-1691661307"

6、helm中有⼀个变量是 $ , $ 会被映射到根作⽤域, 且执⾏过程中不会更改。因此当我们需要使⽤with获取chart包名称和release名称时,这个功能就⽐较有⽤了

[root@k8s-master01 helm]# cat app/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  {{- with .Values.configmap }}
  username: {{ .username | quote }}
  password: {{ .password | quote }}
  # 这⾥不能引⽤ .Chart.Name,但是可⽤使⽤ $.Chart.Name
  chart: "{{ $.Chart.Name }}-{{ $.Chart.Version }}"
  release: "{{ $.Release.Name }}"
  version: "{{ $.Chart.AppVersion }}"
  {{- end }}

7.渲染结果如下

---
# Source: app/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-1691716608-configmap
data:
  username: "oldxu"
  password: "hello"
  name: app-1691716608
  chart: "app-0.1.0"
  release: "app-1691716608"
  version: "1.16.0"