一、介绍
Helm 是一个 Kubernetes 应用的包管理工具,用来管理 chart——预先配置好的安装包资源,有点类似于 Ubuntu 的 APT 和 CentOS 中的 YUM。2019 年 11 月 13 日,Helm 3 发布,2020 年 4 月 30 日,从 CNCF 中毕业。本文基于 Helm 3。
Helm chart 是用来封装 Kubernetes 原生应用程序的 YAML 文件,可以在你部署应用的时候自定义应用程序的一些 metadata,便与应用程序的分发。
二、安装
1)、下载需要的版本:https://github.com/helm/helm/releases
2)、解压:tar -zxvf helm-v3.15.2-linux-arm64.tar.gz
3)、在解压目中找到helm程序,移动到需要的目录中
mv linux-amd64/helm /usr/local/bin/helm
三、概念和Chart文档结构
3.1、Chart目录结构
chart是一个组织在文件目录中的集合。目录名称就是chart名称(没有版本信息)
mychart
├── Chart.yaml
├── charts # 该目录保存其他依赖的 chart(子 chart)
├── templates # chart 配置模板,用于渲染最终的 Kubernetes YAML 文件
│ ├── NOTES.txt # 用户运行 helm install 时候的提示信息
│ ├── _helpers.tpl # 用于创建模板时的帮助类
│ ├── deployment.yaml # Kubernetes deployment 配置
│ ├── ingress.yaml # Kubernetes ingress 配置
│ ├── service.yaml # Kubernetes service 配置
│ ├── serviceaccount.yaml # Kubernetes serviceaccount 配置
│ └── tests
│ └── test-connection.yaml
└── values.yaml # 定义 chart 模板中的自定义配置的默认值,可以在执行 helm install 或 helm update 的时候覆盖
templates/ 目录包括了模板文件。当Helm评估chart时,会通过模板渲染引擎将所有文件发送到templates/
目录中。 然后收集模板的结果并发送给Kubernetes。
value.yaml 这个文件包含了chart的 默认值 。这些值会在用户执行helm install
或 helm upgrade
时被覆盖。
Chart.yaml 文件包含了该chart的描述。你可以从模板中访问它。charts/
目录 可以 包含其他的chart(称之为 子chart)
3.2、创建第一个chart
使用命令helm create 创建一个chart
[root@master ~]# helm create mychart
[root@master ~]# tree mychart/
mychart/
├── charts
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── _helpers.tpl #放置可以通过chart复用的模板辅助对象
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── NOTES.txt
│ ├── serviceaccount.yaml
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
删除templates文件方便后面学习测试用
rm -rf mychart/templates/*
创建一个名为 mychart/templates/configmap.yaml的文件:
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"
测试chart运行
[root@master ~]# helm install --dry-run goodly-guppy ./mychart
NAME: goodly-guppy
LAST DEPLOYED: Tue Jul 2 17:21:53 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"
在configmap.yaml中添加一个引用然后运行
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
[root@master ~]# helm install --dry-run goodly-guppy ./mychart
NAME: goodly-guppy
LAST DEPLOYED: Tue Jul 2 17:23:43 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: goodly-guppy-configmap
data:
myvalue: "Hello World"
{{ .Release.Name }}
将发布名称注入了模板,Release
是一个Helm的内置对象
Release
前面的点表示从作用域最顶层的命名空间开始,.Release.Name
就可解读为“通顶层命名空间开始查找 Release对象,然后在其中找Name对象”。
通过上面的实验我们可以看到最基本的模板:YAML文件有嵌入在{{
和 }}
之间的模板命令
命令helm install --debug --dry-run goodly-guppy,可以测试模板渲染的内容,在不想安装任何实际应用时,可以使用这样不会安装应用(chart)到你的kubenetes集群中,只会渲染模板内容到控制台(用于测试)。
四、内置对象
4.1、Release
在上面我们用{{ .Release.Name }}
在模板中插入版本名称。
Release是模板的顶层对象之一,Release对象描述了版本发布本身。它包含以下对象:
Release.Name: release名称
Release.Namespace:版本中包含的命名空间
Release.IsUpgrade:当前操作是升级或回滚的话,该值为true,否则为false
Release.IsIntall:如果当前操作是安装,该值为true,否则为false
Release.Revision:此次修订的版本号,安装时是1,每次升级或者回滚都会自动加1
Release.Service:该service用来渲染当前模板。Helm里始终是Helm
测试如下:
[root@master ~]# vim mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
name: {{ .Release.Name }}
Namespace: {{ .Release.Namespace }}
IsUpgrade: {{ .Release.IsUpgrade }}
IsInstall: {{ .Release.IsInstall }}
Revision: {{ .Release.Revision }}
Service: {{ .Release.Service }}
[root@master ~]# helm install --dry-run goodly-guppy ./mychart
NAME: goodly-guppy
LAST DEPLOYED: Tue Jul 2 17:47:50 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: goodly-guppy-configmap
data:
name: goodly-guppy #实例名
Namespace: default #安装的命名空间
IsUpgrade: false #此次操作不是升级或者回滚
IsInstall: true #此次是安装
Revision: 1 #第一个版本
Service: Helm #始终为Helm
4.2、Value对象
Values
对象是从values.yaml
文件和用户提供的文件传进模板的。默认为空
取值方式
name1:test1 #获取方式 .Values.name1
info:
name2: test2 #获取方式 .Values.info.name2
[root@master mychart]# vim values.yaml
name1: test1
info:
name2: test2
[root@master ~]# vim mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
name1: {{ .Values.name1 }}
name2: {{ .Values.info.name2 }}
~
[root@master ~]# helm install --dry-run goodly-guppy ./mychart
NAME: goodly-guppy
LAST DEPLOYED: Tue Jul 2 21:19:34 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: goodly-guppy-configmap
data:
name1: test1
name2: test2
4.3、Chart对象
Chart.yaml
文件内容。 Chart.yaml
里的所有数据在这里都可以可访问的。比如 {{ .Chart.Name }}-{{ .Chart.Version }}
.Chart.Name 获取Chart的名称
.Chart.Version 获取Chart的版本
[root@master ~]# helm install --dry-run goodly-guppy ./mychart
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
ChartName: {{ .Chart.Name }}
ChartVersion: {{ .Chart.Version }}
[root@master ~]# helm install --dry-run goodly-guppy ./mychart
NAME: goodly-guppy
LAST DEPLOYED: Tue Jul 2 21:31:07 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: goodly-guppy-configmap
data:
ChartName: mychart
ChartVersion: 0.1.0
4.4、Files对象
File对象:在chart中提供访问所有的非特殊文件的对象。你不能使用它访问Template
对象,只能访问其他文件
Files.Get
:通过文件名获取文件内容的方法
Files.GetBytes:用二进制字节数组代替字符串获取文件内容的方法。 对图片之类的文件很有用
Files.Glob:返回符合给定shell glob pattern的文件数组,例: {{ .Files.Glob "*.yaml" }}
Files.Lines
:逐行读取文件内容的方法。迭代文件中每一行时很有用
Files.AsSecrets:使用Base 64编码字符串返回文件体的方法
Files.AsConfig:使用YAML格式返回文件体的方法
[root@master ~]# vim mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
{{- $files := .Files }}
{{- range tuple "config1.yaml" "config2.yaml" "config3.yaml" }}
{{ . }}: |-
{{ $files.Get . }}
{{- end}}
[root@master ~]# helm install --dry-run goodly-guppy ./mychart
NAME: goodly-guppy
LAST DEPLOYED: Tue Jul 2 21:46:57 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: goodly-guppy-configmap
data:
config1.yaml: |-
message = Hello from config1
config2.yaml: |-
message = This is config2
config3.yaml: |-
message = This is config3
我们创建了一个 $files
变量来引用 .Files
对象。 然后我们打印每个文件的名字( {{ . }}: |-
),通过 {{ $files.Get . }}
打印文件内容。
4.5、Capabilities对象
提供关于Kubernetes集群支持功能的信息
Capabilities.APIVersions:
返回kubernetes 集群API版本信息集合
Capabilities.APIVersions.Has $version:说明集群中的版本 (比如,batch/v1
) 或是资源 (比如, apps/v1/Deployment
) 是否可用
Capabilities.KubeVersion
和Capabilities.KubeVersion.Version:
是Kubernetes的版本号
Capabilities.KubeVersion.Major:Kubernetes的主版本
Capabilities.KubeVersion.Minor:Kubernetes的次版本
Capabilities.HelmVersion:包含Helm版本详细信息的对象,和 helm version
的输出一致
Capabilities.HelmVersion.Version:是当前Helm语义格式的版本
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
APIVersion: {{ .Capabilities.APIVersions }}
KubeVersion: {{ .Capabilities.KubeVersion }}
Major: {{ .Capabilities.KubeVersion.Major }}
Minor: {{ .Capabilities.KubeVersion.Minor }}
4.6、Template对象
包含当前被执行的当前模板信息
Template.Name
: 当前模板的命名空间文件路径 (e.g. mychart/templates/mytemplate.yaml
)
Template.BasePath
: 当前chart模板目录的路径 (e.g. mychart/templates
)
[root@master ~]# vim mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
TempName: {{ .Template.Name }}
TempBasePath: {{ .Template.BasePath }}
[root@master ~]# helm install --dry-run goodly-guppy ./mychart
NAME: goodly-guppy
LAST DEPLOYED: Wed Jul 3 14:54:57 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: goodly-guppy-configmap
data:
TempName: mychart/templates/configmap.yaml
TempBasePath: mychart/templates
五、Values文件
5.1、values值来源
上一部分了解了Helm模板提供的内置对象。其中一个是Values
对象。该对象提供了传递值到chart的方法。
其内容来自对个位置:
- chart中的
values.yaml
文件 - 如果是子chart,就是父chart中的
values.yaml
文件 - 使用
-f
参数(helm install -f myvals.yaml ./mychart
)传递到helm install
或helm upgrade
的values文件 - 使用
--set
(比如helm install --set foo=bar ./mychart
)传递的单个参数
顺序:默认使用values.yaml
,可以被父chart的values.yaml
覆盖,继而被用户提供values文件覆盖, 最后会被--set
参数覆盖,优先级为values.yaml
最低,--set
参数最高。
values文件是普通的YAML文件。现在编辑mychart/values.yaml
然后编辑配置映射ConfigMap模板。
[root@master ~]# vim mychart/values.yaml
name1: test1
在模板中使用它
[root@master ~]# helm install --dry-run goodly-guppy ./mychart --debug
install.go:222: [debug] Original chart version: ""
install.go:239: [debug] CHART PATH: /root/mychart
NAME: goodly-guppy
LAST DEPLOYED: Wed Jul 3 15:07:01 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
USER-SUPPLIED VALUES:
{}
COMPUTED VALUES:
name1: test1
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: goodly-guppy-configmap
data:
name: test1
可以在调用helm install
时设置--set
,很容易就能覆盖这个值。
[root@master ~]# helm install --dry-run goodly-guppy ./mychart --set name1=test2
NAME: goodly-guppy
LAST DEPLOYED: Wed Jul 3 15:08:12 2024
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: goodly-guppy-configmap
data:
name: test2
由于--set
比默认的values.yaml
文件优先级更高,模板就生成了 name: test2
5.2、删除默认的key
如果需要从默认的value中删除key,可以将key设置为null
,Helm将在覆盖的value合并时删除这个key。
比如,稳定的Drupal允许在配置自定义镜像时配置活动探针。默认值为httpget
:
livenessProbe:
httpGet:
path: /user/login
port: http
initialDelaySeconds: 120
替换掉httpGet
用exec
重写活动探针,使用--set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt]
Helm会把默认的key和重写的key合并在一起,从而生成以下YAML:
livenessProbe:
httpGet:
path: /user/login
port: http
exec:
command:
- cat
- docroot/CHANGELOG.txt
initialDelaySeconds: 120
为了解决这个问题,Helm可以指定通过设定null来删除livenessProbe.httpGet
helm install stable/drupal --set image=my-registry/drupal:0.1.0 --set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt] --set livenessProbe.httpGet=null