Helm3 快速入门 —— 3、初识 Chart

第3章、初识 Chart


一、Chart 是什么?

还记得我们在第一章节时介绍 Helm 的三大概念时是如何介绍 chart 这个概念的吗?是的,chart 就像许多语言封装的源码包一样,它是 Helm 使用的封装包的总称。

我们知道,Kubernetes 将其管理的对象称为资源,例如 deployment、service、ingress 等。而 Helm 作为 K8s 的包管理器,其最大的作用就是通过 chart 的方式整合需要管理的 K8s 中的资源,再通过 Helm 客户端 统一交由 K8s api server 去执行。



二、Chart 基础使用

1、查找 Chart

Helm 提供了2种搜索命令,可用用来从两种来源中进行搜索:

  • helm search hub:从 Artifact Hub 中查找并列出 helm charts。 Artifact Hub中存放了大量不同的仓库。
  • helm search repo:从你添加(使用 helm repo add)到本地 helm 客户端中的仓库中进行查找。该命令基于本地数据进行搜索,无需连接互联网。

1)搜索所有公开可用的 charts

执行以下命令从 Artifact Hub 中搜索所有的 wordpress charts:

# 命令: helm search hub  
helm search hub wordpress
helm search hub

2)搜索本地 stable 源中可用的 charts

# 命令: helm search repo 
helm search repo stable
helm search repo

3)模糊匹配搜索

Helm 的搜素使用模糊字符串匹配算法,只需要输入名字的一部分就可以从本地仓库记录中进行搜索,如下搜索 word

# 命令: helm search repo 
helm search repo word
模糊匹配

2、安装 Chart

使用 helm search 找到你想要安装的 helm包后,就可以使用 helm install 来进行安装。最简单使用方案只需要传入两个参数:release的名字chart的名称

1)安装helm包

执行以下命令,即创建了一个新的 release 对象,命名为 happy-panda ,如果想要自动生成一名名称,可以使用--generate-name 参数:

# 命令: helm install   (chart名称须具体,如 bitnami/wordpress。不能只是关键字)
helm install happy-panda bitnami/wordpress
helm install

2)查看运行状态

helm list

返回如下:

NAME        NAMESPACE   REVISION    UPDATED                                 STATUS      CHART               APP VERSION
happy-panda default     1           2021-06-29 10:51:13.437131205 +0800 CST deployed    wordpress-11.0.16   5.7.2  

3)查看发布状态

# 命令: helm status 
helm status happy-panda

返回值和安装时的返回一样。

4)卸载helm包

# 命令: helm uninstall 
helm uninstall happy-panda

3、下载 Chart

Helm 的 chart 同时也支持下载,下载下来的是一个tar包,解压后即可获得官方的 chart 目录,基于目录中提供的文件,我们可以对其中的内容进行修改,进行自定义的发布,同时也可以学习其语法。

1)下载

# 命令: helm pull  (chart名称须具体,如 bitnami/kong。不能只是关键字)
helm pull bitnami/kong
helm pull

2)解压

tar xf kong-3.7.5.tgz 
image-20210701103958115.png

3)目录结构

kong
├── Chart.lock
├── charts                      # kong 的 chart 依赖的其他 chart,数据库
│   ├── cassandra
│   ├── common
│   └── postgresql
├── Chart.yaml                  # 包含了chart信息的YAML文件
├── ci
│   ├── values-editing-containers.yaml
│   ├── values-external-cassandra.yaml
│   ├── values-external-postgresql.yaml
│   ├── values-ingress.yaml
│   └── values-metrics-hpa-pdb.yaml
├── crds                        # 自定义资源
│   └── custom-resource-definitions.yaml
├── README.md
├── templates                   # 资源模版,配置 values 进行渲染,生产有效的 K8s manifest
│   ├── dep-ds.yaml
│   ├── external-database-secret.yaml
│   ├── extra-list.yaml
│   ├── _helpers.tpl
│   ├── hpa.yaml
│   ├── ingress-controller-rbac.yaml
│   ├── ingress.yaml
│   ├── kong-prometheus-rolebinding.yaml
│   ├── kong-prometheus-role.yaml
│   ├── kong-script-configmap.yaml
│   ├── metrics-exporter-configmap.yaml
│   ├── metrics-script-configmap.yaml
│   ├── metrics-service.yaml
│   ├── migrate-job.yaml
│   ├── NOTES.txt
│   ├── pdb.yaml
│   ├── servicemonitor.yaml
│   ├── service.yaml
│   └── tls-secrets.yaml
└── values.yaml                  # chart 默认的配置值


4、自建 Chart

除了从远程 helm 仓库中获取官方或三方的 chart 外,Helm 更加重要的功能在于自建 chart,它会创建一个 chart 需要的最小化目录结构以及各必要文件的模版。chart 的整体构造比较类似 ansible 的 roles。

# 命令: helm create 
helm create test_chart
helm create

5、检查 Chart

Helm 自动了语法检查工具,其作用类似 nginx -t,会对 chart 的格式或者一些信息进行自检,并返回检查结果,在发布前,进行语法检查是很好的选择。

# 命令: helm lint 
helm lint test_chart
helm lint

6、上传 Chart

1)打包 Chart

在上面的一系列操作中我们知道,Helm 仓库中存放的是一个个的 tar 包,而不是目录,因此如果你想上传自建的 chart,就需要将其先行打包。Helm 提供了这样一个命名来将你自建的 chart 打包出 Helm 可识别的格式。

# 命令: helm package 
helm package test_chart
helm package

为什么版本是 0.1.0?

这是由 Chart.yaml 中的 version 字段决定的。

image-20210701111524833.png

2)上传至私有仓库

四个步骤:

1)自建私有仓库

2)生成、更新 chart 索引文件

3)上传 chart 和索引文件

4)更新本地 chart 仓库

具体内容在后续章节中介绍


3)上传至 Helm Hub

参考文档:
https://blog.csdn.net/jeffzhesi/article/details/106565173



三、Chart 语法释义

1、chart 基本元素释义:

test_chart
├── charts                        # 可选: 本 chart 依赖的其他 chart
├── Chart.yaml                    # 必需: 用于描述 chart 相关信息,包括名称、描述信息、api版本等
├── templates                     # 必需: 做用于 K8s 资源的 yaml 模版
│   ├── deployment.yaml           # 用于生成 K8s deployment 资源的 yaml 模版,发布应用的基本元素
│   ├── _helpers.tpl              # 用于定义一些可重用的模板片断,在此文件中的定义在任何资源定义模板中都可用
│   ├── hpa.yaml                  # 用于生成 K8s hpa 的 yaml 模版,如服务需要弹性伸缩策略,则在该模版中定义
│   ├── ingress.yaml              # 用于生成 K8s ingress 的 yaml 模版,如果服务需要对外放出,则在该模版中定义 ingress
│   ├── NOTES.txt                 # 必需: 用于介绍 chart 部署后的一些信息,比如如何使用这个 chart、列出缺省设置等
│   ├── serviceaccount.yaml       # 用于生成 K8s serviceaccount 资源的 yaml 模版,如需要创建特定认证对象,则在该模版中定义
│   ├── service.yaml              # 用于生成 K8s service 资源的 yaml 模版,发布应用的基本元素
│   └── tests                     # helm 的测试钩子
│       └── test-connection.yaml
└── values.yaml                   # 必需: 用于存储要渲染至 templates/ 下模版文件中的值

2、Chart.yaml

一个标准的 Chart.yaml 包含以下字段:

apiVersion:                 # 必需: chart API 版本, v2 版本为 helm3 语法,v1 版本仍然保留使用
name:                       # 必需: chart名称
version:                    # 必需: chart 的版本控制标识
kubeVersion:                # 可选: 兼容Kubernetes版本的语义化版本,可以使用运算符,形式如 >= 1.13.0 < 1.15.0
description:                # 可选: 对于这个 chart 的描述信息
type:                       # 可选: chart类型, 支持2种类型,application 和 library,默认使用 application
keywords:                   # 可选: 关于项目的一组关键字
  - xxx                 
  - xxx
home:                       # 可选: 项目home页面的URL
sources:                    # 可选: 项目源码的URL列表
  - xxx
  - xxx
dependencies:               # 可选: chart 的依赖项,执行 `helm dep up ` 更新依赖,依赖的 chart包 会下载至 charts/ 
  - name:                   # chart名称, 如 nginx
    version:                # chart版本, 如 "1.2.3"
    repository:             # 可选: 仓库的完整URL ("https://example.com/charts") 或别名 ("@repo-name")
    condition:              # 可选: 解析为布尔值的yaml路径,用于启用/禁用chart (e.g. subchart1.enabled )
    tags:                   # 可选: 用于一次启用/禁用 一组chart的tag
      - xxx
      - xxx
    import-values:          # 可选: 保存源值到导入父键的映射。每项可以是字符串或者一对子/父列表项
      - ImportValue  
    alias:                  # 可选: 依赖 chart 的别名。当你要多次添加相同的chart时会很有用
maintainers:                # 可选: 维护者信息
  - name:                   # 维护者名字 (每个维护者都需要)
    email:                  # 维护者邮箱 (每个维护者可选)
    url:                    # 维护者URL (每个维护者可选)
icon:                       # 可选: 用做icon的SVG或PNG图片URL
appVersion:                 # 可选: 与版本控制的 version 无关,用于指定应用的版本
deprecated:                 # 可选: 标记该 chart 已废弃,使用方法为布尔值
annotations:
  example:                  # 可选: 按名称输入的批注列表

1)使用 dependencies 表达式管理依赖

1. 基本原则

Helm3 中,弃用了 requeirements.yamldependencies 字段被合并至了 Chart.yaml 中,但是就语法表达式来说,和之前没有太大的变化。使用方式比较类似 ansible 的 playbook 或 docker compose,其表达式如下,是一个列表形式:

dependencies:
  - name: nginx
    version: 2.0.1
    repository: https://example.com/charts
  - name: mysql
    version: 3.2.1
    repository: https://another.example.com/charts
  • name 字段:所需依赖 chart 的名称

  • version 字段:所需依赖 chart 的版本

  • repository 字段:chart 仓库的完整 URL 或者 仓库的名称

    使用 URL :https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts

    使用 仓库名称:@stable

仓库必须事先使用 helm repo add 添加,执行类似如下命令:

helm repo add stable https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
2. 示例说明
1⃣️ 添加仓库
helm repo add bitnami https://charts.bitnami.com/bitnami  
2⃣️ 写依赖表达式
dependencies:
  - name: nginx
    version: 9.3.3
    repository: "@bitnami"
  - name: mariadb
    version: 2.1.6
    repository: "@bitnami"
3⃣️ 更新依赖
helm dependency update
更新依赖

依赖的 chart 包 会被下载到 charts/ 目录下:

chart包

2)通过 charts/ 目录手动管理依赖

Helm 提供了两种管理依赖的方式,一种是如上所述的 dependencies 表达式,它会遵循语法原则,自动的管理依赖,依赖包会被下载到 charts/ 中;另一种方式就是通过 charts/ 目录来手动管理依赖,这种方式可以对依赖的 chart 做更多的自定义设置。

1. 基本原则
  • charts/ 下管理的依赖必须是一个 chart 包xxx-1.0.1.tgz)或是一个解压的 chart 目录
  • 依赖的名称不能以 _. 开头,否则会被 chart 加载器忽略
  • 可以使用 helm pull 将依赖下载到 charts/
2. 示例说明

比如 WordPress 的 chart 依赖 Apache 和 mariadb,其目录形式应该如下:

wordpress:
  Chart.yaml
  # ...
  charts/
    apache/
      Chart.yaml
      # ...
    mariadb/
      Chart.yaml
      # ...
    memcached/
        Chart.yaml
      # ...

3)dependencies 中 condition 和 tags 使用释义

1. 基本原则:
  • 条件(condition)优先

    当设置 value 时,如果同时存在 conditiontags 的值,那么 condition 的效果会覆盖 tags 的效果。

  • 标签(tags)最小化元素

    tags 中的任意一个元素的值被设置为 true 时,带有该 tags 的 chart 就会被启用。

  • conditiontags 在 values.yaml 中必需在缩进的最顶层

  • tags 在 values.yaml 中需以以下形式:

    tags:
      xxx
      xxx
    
2. 示例说明:

文件: test_chart/Chart.yaml

dependencies:
  - name: subchart1
    repository: http://localhost:10191
    version: 0.1.0
    condition: subchart1.enabled, global.subchart1.enabled
    tags:
      - front-end
      - subchart1
  - name: subchart2
    repository: http://localhost:10191
    version: 0.1.0
    condition: subchart2.enabled,global.subchart2.enabled
    tags:
      - back-end
      - subchart2

文件: test_chart/values.yaml

subchart1:
  enabled: true

如上表达式表示,condition 中带有 subchart1 的 chart 会被启动

tags:
  front-end: false
  back-end: true

如上表达式表示,tags 中带有 back-end 的 chart 会被启动,而带有 front-end 的则不会被启动

subchart1:
  enabled: true
tags:
  front-end: false
  back-end: true

如上表达式,当 conditiontags 一起使用时,是会发生效果覆盖的,比如,虽然 front-end 设置为了 false,但是由于 subchart1.enabled 设置为 true,条件发生覆盖,所以 chart subchart1 还是会被启用。

而当 back-end 设置为 true 的时候,条件读取的就是 back-end: true ,因此,即使没有设置 subchart2.enabledtrue,chart subchart2 也会被启用。


4)dependencies 中的 alias 使用释义(了解)

1. 基本原则

dependencies 的表达式中,可以使用 alias 对需求项添加别名,当存在依赖多次复用的时候就可以通过别名的方式来访问该需求项,以此加以区分。(比如 数据库的主从、集群等使用场景)

2. 示例说明

文件: parent_chart/Chart.yaml

dependencies:
  - name: subchart
    repository: http://localhost:10191
    version: 0.1.0
    alias: new-subchart-1
  - name: subchart
    repository: http://localhost:10191
    version: 0.1.0
    alias: new-subchart-2
  - name: subchart
    repository: http://localhost:10191
    version: 0.1.0

如上情况,parent_chart 中相当于有 3 个依赖项,subchartnew-subchart-1new-subchart-2 ,虽然他们是基于同一个 chart 的,但是可以被区别对待。


5)dependencies 中的 import-values 使用释义(了解)

从上文中,我们知道,在 charts/ 目录下面管理的其实也是 chart,那么它就会遵循 chart 的原则,那么这种情况下,目录结构就是一种 父-子 的关系。在某些场景中,我们可能会需要读取 子 char 的值,Helm 则提供了 import-values 这样一种实现方式。

1. 基本原则
  • 目录结构和文件关系如下

    parent_chart:           # 父 chart
      Chart.yaml            # dependencies - child_chart - import-values - Key
      # ...
      charts/
        child_chart/    # 子 chart
          Chart.yaml    
          values.yaml   # exports - Key - value
          # ...
    
  • 加载器会根据 dependencies - name子 chart,根据 dependencies - import-values 的 key 解析 子 chart 中对应的值

  • 加载器默认识别 exports

  • 没有 exports ,需要以 parent-child 方式明确指明要注入的 子 chart 的值的 Key 和 要被注入的 父 chart 的值的名称

  • import 子 chart 所得的值最终会被合并入 父 chart 的 values 中,并会覆盖原有键值

2. 示例说明
1⃣️ 使用 exports 的方式

文件: parent_chart/Chart.yaml

dependencies:
  - name: child_chart
    repository: http://localhost:10191
    version: 0.1.0
    import-values:
      - data                    # 引用子 chart 的变量 - data

文件: parent_chart/charts/child_chart/values.yaml

exports:                            # 声明变量 data
    data:
        port: 3306

Helm 会在 import-values 的列表到入内容时,将其中的元素作为 Key,并以此到 子 chartexports 字段查找对应的 Key,并将对应的 value 注入 父 chart 的 values 中,所以最终我们可以在 父 chart 中可获取到的值为:

port: 3306
2⃣️ 使用 parent — child 的方式

⚠️ 注意:

如果在 子 chart 的 values.yaml 中没有使用 exports ,就必须指定要注入的 子 chart 值的 源Key 以及 被注入的 父 chart 的值的名称。

文件: parent_chart/Chart.yaml

dependencies:
  - name: child_chart
    repository: http://localhost:10191
    version: 0.1.0
    ...
    import-values:
      - child: default.data
        parent: myimports

文件: parent_chart/charts/child_chart/values.yaml

default:
  data:
    myint: 999
    mybool: true

文件: parent_chart/values.yaml

myimports:
  myint: 0
  mybool: false
  mystring: "helm tests!"

如上述示例,import-values 的加载器,根据 child 去 child_chart 的 values.yaml 中找 default - data ,并解析出其值,并将其注入到 父 chart 中,并会覆盖原有的键值,由此 父 chart 最终的 values 会合并如下:

myimports:
  myint: 999
  mybool: true
  mystring: "helm tests!"

3、templates/ 和 values.yaml

1)Values 的生效机制

Values 通过模板中.Values对象可访问的values.yaml文件,也可以通过 .Chart 对象可访问的 Chart.yaml ,以此类推。另外 ,Helm 中有一些预定义的 values,可以将其视为环境变量,具体如下:

  • .Release

    该对象描述了版本发布本身。

    使用方法如,{{ .Release.Name }} (获取 release 的名称)

  • .Values

    访问 values.yaml 的内容。

    使用方法如,{{ .Values.image.repository }} (获取 values.yaml 中 image - repository 的值)

  • .Chart

    访问 Chart.yaml 的内容。

    使用方法如, {{ .Chart.Version }} (获得 chart 的版本)、{{ .Chart.Maintainers }} (获取 chart 的维护者)

    语法风格遵循 go 模版规则,类似 jinja2。是一种层级检索的方式,. 表示层级,最顶层的 .

  • .Files

    访问 chart 中存在的文件的内容 (.helmignore 除外)。

    使用方法如,{{ index .Files "file.name" }} (获取该文件中 name的值),它等效于 {{ .Files.Get name }} 方法。

    {{ .Files.GetBytes }} 方法等效于访问文件中的 []byte 对象

  • .Capabilities

    访问 K8s 的 Capabilities 对象。

    使用方法如,{{ .Capabilities.KubeVersion }} (获取 K8s 版本)、{{ .Capabilities.APIVersions.Has "batch/v1" }}(获取支持的 K8s API 版本)


2)templates/ 中的模版

模板文件遵守书写Go模板的标准惯例(查看 文本/模板 Go 包文档了解更多)。以发布一个 nginx 的 templates/deployment.yaml 的示例模版为例,内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Chart.Name  }}
spec:
  {{- if not .Values.autoscaling.enabled }}
  replicas: {{ .Values.replicaCount }}
  {{- end }}
  selector:
    matchLabels:
      app: {{ .Chart.Name }}
  template:
    metadata:
      labels:
        app: {{ .Chart.Name }}
    spec:
      imagePullSecrets:
            - name: harborsecret
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - name: http
              containerPort: {{ .Values.service.port }}
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            {{- toYaml .Values.resources | nindent 12 }}
      {{- with .Values.nodeSelector }}
      nodeSelector:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
      {{- end }}
      {{- with .Values.tolerations }}
      tolerations:
        {{- toYaml . | nindent 8 }}
      {{- end }}

3)取值 values.yaml 渲染模版

根据如上模版的变量关系,进行对应文件 value 的配置,涉及到 Chart.yamlvalues.yaml 两个文件:

1. Chart.yaml 的必要值
apiVersion: v2
name: test_chart
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: "1.16.0"
2. values.yaml 的必要值
replicaCount: 1

image:
  repository: nginx
  tag: "stable"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 80

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

autoscaling:              # hpa 需求,可以不管
  enabled: false
  minReplicas: 1
  maxReplicas: 100
  targetCPUUtilizationPercentage: 80
  # targetMemoryUtilizationPercentage: 80

nodeSelector: {}

tolerations: []

affinity: {}
3. 验证渲染效果

我们可以通过在 helm install 时使用 --dry-run 参数来只渲染模版,而进行直接部署,这样我们就可以验证效果了。执行如下命令:

helm install --dry-run demo test_chart/

渲染后的 manifest 如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test_chart
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test_chart
  template:
    metadata:
      labels:
        app: test_chart
    spec:
      imagePullSecrets:
        - name: harborsecret
      containers:
        - name: test_chart
          image: "nginx:stable"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            limits:
              cpu: 100m
              memory: 128Mi
            requests:
              cpu: 100m
              memory: 128Mi

4)--set 指定参数渲染

当我们在执行 helm install 或者 helm upgrade 时,除了直接通过 values.yaml 渲染外,也支持直接在命令行通过 --set 参数传参,传入的参数会覆盖 values.yaml 中的预设值

示例:通过 --set 修改 镜像版本端口
helm install --set image.tag="1.16.0" --set service.port=9999 --dry-run demo test_chart/

渲染后的 manifest 如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test_chart
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test_chart
  template:
    metadata:
      labels:
        app: test_chart
    spec:
      imagePullSecrets:
        - name: harborsecret
      containers:
        - name: test_chart
          image: "nginx:1.16.0"                 # 镜像版本由原来的 stable 更改为 1.16.0
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 9999               # 端口由原来的 80 更改为 9999
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            limits:
              cpu: 100m
              memory: 128Mi
            requests:
              cpu: 100m
              memory: 128Mi

5)通过 -f 指定 Values 文件

chart 默认的 Values 文件命名为 values.yaml,当你在执行 helm installhelm upgrade 时,如果名称不是 values.yaml,执行就会出错。通过命令行 -f 参数,可以指定 Values 文件,这样文件的名称就不受限制了。

示例:

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

replicaCount: 1

image:
  repository: mysql
  tag: "8.7.0"
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 3306

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

autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 100
  targetCPUUtilizationPercentage: 80
  # targetMemoryUtilizationPercentage: 80

nodeSelector: {}

tolerations: []

affinity: {}

执行如下命令,进行渲染测试:

helm install -f test_chart/demo.yaml --dry-run demo test_chart

渲染后的 manifest 如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: test_chart
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test_chart
  template:
    metadata:
      labels:
        app: test_chart
    spec:
      imagePullSecrets:
        - name: harborsecret
      containers:
        - name: test_chart
          image: "mysql:8.7.0"                  # 镜像已更改
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 3306               # 端口已更改
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /
              port: http
          readinessProbe:
            httpGet:
              path: /
              port: http
          resources:
            limits:
              cpu: 100m
              memory: 128Mi
            requests:
              cpu: 100m
              memory: 128Mi

4、架构文件 values.schema.json

是否还记得,在第1章中我们介绍过 Helm3 的新功能中增加了 使用JSON Schema 来验证 Chart 的 Values 的机制?事实上,它在 Chart 的表现就是 values.schema.json 文件。在其中required 可以用于定义哪些字段是必须的,type 可用用于定义哪些字段需要是什么字段类型等。

当我们在执行如下命令时,Helm 将会以该 Json 定义的架构格式去验证 .Values 对象是否符合规格,只有当验证通过后,才能正常发送给 K8s 执行。

  • helm install
  • helm upgrade
  • helm lint
  • helm template

1)格式示例:

{
  "$schema": "https://json-schema.org/draft-07/schema#",
  "properties": {
    "image": {
      "description": "Container Image",
      "properties": {
        "repo": {
          "type": "string"
        },
        "tag": {
          "type": "string"
        }
      },
      "type": "object"
    },
    "name": {
      "description": "Service name",
      "type": "string"
    },
    "port": {
      "description": "Port",
      "minimum": 0,
      "type": "integer"
    },
    "protocol": {
      "type": "string"
    }
  },
  "required": [
    "protocol",
    "port"
  ],
  "title": "Values",
  "type": "object"
}

2)示例说明

required 字段定义了 Values 中必要的字段,如上例所示,即 protocolport 。另外,name 默也是必须的,因为 service name 是一个 Release 的必要元素,因此,一个符合该架构要求的最精简 values.yaml 应该如下:

name: nginx
protocol: http
port: 80

⚠️ 注意:

上面有提到过,架构文件验证的对象是 .Values 对象,而不是 values.yaml ,也就是说,使用 --set 指定的参数也属于其检测的范畴,因此,如下这种情况也是可以的通过检查的:

values.yaml

name: fronend
protocol: https

命令行指定 port

helm install --set port=443

5、用户自定义资源 —— CRD

CRDCustom Resource Definition)是 K8s 提供的一种自定义资源对象的机制。在 Helm3 中,使用 crds/ 目录来对其进行管理,Helm3 会在安装 chart 之前检查该目录是否存在 CRD 的 yaml 文件,如果存在,则会先加载该目录下的 所有yaml文件至 K8s,然后再进行 chart 的发布。

⚠️ 注意以下几点:

  • 多个 CRD 的表达式可以写在一个 yaml 文件中,但需要以 开始结束符 " --- " 进行分割
  • CRD文件无法套用 Helm 模版,必须是普通的 yaml 格式文件
  • 安装 chart 时,会先上传 CRD(如有),并同时暂停安装,直到 CRD 被 api server 调用,才会开始后续 chart 渲染步骤。

1)使用示例

如果要创建一个针对 crontab 的 CRD,需要遵循以下目录结构和语法规则:

1. 目录结构
test_chart/
  Chart.yaml
  crds/
    crontab.yaml
  templates/
    mycrontab.yaml
2. crontab.yaml 的写法

⚠️ 注意: CRD 不支持 Helm 模版指令,所以 crontab.yaml 只能使用 K8s 经典声明表达式。

kind: CustomResourceDefinition
metadata:
  name: crontabs.stable.example.com
spec:
  group: stable.example.com
  versions:
    - name: v1
      served: true
      storage: true
  scope: Namespaced
  names:
    plural: crontabs
    singular: crontab
    kind: CronTab
3. mycrontab.yaml 模版文件

CRD 的信息在被加载至 K8s 后,就会在 Helm 模版的 .Capabilities 中生效,指定 apiVersion 就可以引用。和其他资源对象一样,你需要通过创建模版,并通过 Values 渲染来创建实例。CRD 的模版文件同其他 template 文件一样。

apiVersion: stable.example.com
kind: CronTab
metadata:
  name: {{ .Values.name }}
spec:
   # ...

2)CRD 的限制

和大部分的 K8s 资源对象不同,CRD 是全局性的,故 Helm 对其的管理较为慎重,并对其设置了一下限制:

  • 不会重复安装

    如果 crds/ 目录下的 CRD已存在,无论是否有版本区别,都不会重新安装覆盖,不会自动升级

  • 不会在升级、回滚时安装

    只有在第一次 helm install 时才会被安装

  • 不会被自动删除

    自动删除 CRD 会删除所有 namespace 中的所有 CRD ,故不能通过 Helm 删除

    希望升级或删除 CRD,需要进行手动操作,操作需谨慎

你可能感兴趣的:(Helm3 快速入门 —— 3、初识 Chart)