Helm Chart 使用简析

文章目录

  • 一、Chart 文件结构
  • 二、Chart 模版赋值
    • 2.1 通过values.yaml文件取值
    • 2.2 手动使用 --set 指定
    • 2.3 通过 -f 指定文件
  • 三、Chart 模版语法
    • 3.1 quote 函数
    • 3.2 管道
    • 3.3 default 函数
    • 3.4 indent 函数
    • 3.5 with
    • 3.6 变量
    • 3.7 if-else
  • 四、命名模板
  • 五、参考链接

一、Chart 文件结构

[root@harbor ~]# tree mychart/
mychart/                             # Chart 目录
├── charts                           # 这个 charts 依赖的其他 charts,始终被安装
├── Chart.yaml                       # 描述这个 Chart 的相关信息、包括名字、描述信息、版本等
├── templates                        # 模板目录
│   ├── deployment.yaml              # deployment 控制器的 Go 模板文件
│   ├── _helpers.tpl                 # 以 _ 开头的文件不会部署到 k8s 上,可用于定制通用信息
│   ├── hpa.yaml                     # hpa 的模板文件
│   ├── ingress.yaml                 # ingress 的模板文件
│   ├── NOTES.txt                    # Chart 部署到集群后的一些信息,例如:如何使用、列出缺省值
│   ├── serviceaccount.yaml          # serviceaccount 的 Go 模板文件
│   ├── service.yaml                 # service 的 Go 模板文件
│   └── tests                        # 测试pod目录
│       └── test-connection.yaml     # 测试pod的deployment文件
└── values.yaml                      # 模板的值文件,这些值会在安装时应用到 GO 模板生成部署文件

二、Chart 模版赋值

该对象提供对传入 chart 的值的访问。其内容来自四个来源:

  • chart 中的 values.yaml 文件
  • 如果这是一个子 chart,来自父 chart 的 values.yaml 文件
  • value 文件通过 helm installhelm upgrade 的 - f 标志传入文件(helm install -f myvals.yaml ./mychart
  • 通过 --set(例如 helm install --set foo=bar ./mychart

上面的列表按照特定的顺序排列:values.yaml 在默认情况下,父级 chart 的可以覆盖该默认级别,而该 chart values.yaml 又可以被用户提供的 values 文件覆盖,而该文件又可以被 --set 参数覆盖。

2.1 通过values.yaml文件取值

创建 mychart

helm create mychart

编辑 values.yaml 文件。将 service.port 值改为 8888

···
 service:
  type: ClusterIP
  port: 8888
···

查看渲染前的 service.yaml 模版

apiVersion: v1
kind: Service
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    {{- include "mychart.selectorLabels" . | nindent 4 }}

使用 --dry-run 命令只渲染模版,而不安装

helm install --dry-run demo mychart/

查看渲染后的 service.yaml 文件,可以看到 8888 已经被渲染进模版

---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-mychart
  labels:
    helm.sh/chart: mychart-0.1.0
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 8888
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
---

2.2 手动使用 --set 指定

注意--set 的值会覆盖 values.yaml 中预设的值

使用 --set 命令,将 service.port 值更改为 9999

helm install --set service.port=9999 --dry-run demo mychart/

查看渲染后的 service.yaml 文件,可以看到 9999 已经被渲染进模版

---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-mychart
  labels:
    helm.sh/chart: mychart-0.1.0
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 9999
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
---

2.3 通过 -f 指定文件

创建 demo.yaml 文件,内容如下

 service:
  type: ClusterIP
  port: 7777

通过指定 demo.yaml 文件渲染

···
helm install -f /root/demo.yaml --dry-run demo mychart/
···

查看渲染后的 service.yaml 文件,可以看到 7777 已经被渲染进模版,说明指定的文件会覆盖 values.yaml 中相同的参数。

---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-mychart
  labels:
    helm.sh/chart: mychart-0.1.0
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 7777
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
---

三、Chart 模版语法

3.1 quote 函数

当从 .Values 对象注入字符串到模板中时,我们引用这些字符串。我们可以通过调用 quote 模板指令中的函数来实现

apiVersion: v1
kind: Service
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
spec:
  type: {{ quote .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    {{- include "mychart.selectorLabels" . | nindent 4 }}

渲染后的 service.yaml 文件

---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-mychart
  labels:
    helm.sh/chart: mychart-0.1.0
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: "ClusterIP"
  ports:
    - port: 8888
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
---

3.2 管道

模板语言的强大功能之一是其管道概念。利用 UNIX 的一个概念,管道是一个链接在一起的一系列模板命令的工具,以紧凑地表达一系列转换。换句话说,管道是按顺序完成几件事情的有效方式。

apiVersion: v1
kind: Service
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
spec:
  type: {{ .Values.service.type | upper |quote }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    {{- include "mychart.selectorLabels" . | nindent 4 }}

渲染后的 service.yaml 文件

"ClusterIP" 已变成 "CLUSTERIP"

---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-mychart
  labels:
    helm.sh/chart: mychart-0.1.0
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: "CLUSTERIP"
  ports:
    - port: 8888
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
---

3.3 default 函数

经常使用的一个函数是 default:default DEFAULT_VALUE GIVEN_VALUE。该功能允许在模板内部指定默认值,以防该值被省略。
注释掉 values.yaml 文件中的port

···
service:
  type: ClusterIP
  port:
···

service.yaml 中的port默认值设为 9999

apiVersion: v1
kind: Service
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port | default 9999 }}
      targetPort: http
      protocol: TCP
      name: http
  selector:
    {{- include "mychart.selectorLabels" . | nindent 4 }}

渲染后的 service.yaml 文件,已经设置为默认值 9999

---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-mychart
  labels:
    helm.sh/chart: mychart-0.1.0
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 9999
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
---

3.4 indent 函数

indent 模板函数,从左开始流出指定空格

values.yaml 文件取消注释以下内容

resources: 
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 100m
    memory: 128Mi

deployment.yaml 文件内容,取出 values.yamlresources 的值,并以左边添加12个空格的格式渲染

···
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
···

查看渲染后的deployment.yaml 文件

···
          resources:
            limits:
              cpu: 100m
              memory: 128Mi
            requests:
              cpu: 100m
              memory: 128Mi
···

3.5 with

with 可以允许将当前范围 . 设置为特定的对象。例如,.Values.service,使用 with 可以将 .Values.service 改为 .

现在我们可以引用 .port.type 无需对其进行限定。这是因为该 with 声明设置 . 为指向 .Values.service。在 {{ end }}. 复位其先前的范围。

apiVersion: v1
kind: Service
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
spec:
  {{- with .Values.service }}
  type: {{ .type }}
  ports:
    - port: {{ .port }}
      targetPort: http
      protocol: TCP
      name: http
  {{- end }}
  selector:
    {{- include "mychart.selectorLabels" . | nindent 4 }}

查看渲染后的service.yaml 文件

---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-mychart
  labels:
    helm.sh/chart: mychart-0.1.0
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 8888
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
---

3.6 变量

Helm 模板中,变量是对另一个对象的命名引用。它遵循这个形式 $name。变量被赋予一个特殊的赋值操作符::=

apiVersion: v1
kind: Service
metadata:
  name: {{ include "mychart.fullname" . }}
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
spec:
  {{- $portname := .Release.Name }}
  {{- with .Values.service }}
  type: {{ .type }}
  ports:
    - port: {{ .port }}
      targetPort: http
      protocol: TCP
      name: {{ $portname }}
  {{- end }}
  selector:
    {{- include "mychart.selectorLabels" . | nindent 4 }}

查看渲染后的service.yaml 文件

---
# Source: mychart/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: demo-mychart
  labels:
    helm.sh/chart: mychart-0.1.0
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm
spec:
  type: ClusterIP
  ports:
    - port: 8888
      targetPort: http
      protocol: TCP
      name: demo
  selector:
    app.kubernetes.io/name: mychart
    app.kubernetes.io/instance: demo
---

3.7 if-else

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

如果值为如下情况,则管道评估为 false。

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

在其他情况下, 条件值为 true 此管道被执行。

values.yaml内容

favorite:
  drink: coffee
  food: pizza

configmap.yaml内容

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{.Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {{.Values.favorite.drink }}
  food: {{.Values.favorite.food }}
  {{- if eq .Values.favorite.drink "coffee" }}
  mug: true
  {{- end}}

渲染后的模版

# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: clunky-cat-configmap
data:
  myvalue: "Hello World"
  drink: "coffee"
  food: "PIZZA"
  mug: true

四、命名模板

一般在 template 文件夹下的 _helpers.tpl 中定义命名模板。通过 define 函数定义命名模板,template 使用命名模板。

_helpers.tpl文件内添加一个模版

···
{{/*
Demo template
*/}}
{{- define "my_labels" }}
  labels:
    generator: helm
    date: {{ now | htmlDate }}
    chart: {{ .Chart.Name }}
    version: {{ .Chart.Version }}
{{- end }}

configmap 中使用该模版

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
  {{- template "my_labels" . }}

查看渲染后的 configmap.yaml

---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: demo-configmap
  labels:
    generator: helm
    date: 2020-07-17
    chart: mychart
    version: 0.1.0
---

五、参考链接

https://whmzsu.github.io/helm-doc-zh-cn/
https://juejin.im/post/5d5b8dba6fb9a06b1b19c21b
https://www.cnblogs.com/cjwnb/p/12571199.html#_lab2_0_1

你可能感兴趣的:(Kubernetes)