k8s-helm使用
# 一、概述
Helm (opens new window)是一个用于管理Kubernetes
应用程序的开源工具。它允许您定义、安装和升级Kubernetes
应用程序,以及管理应用程序的相关资源,如部署、服务、配置等。
Helm使用称为"chart"的打包格式来组织和管理Kubernetes应用程序。Chart是一个预定义的目录结构,包含了描述应用程序的配置、依赖关系和部署信息的文件。通过使用Helm,您可以使用现有的Chart来快速部署和管理常见的应用程序,也可以创建自己的Chart来自定义应用程序的部署。
Helm具有强大的模板引擎,允许您在Chart中定义可配置的值,并根据需要生成最终的部署清单。
# 二、安装
安装这里采用二进制模式,更多的安装方式建议参考官方 (opens new window)
# 2.1 下载安装
[root@k8s-master01 ~]# wget https://get.helm.sh/helm-v3.12.0-linux-amd64.tar.gz
[root@k8s-master01 ~]# tar -xf helm-v3.12.0-linux-amd64.tar.gz
[root@k8s-master01 ~]# mv linux-amd64/helm /usr/local/bin/helm
[root@k8s-master01 ~]# helm version
version.BuildInfo{Version:"v3.12.0", GitCommit:"c9f554d75773799f72ceef38c51210f1842a1dea", GitTreeState:"clean", GoVersion:"go1.20.3"}
2
3
4
5
# 2.2 helm架构
- Helm 客户端(Helm Client):Helm 客户端是与用户交互的命令行工具,用于管理和操作 Helm Charts。用户通过 Helm 客户端执行各种 Helm 命令,例如安装、升级和删除应用程序,搜索和管理 Charts,配置和管理 Helm 仓库等。
- Helm Charts:
Helm Charts
是 Helm 的核心概念,它是一个预定义的目录结构,用于打包和组织 Kubernetes 应用程序的相关资源。Chart 包含了应用程序的配置、依赖关系、模板文件以及其他与应用程序部署相关的信息。 - Kubernetes API Server:
Kubernetes API Server
是 Kubernetes 集群的中央控制平面组件,负责处理集群中的 API 请求。Helm 客户端与 Kubernetes API Server 通信,通过 API 创建、更新和删除 Kubernetes 资源。 - 仓库(Repository):仓库是用于存储和分发 Helm Charts 的地方。Helm v3 支持多个仓库,并且您可以添加自定义的仓库。仓库由一个包含 Charts 索引文件的 HTTP(S) 服务器或文件系统提供支持。
- Release: 使用 Helm 安装的一个特定应用程序实例的部署。每个 Release 代表一个独立的应用程序部署,并具有唯一的名称和版本号,每个 Release 都与一个特定的 Chart 相关联,该 Chart 包含了应用程序的配置、依赖关系和相关资源定义。
- Tiller(已弃用):在 Helm v3 及更高版本中,Tiller 已被移除。Tiller 是 Helm v2 中的服务端组件,负责管理 Kubernetes 集群中的部署,以及将用户的 Chart 渲染为 Kubernetes 资源并进行部署。Tiller 与 Kubernetes API Server 交互,并在集群中创建和管理相应的资源。
总结
Helm 安装 charts 到 Kubernetes 集群中,每次安装都会创建一个新的 release。你可以在 Helm 的 chart repositories 中寻找新的 chart
# 三、常用命令
# 3.1 仓库相关
- helm repo add - 添加仓库
helm repo add <repository-name> <repository-url>
- helm repo list - 列举chart仓库
- helm repo remove - 删除一个或多个仓库
helm repo remove <repository-name>
- helm repo update - 更新仓库
- helm search repo - 搜索可用的 Charts
helm search repo <keyword>
# 3.2 安装相关
- 安装应用程序
# release-name 安装指定Release 名称
# chart 指定要安装的包名
helm install <release-name> <chart>
2
3
- 列出Release
helm list
- 获取Release状态
helm status <release-name>
- 升级应用程序
helm upgrade <release-name> <chart>
- 回滚应用程序
helm rollback <release-name> <revision-number>
- 删除应用程序
helm uninstall <release-name>
# 3.3 管理相关
- 创建 Chart
helm create <chart-name>
创建一个新的 Helm Chart,其中 <chart-name>
是您指定的 Chart 的名称,会在当前目录创建一个指定名称的目录树:
- 打包Chat
在指定的
<chart-path>
目录中创建一个 Chart 包(.tgz
格式),用于发布和共享 Chart
helm package <chart-path>
- 校验
验证指定的 Chart 是否符合 Helm 的规范和最佳实践
helm lint <chart-path>
- 调试
在本地模拟部署指定的 Chart,并显示详细的调试信息,但不会实际创建 Release。
helm install --dry-run --debug <release-name> <chart-path>
# 3.4 更多
更多命令参考官方命令行 (opens new window)
# 四、Chart模板
Helm Chart 模板目录是 Chart 的核心部分,它包含了用于生成 Kubernetes 资源清单的模板文件。
# 4.1 目录结构
上面我们通过
helm create nginx
创建过一个名为nginx的模板,接下来我们看下生成目录结构及对应的意义
nginx/
├── charts
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── _helpers.tpl
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── NOTES.txt
│ ├── serviceaccount.yaml
│ ├── service.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
2
3
4
5
6
7
8
9
10
11
12
13
14
# 4.2 目录解释
Chart.yaml:
Chart 的描述信息和元数据,如名称、版本、依赖关系等。values.yaml:
存储和管理 Chart 的默认配置值。values.yaml
文件中定义了一组键值对,用于配置 Chart 中的各种参数和选项。这些配置值可以在templates
下的模板文件中使用,也可以在install
时根据实际需求进行覆盖和定制。**
templates:
**用于生成Kubernetes
资源清单的模板文件的目录。模板文件可以使用 Helm 的模板语言,通过替换变量和执行逻辑来生成最终的资源清单,例如:deployment.yaml
: 用于生成 Deployment 资源的模板文件service.yaml
: 用于生成 Service 资源的模板文件ingress.yaml
:用于生成 Ingress 资源的模板文件_helpers.tpl
:是一个特殊的模板文件,用于定义和包含 Helm Chart 中可重用的模板函数和全局变量。它可以在 Chart 的模板文件中被引用和调用,以提供更高级的模板功能和代码重用。
注意
上面只是我们创建的时候,默认的目录结构,日常使用中,我们可能并不需要这么多资源,因此我们可以把不需要的删除,也可以把所有模板文件都删除,然后自定义模板内容。
Helm的模板是基于Go template编写,因此如果想要深入了解模板,则需要学习一些go template
相关的基础语法。
注: 虽然我们可以删除templates
下所以文件自定义,但是对于整体的目录结构不能改变
# 4.3 模板简单使用
这里参考官方的例子,创建一个
ConfigMap
资源,对模板相关语法进行学习,更多的信息还请移步官方文档 (opens new window)
# 4.3.1 创建默认模板
[root@k8s-master01 ~]# helm create mychart
Creating mychart
# 这里我们并不需要 初始化生成的相关模板资源那文件,因此删除,我们自定义创建
[root@k8s-master01 ~]# rm -rf mychart/templates/*
2
3
4
# 4.3.2 自定义模板
- 模板定义
mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: mychart-configmap
data:
myvalue: "Hello World"
2
3
4
5
6
- 安装
首次使用,我们并没有进行变量引用,单纯看下通过模板创建资源
[root@k8s-master01 ~]# helm install myconfigmap ./mychart/
NAME: myconfigmap
LAST DEPLOYED: Fri Jun 9 17:31:52 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
2
3
4
5
6
7
- 查看资源创建
# 4.4 模板调用
下面我们修改下模板,通过引用变量的方式,进行渲染模板,然后安装应用
- 模板清单定义
mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
2
3
4
5
6
- 安装
[root@k8s-master01 ~]# helm install myconfigmap --debug --dry-run ./mychart/
**--debug
和 --dry-run
**意思是调试运行,而不会真正的应用至集群中,通过下面截图可以看到引用变量已经生效
# 4.5 内置变量
上面
我们并没有在哪里定义,最终也被成功渲染成{{ .Release.Name }}
myconfigmap
,这是因为.Release.Name
属于Helm
的内置对象之一,关于Helm
中内置对象,这里简单列举如下:
# 4.5.1 Release
Release.Name
: 发布的名称Release.Time
: 发布时间Release.Namespace
: 发布的目标命名空间(如果清单没有覆盖)Release.IsUpgrade
: 如果当前操作是升级或回滚的话,该值将被设置为true
Release.IsInstall
: 如果当前操作是安装的话,该值将被设置为true
Release.Revision
: 此次修订的版本号。安装时是1,每次升级或回滚都会自增Release.Service
: 该service用来渲染当前模板。Helm里始终Helm
# 4.5.2 Values
在 Helm Chart 中,values.yaml
文件定义了一组键值对,表示 Chart 的默认配置值。这些默认值可以在模板文件中通过 .Values
来引用和访问。.Values
实际上是一个变量,它提供了对这些配置值的访问入口。
.Values
变量的可用性仅限于 Helm Chart 内部,而不能在模板文件之外的上下文中直接使用。这是因为 .Values
是 Chart 的一部分,它的作用范围仅限于 Chart 的模板文件。
# 4.5.3 Chart
跟Values
类似,不过.Chart
是从Chart.yaml
文件中获取变量值,比如
会打印出 {{ .Chart.Name }}-{{ .Chart.Version }}
mychart-0.1.0
,其中Name
和Version
都是Chart.yaml
中定义的变量值。
# 4.5.4 Files
在Helm中,Files
对象提供了一种在Helm chart
中包含和引用外部文件的方式。该对象允许您包含脚本、配置文件或应用程序所需的任何其他资源文件。
Files.Get
通过文件名获取文件的方法。
# 创建files目录
[root@k8s-master01 ~]# mkdir mychart/files
[root@k8s-master01 ~]# touch mychart/files/config.ini
[root@k8s-master01 ~]# echo "message = this is config" > mychart/templates/files/config.ini
# 编辑configmap示例文件
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
config.ini: |-
{{ .Files.Get "files/config.ini"}}
# 调试查看是否可以获取文件内容
[root@k8s-master01 ~]# helm install myconfigmap --debug --dry-run ./mychart/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Files.GetBytes
用字节数组代替字符串获取文件内容的方法。 对图片之类的文件很有用Files.Glob
用给定的shell glob模式匹配文件名返回文件列表的方法Files.Lines
逐行读取文件内容的方法。迭代文件中每一行时很有用Files.AsSecrets
使用Base 64编码字符串返回文件体的方法Files.AsConfig
使用YAML格式返回文件体的方法
# 4.5.5 Capabilities
Capabilities
是一个内置对象,用于检查和获取当前集群或部署环境的功能和配置信息。这里简单介绍以下几个属性:
Capabilities.APIVersions
:返回集群支持的API版本列表。您可以使用此属性来检查特定API版本是否受当前集群支持。Capabilities.KubeVersion
:返回当前集群的Kubernetes版本。您可以使用此属性来执行特定于版本的操作或检查是否满足最低版本要求。Capabilities.HelmVersion
:返回当前Helm客户端的版本。您可以使用此属性来执行特定于版本的操作或检查是否满足最低版本要求。
示例:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: "Hello World"
config.ini: |-
{{ .Files.Get "files/config.ini"}}
k8sversion: {{ .Capabilities.KubeVersion.Version }}
helmversion: {{ .Capabilities.HelmVersion.Version }}
2
3
4
5
6
7
8
9
10
# 4.6 函数
在Helm中,函数是用于处理和转换数据的工具。函数允许我们在Helm模板中执行各种操作,以便动态生成配置文件。
# 4.6.1 quote函数
该函数简单的理解,就是在字符串加上双引号然后输出
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: {{ quote "Hello World" }}
myvalue2: {{ "Hello World" }}
2
3
4
5
6
7
- 调试输出
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap-configmap
data:
myvalue: "Hello World"
myvalue2: Hello World
2
3
4
5
6
7
8
# 4.6.2 upper
用于将字符串转换为大写形式
- 模板
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: {{ upper "hello world" }}
2
3
4
5
6
- 调试
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap-configmap
data:
myvalue: HELLO WORLD
2
3
4
5
6
7
# 4.6.3 default
常用于在模板中指定一个默认值,以防所需的值未定义或为空。
- 模板
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: {{ ""|default "haha" }}
2
3
4
5
6
- 调试
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap-configmap
data:
myvalue: haha
2
3
4
5
6
7
注意
上面我们可以看到在使用default
函数是,我们借助了一个管道,其实这种方式与放在前面是一样的效果,因为我们经常会多个函数一起使用,因此在平时使用的时候大多都是使用这种管道模式,然后借助多个函数处理字段。
# 4.6.4 indent
字符串前面缩进指定的行数
- 模板
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: {{ "haohao"|indent 2|quote }}
2
3
4
5
6
- 运行
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap-configmap
data:
myvalue: " haohao"
2
3
4
5
6
7
# 4.6.5 更多函数
Helm 有超过60个可用函数。其中有些通过 Go模板语言 (opens new window)本身定义。其他大部分都是 Sprig 模板库 (opens new window)。因此如果懂一些Go语言相关模板语法,对于helm的使用,更加得心应手。
# 4.7 流程控制
Helm 模板提供了一些流程控制指令,使我们能够在模板中执行条件判断和循环操作。以下是 Helm 中常用的流程控制指令:
# 4.7.1 if/else
values.yaml
文件内容
favorite:
food: tea
drink: coffee
like:
- football
- basketball
- volleyball
- doubleball
2
3
4
5
6
7
8
- 模板文件
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: {{ "haohao"|indent 2|quote }}
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
{{ if eq .Values.favorite.drink "coffee" }}
mug: "true"
{{ end }}
2
3
4
5
6
7
8
9
10
11
- 调试渲染
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap-configmap
data:
myvalue: " haohao"
drink: "coffee"
food: "TEA"
mug: "true"
2
3
4
5
6
7
8
9
10
11
特殊符号
上面我们看到渲染后的mug
字段与上面food
字段有一个空格,这看起来有点怪怪的,这是因为当模板引擎运行时,它 移除了
里面的内容,但是留下的空白完全保持原样。想要去除这些空白,我们可以使用特殊符号{{
和 }}
-
,例如:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: {{ "haohao"|indent 2|quote }}
drink: {{ .Values.favorite.drink | default "tea" | quote }}
food: {{ .Values.favorite.food | upper | quote }}
{{- if eq .Values.favorite.drink "coffee" }}
mug: "true"
{{ end }}
# 渲染结果
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap-configmap
data:
myvalue: " haohao"
drink: "coffee"
food: "TEA"
mug: "true"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 4.7.2 range
range
循环语句用于迭代一个集合或列表,并对其中的每个元素执行相应的代码块。
values.yaml
文件内容
favorite
其实可以看做go语言的map类型,like
类似go语言中的切片
favorite:
food: tea
drink: coffee
like:
- football
- basketball
- volleyball
- doubleball
2
3
4
5
6
7
8
- 模板文件
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: {{ "haohao"|indent 2|quote }}
rangeLike: |-
{{- range .Values.like }}
- {{ . | title | quote }}
{{- end }}
{{- range $key,$val := .Values.favorite }}
{{ $key }}: {{ $val}}
{{- end }}
2
3
4
5
6
7
8
9
10
11
12
13
14
特殊字符`|-`
|-
标识在YAML中是指多行字符串。这在清单列表中嵌入大块数据是很有用的技术。
title
,内置函数,指的是将首字母大写
- 模板渲染
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap-configmap
data:
myvalue: " haohao"
rangeLike: |-
- "Football"
- "Basketball"
- "Volleyball"
- "Doubleball"
drink: coffee
food: tea
2
3
4
5
6
7
8
9
10
11
12
13
14
4.7.3 with
with
上下文语句用于将特定的上下文应用于代码块,以便在该上下文中访问特定的值。
values.yaml
文件内容
favorite:
food: tea
drink: coffee
like:
- football
- basketball
- volleyball
- doubleball
2
3
4
5
6
7
8
- 模版文件
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: {{ "haohao"|indent 2|quote }}
{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}
food: {{ .food | upper | quote }}
inName: {{ $.Release.Name }}
{{- end }}
outName: {{ .Release.Name }}
2
3
4
5
6
7
8
9
10
11
12
解释说明
这里其实类似{{- with .Values.favorite }}
if
判断,只要当条件为真时,才会触发下面的执行。
.drink
、.food
,我们看到这里直接使用.
,上面通过with
把.
作用域已经映射为.Values.favorite
,这就是with
的作用。
$
,表示从父作用域访问.Release.Name
变量的值,这是因为在with
的作用域内,.
已经被映射为.Values.favorite
了,在此作用域内并没有Release.Name
,因此需要借助$
从父作用域获取对应的值,但是当遇到end
后,该作用域被重置了。
- 渲染
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap-configmap
data:
myvalue: " haohao"
drink: "coffee"
food: "TEA"
inName: myconfigmap
outName: myconfigmap
2
3
4
5
6
7
8
9
10
11
# 4.8 变量
在 Helm 中,可以通过定义和使用变量来实现动态的模板生成。变量可以用于存储值,变量不仅可以定义在values.yaml
文件中,我们也可以在模板文件中使用变量简化代码。
- 模板
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: {{ "haohao"|indent 2|quote }}
# 赋值当前模板 全局变量
{{- $relname := .Release.Name -}}
{{- with .Values.favorite }}
drink: {{ .drink | default "tea" | quote }}
food: {{ .food | upper | quote }}
# 使用`$`获取父作用域获取变量
inName: {{ $.Release.Name }}
# 使用自定义 获取全局变量
setName: {{ $relname }}
{{- end }}
# 使用`.`获取变量
outName: {{ .Release.Name }}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- 模版渲染
# Source: mychart/templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap-configmap
data:
myvalue: " haohao"
drink: "coffee"
food: "TEA"
inName: myconfigmap
setName: myconfigmap
outName: myconfigmap
2
3
4
5
6
7
8
9
10
11
12
注意
模板中变量的定义也是遵循其他语言一样的规范,变量存在于不同的作用域,上面的定义在顶部,等于是定义全局变量,因此我们在with
流程中可以使用该变量,如果定义在某一个流程控制中,那么只能在该作用域生效,例如:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-configmap
data:
myvalue: {{ "haohao"|indent 2|quote }}
rangeLike: |-
{{- range .Values.like }}
- {{ . | title | quote }}
{{- end }}
{{- range $key,$val := .Values.favorite }}
{{ $key }}: {{ $val}}
{{- end }}
2
3
4
5
6
7
8
9
10
11
12
13
14
上面$key
,$val
则只能在rang
代码块生效
# 五、总结
以上,为helm
的相关使用,当然如果想真正的学习,还需要自己进行花时间学习练习相关的语法,来验证效果,总提而言,helm
在日常工作中能给基于我们很大的帮助,通过模板应用可配置项,可重用性等优点,优化资源的配置维护。