helm 二、制作Chart(上)

大番茄 2020年02月23日 1,729次浏览

helm version: v3.1.0

一些惯例:
https://helm.sh/docs/topics/chart_best_practices/conventions/

  1. chart名称由小写与数字组成,单词之间可以用 - 连接。
    如:
drupal
nginx-lego
aws-cluster-autoscaler
  1. 不能使用大写字母和下划线以及圆点。
  2. chart目录必须与chart的名称一致。
  3. 版本号必须使用SemVer 2表示版本号:
    由MAJOR.MINOR.PATCH组成(主版本.次版本.补丁):
    MAJOR, 当您进行不兼容的API更改时的主要版本
    MINOR, 当您以向后兼容的方式添加功能时
    PATCH, 向后兼容的bug修复程序时的PATCH版本。

一、chart的文件结构

https://helm.sh/docs/topics/charts/

官方提供的完整的结构。

wordpress/
  Chart.yaml          # A YAML file containing information about the chart
  LICENSE             # OPTIONAL: A plain text file containing the license for the chart
  README.md           # OPTIONAL: A human-readable README file
  values.yaml         # The default configuration values for this chart
  values.schema.json  # OPTIONAL: A JSON Schema for imposing a structure on the values.yaml file
  charts/             # A directory containing any charts upon which this chart depends.
  crds/               # Custom Resource Definitions
  templates/          # A directory of templates that, when combined with values,
                      # will generate valid Kubernetes manifest files.
  templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes

这里 可选 的意思是不影响chart的功能。 没有可选字样的文件如果不需要也可以不写。

文件描述
Chart.yamlChart信息,如:名称,版本。
LICENSE(可选) chart的许可证信息。
README.me(可选) 提供描述信息的。
values.yamlchart的默认配置
values.schema.json(可选) 使用JSON Schema 校验变量格式
charts放一些chart所依赖的chart, 是一个完整的charts,如: charts/redis/{Chart.yaml,templates,values.yaml,charts}
crds自定义资源,没有用过
templates存放模板文件
templates/NOTES.txt简短的使用说明,在安装完chart以后会显示

Chart.yaml内容

Chart.yaml是chart所必需的,包含以下字段:

apiVersion: The chart API version (required)
name: The name of the chart (required)
version: A SemVer 2 version (required)
kubeVersion: A SemVer range of compatible Kubernetes versions (optional)
description: A single-sentence description of this project (optional)
type: It is the type of chart (optional)
keywords:
  - A list of keywords about this project (optional)
home: The URL of this project's home page (optional)
sources:
  - A list of URLs to source code for this project (optional)
dependencies: # A list of the chart requirements (optional)
  - name: The name of the chart (nginx)
    version: The version of the chart ("1.2.3")
    repository: The repository URL ("https://example.com/charts") or alias ("@repo-name")
    condition: (optional) A yaml path that resolves to a boolean, used for enabling/disabling charts (e.g. subchart1.enabled )
    tags: # (optional)
      - Tags can be used to group charts for enabling/disabling together
    enabled: (optional) Enabled bool determines if chart should be loaded
    import-values: # (optional)
      - ImportValues holds the mapping of source values to parent key to be imported. Each item can be a string or pair of child/parent sublist items.
    alias: (optional) Alias usable alias to be used for the chart. Useful when you have to add the same chart multiple times
maintainers: # (optional)
  - name: The maintainer's name (required for each maintainer)
    email: The maintainer's email (optional for each maintainer)
    url: A URL for the maintainer (optional for each maintainer)
icon: A URL to an SVG or PNG image to be used as an icon (optional).
appVersion: The version of the app that this contains (optional). This needn't be SemVer.
deprecated: Whether this chart is deprecated (optional, boolean)
version

必须。 每个chart必须有个版本号,需要遵循SemVer 2格式。
这个版本不是具体软件的版本,如 redis的版本,只是chart自身的版本。helm package命令也会使用这个版本,如:
version: 1.2.3 打包以后, nginx-1.2.3.tgz
nginx-1.2.3 是chart包的名称,并不是nginx的版本。

appVersion

可选。 appVersionversion没有关系, 是用来标识里面具体软件的版本。如 redis 的版本。 只是一个标识,不会对chart有什么影响。

apiVersion

必须。 这个是固定的。 现在有v2, v1两个版本。
helm v3 应该是使用v2, 但是也可以安装v1版本的chart。

kubeVersion

可选。 为受支持的kubernetes版本定义semver约束。
helm在安装chart时验证版本约束,如果发现kubernetes版本不受支持,则安装失败。
定义方式,简单把官方的几个例子列一下,详细的可以参考:
https://github.com/Masterminds/semver

  • >= 1.13.0 < 1.15.0
  • >= 1.13.0 < 1.14.0 || >= 1.14.1 < 1.15.0

支持-连字符

  • 1.1 - 2.3.4 等价于 >= 1.1 <= 2.3.4
  • 2.3.4 - 4.5 等价于 >= 2.3.4 <= 4.5

支持通配符xX*

  • 1.2.x 等价于 >= 1.2.0 < 1.3.0
  • >= 1.2.x 等价于 >= 1.2.0
  • <= 2.x 等价于 < 3
  • * 等价于 >= 0.0.0

支持~, 表示可以大于最后一个小版本, 下面的第一个例子就是最后一个版本可以大于3,但是前两个版本不能大。

  • ~1.2.3等价于>= 1.2.3 < 1.3.0
  • ~1 等价于 >= 1, < 2
  • ~2.3 等价于 >= 2.3, < 2.4
  • ~1.2.x 等价于 >= 1.2.0, < 1.3.0
  • ~1.x 等价于 >= 1, < 2

支持^符号。

  • ^1.2.3 相当于 >= 1.2.3, < 2.0.0
  • ^1.2.x 相当于 >= 1.2.0, < 2.0.0
  • ^2.3 相当于 >= 2.3, < 3
  • ^2.x 相当于 >= 2.0.0, < 3
  • ^0.2.3 相当于 >=0.2.3 <0.3.0
  • ^0.2 相当于 >=0.2.0 <0.3.0
  • ^0.0.3 相当于 >=0.0.3 <0.0.4
  • ^0.0 相当于 >=0.0.0 <0.1.0
  • ^0 相当于 >=0.0.0 <1.0.0
deprecated

可选。 定义chart是否已弃用。 布尔值

type

可选。 定义chart的类型。
有两种类型:applicationlibrary
application 是默认类型, 就是标准的chart。
library 不能安装,可能只是被其他调用的,这个搞不懂。

keywords

可选。 关键字列表, 用来被helm search搜索到的关键字。

dependencies

可选。 定义chart所依赖的chart。如:

dependencies:
  - name: apache
    version: 1.2.3
    repository: https://example.com/charts
  - name: mysql
    version: 3.2.1
    repository: https://another.example.com/charts

依赖这块有点多,具体使用需要查看官方网站:
https://helm.sh/docs/topics/charts/#chart-dependencies

description

可选。 描述信息

home

可选。 对象的url目录。

maintainers

可选。 维护人员的信息。

icon

可选。 url 图标。


例子, mysql的Chart.yaml:

apiVersion: v1
appVersion: 5.7.28
description: Fast, reliable, scalable, and easy to use open-source relational database
  system.
engine: gotpl
home: https://www.mysql.com/
icon: https://www.mysql.com/common/logos/logo-mysql-170x115.png
keywords:
- mysql
- database
- sql
maintainers:
- email: o.with@sportradar.com
  name: olemarkus
- email: viglesias@google.com
  name: viglesiasce
name: mysql
sources:
- https://github.com/kubernetes/charts
- https://github.com/docker-library/mysql
version: 1.6.2

其他文件

README.md:
可选。
采用Markdown(README.md)格式,并且通常应包含:

  • chart提供的应用程序或服务的描述
  • 运行chart的任何先决条件或要求
  • values.yaml中的选项说明和默认值
  • 与chart的安装或配置有关的任何其他信息

templates/NOTES.txt:
可选。
文件内容将在安装完以及查看Release状态的时候显示出来。
文件定义为模板,里面可以使用变量与控制语句。
一般用于显示使用说明与测试步骤之类的。
``
values.yaml:
模板的默认配置文件,定义的各种配置,都可以在模板里当做变量引用。

templates:
存放模板的目录。chart的核心就是模板。

二、模板基础

https://helm.sh/docs/chart_template_guide/
https://helm.sh/docs/topics/charts/#templates-and-values

1、创建一个chart

使用helm create创建chart。

[root@k8s-master3 ~]# helm create mytest
Creating mytest

为了方便熟悉模板的,删除多余文件, 只保留Chart.yaml与templates目录。其他的文件手动创建。

[root@k8s-master3 ~]# tree mytest/
mytest/
├── Chart.yaml
└── templates

1 directory, 1 file

2、熟悉模板

创建一个自定义模板文件

首先在templates目录下生成一个deployment.yaml文件
这个文件名称没有关系,叫做deployment.yaml只是为了方便管理。

[root@k8s-master3 templates]# kubectl create deployment web1 --image=nginx --dry-run -o yaml > deployment.yaml

把文件修改一下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: {{ .Values.name }}
  name: {{ .Values.name }}
spec:
  replicas: {{ .Values.replicas }}
  selector:
    matchLabels:
      app: {{ .Values.name }}
  template:
    metadata:
      labels:
        app: {{ .Values.name }}
    spec:
      containers:
      - image: "{{ .Values.image.name }}:{{ .Values.image.tag }}"
        name: {{ .Values.image.name }}

里面的.Values 就是引用values.yaml文件, 是固定的。
image部分需要加双引号,是因为里面有:, 跟yaml语法有关,跟模板设置没有关系。

创建values.yaml文件

添加values.yaml文件,并设置对应的配置。
values.yaml:

name: web1
replicas: 3
image:
  name: nginx
  tag: 1.16
创建NOTES.txt

这个文件也是模板
NOTES.txt

[root@k8s-master3 templates]# cat NOTES.txt
hello:
install {{ .Values.name }} is successful

现在的文件结构:

[root@k8s-master3 ~]# tree mytest/
mytest/
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   └── NOTES.txt
└── values.yaml

1 directory, 4 files
测试

使用helm lint测试有没有什么问题。

[root@k8s-master3 ~]# helm lint mytest
==> Linting mytest
[INFO] Chart.yaml: icon is recommended

1 chart(s) linted, 0 chart(s) failed

dry-run一下看看结果

[root@k8s-master3 ~]# helm install test1 mytest --dry-run

安装chart

[root@k8s-master3 ~]# helm install test1 mytest
NAME: test1
LAST DEPLOYED: Mon Feb 24 12:05:20 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
hello:
install web1 is successful

里面的NOTES:部分就是NOTES.txt文件里的。

查看:

[root@k8s-master3 ~]# helm list
NAME 	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART       	APP VERSION
test1	default  	1       	2020-02-24 12:05:20.703662828 +0800 CST	deployed	mytest-0.1.0	1.16.0

k8s:

[root@k8s-master3 ~]# kubectl get deployments
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web1   3/3     3            3           2m10s
[root@k8s-master3 ~]# kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
web1-74f74dd6fd-55mz4   1/1     Running   0          2m14s
web1-74f74dd6fd-m47lv   1/1     Running   0          2m14s
web1-74f74dd6fd-vdkf4   1/1     Running   0          2m14s
[root@k8s-master3 ~]# kubectl get deployment/web1 -o yaml | grep image
      - image: nginx:1.16

可以看到deployment的名称,镜像名称与版本, 副本数 都是我们设置的。

3、自定义配置安装chart

上面修改chart里的values.yaml当然可以修改配置了。但是一般安装时不可能把chart下载下来,解压,在修改。
可以通过--set-f, --values修改配置。
--set: 命令行指定配置。 -f, --values: 指定提供配置的文件。

--set:

[root@k8s-master3 ~]# helm install test2 mytest --set replicas=2 --set image.tag=1.17 --set name=web2
NAME: test2
LAST DEPLOYED: Mon Feb 24 13:07:19 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
hello:
install web2 is successful

-f, --values:
创建包含配置的文件,文件名随意:

[root@k8s-master3 ~]# cat conf
name: web3
image:
  tag: 1.15
[root@k8s-master3 ~]# helm install test3 mytest -f conf
NAME: test3
LAST DEPLOYED: Mon Feb 24 13:09:20 2020
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
hello:
install web3 is successful
[root@k8s-master3 ~]# cat conf
name: web3
image:
  tag: 1.15

只是把文件里的值替换或添加到配置中,不是这个文件整个替换values.yaml文件。

3、内置变量

https://helm.sh/docs/chart_template_guide/builtin_objects/
上面的.Values是引用values.yaml文件里的, 还有一些内置的变量。
比如: .Chart.Name,.Chart.Version, Release.Name。

Release

描述Release本身。

变量描述
Release.NameRelease名称
Release.NamespaceRelease命名空间
Release.IsUpgrade如果当前操作是升级或回滚,则为true
Release.IsInstall如果当前操作是安装,则为true
Release.Revision此版本的修订号REVISION。
Release.Service呈现当前模板的服务。在Helm上,这始终是Helm
Chart

Chart.yaml 文件的内容, 里面的任何配置都可以使用。
如:
Chart.Name
Chart.Version
Chart.Type
Chart.AppVersion

Capabilities

提供有关Kubernetes集群支持哪些功能的信息。

变量描述
Capabilities.APIVersions所有api-version
Capabilities.APIVersions.Has $versionapiversion是否可用
Capabilities.KubeVersionCapabilities.KubeVersion.Versionkubernetes的版本
Capabilities.KubeVersion.MajorKubernetes的主要版本
Capabilities.KubeVersion.MinorKubernetes的次要版本
Template

包含正在执行的模板信息

变量描述
Name当前模板的文件路径
BasePathchart的模板目录路径
内置变量的使用

使用方式与.Values一样。
比如,修改deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: {{ .Values.name }}
  name: {{ .Chart.Name }}-{{ .Release.Name }}
spec:
  replicas: {{ .Values.replicas }}
  selector:
    matchLabels:
      app: {{ .Values.name }}
  template:
    metadata:
      labels:
        app: {{ .Values.name }}
    spec:
      containers:
      - image: "{{ .Values.image.name }}:{{ .Chart.AppVersion }}"
        name: {{ .Values.image.name }}

上面的name一般都会使用Chart.Name和.Release.Name的组合。
就不用为了防止deployment资源名称重复,每次都传递name值了。

4、函数与管道

https://helm.sh/docs/chart_template_guide/functions_and_pipelines/

函数

模板函数语法functionName arg1 arg2...
函数是用来对拿到的数据做二次处理。
比如官方的一个示例:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {{ quote .Values.favorite.drink }}
  food: {{ quote .Values.favorite.food }}

其中,quote是函数,后面的是函数的参数。
quote函数用来把值变成字符串,防止接收到数字。

在templates目录下创建configmap.yaml模板并添加需要的配置到values.yaml文件,渲染一下看看结果:

apiVersion: v1
kind: ConfigMap
metadata:
  name: yy-configmap
data:
  myvalue: "Hello World"
  drink: "water"
  food: "332"
管道

管道跟shell的一样,一个 | 竖线。
上面的quote函数也可以通过管道接收参数

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {{ .Values.favorite.drink | quote }}
  food: {{ .Values.favorite.food | quote }}

管道可以多次使用

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"
  drink: {{ .Values.favorite.drink | upper | quote }}
  food: {{ .Values.favorite.food | quote }}

upper 函数用来把小写变成大写。
渲染结果:

apiVersion: v1
kind: ConfigMap
metadata:
  name: tttt-configmap
data:
  myvalue: "Hello World"
  drink: "WATER"
  food: "332"

管道参数的传递,会传给后面函数的最后一个参数。上面都是一个参数的函数, 下面试一下两个参数的函数。

repeat:
有两个参数,第一个是次数, 第二个是字符串。
函数会把给定的字符串重复多次。
比如:

drink: {{ repeat 3 .Values.favorite.drink }}
结果是:
drink: waterwaterwater

用管道就成了这样:

drink: {{ .Values.favorite.drink | repeat 3 | quote | upper }}
其他函数
default

设置默认值。如:

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

如果.Values.favorite.drink没有定义,就返回默认值。
如,把values里的drink注释:

favorite:
  #drink: water
  food: 332

渲染以后:

apiVersion: v1
kind: ConfigMap
metadata:
  name: tttt-configmap
data:
  myvalue: "Hello World"
  drink: tea
  drink: coffee

default的两个参数都可以是变量:

name: `{{ default .Chart.Name .Values.name }}`

如果.Value.name没有定义,则使用.Chart.Name的值。

indent

缩进:{{ .Values.resources | indent 12 }}
一般是用在导入模板里, 因为导入进来的模板缩进不能手动控制。
这里是缩进12个空格。

nindent

indent 只对单行数据做缩进。
nindent 会对每行都做缩进。

toYaml

{{ toYaml .Value.service | nindent 4 }}
toYaml 把配置中的变量原模原样添加到模板中。
因为添加过来的内容会从行首开始,所以要用nindent添加缩进,因为一般添加过来的都是多行内容,所以要用nindent

title

首字母大写:{{ title .Values.resources }}