为什么需要Helm
由于Kubernetes缺少对发布的应用版本管理和控制,使得部署的应用维护和更新等面临诸多的挑战,主要面临以下问题:
- 如何将这些服务作为一个整体管理?
- 这些资源文件如何高效复用
- 不支持应用级别的版本管理
Helm介绍
Helm是一个Kubernetes的包管理工具,就像Linux下的包管理器,如yum/apt等,可以很方便的将之前打包好的yaml文件部署到kubernetes上。
Helm有3个重要概念:
- helm:一个命令行客户端工具,主要用于Kubernetes应用chart的创建、打包、发布和管理
- Chart:应用描述,一系列用于描述k8s资源相关文件的集合。
- Release:基于Chart的部署实体,一个chart被Helm运行后将会生成对应的一个release,将在k8s中创建出真实运行的资源
Helm安装
helm官网
使用helm很简单,你只需要下载一个二进制客户端包即可,会通过kubeconfig配置(通常$HOME/.kube/config)来连接Kubernetes
下载Helm客户端:
wget https://get.helm.sh/helm-v3.2.4-linux-amd64.tar.gz
tar zxf helm-v3.2.4-linux-amd64.tar.gz
mv linux-amd64/helm /usr/bin/
命令
命令 | 描述 |
---|---|
completion | 命令补全,source<(helm completion bash)> |
create | 创建一个chart并指定名字 |
dependency | 管理chart依赖 |
get | 下载一个release,可用子命令:all、hooks、manifest、notes、values |
history | 获取release历史 |
install | 安装一个chart |
list | 列出release |
package | 将chart目录打包到chart并解压到本地 # helm pull stable/mysql --untar |
repo | 添加,列出,移除,更新和索引chart仓库。可用子命令:add、index、list、remove、update |
rollback | 从之前的版本回滚 |
search | 根据关键字搜索chart。可用子命令:hub、repo |
show | 查看chart详细信息。可用子命令:all、chart、readme、values |
status | 显示已命名版本的状态 |
template | 本地呈现模板 |
uninstall | 卸载一个release |
upgrade | 更新一个release |
version | 查看helm客户端版本 |
Helm基本使用
制作chart
创建chart:
helm create mychart
打包chart:
helm package mychart
- Chart.yaml:用于描述这个Chart的基本信息,包括名字、描述信息以及版本等。
- values.yaml:用于存储templates目录中模板文件中用到变量的值
- templates:目录里存放所有yaml模板文件
- charts:目录里存放这个chart依赖的所有子chart
- NOTES.txt:用于介绍Chart帮助信息,helm install部署后展示给用户。例如:如何使用这个Chart、列出缺省的设置等
- _helpers.tpl:放置模板的地方,可以在整个chart中重复使用
# 创建一个chart示例
[root@k8s-master ~]# helm create mychart
[root@k8s-master ~]# cd mychart/
[root@k8s-master mychart]# ls
charts Chart.yaml templates values.yaml
# 自己手动创建一个chart
[root@k8s-master ~]# mkdir charts
[root@k8s-master ~]# mkdir charts/templates
[root@k8s-master ~]# touch charts/values.yaml
[root@k8s-master ~]# vim charts/templates/NOTES.txt
# 随便写一些用作测试即可
部署成功。。。
[root@k8s-master ~]# cp /root/mychart/Chart.yaml
# 删除注释内容,并修改name
[root@k8s-master charts]# vim Chart.yaml
apiVersion: v2
name: chart
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: 1.16.0
# 拷贝两个之前部署的yaml,修改下名称即可
# 查看一下我手动创建的层级目录
[root@k8s-master charts]# tree
.
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── NOTES.txt
│ └── services.yaml
└── values.yaml
# 使用helm部署
[root@k8s-master charts]# helm install web-chart /root/charts/
NAME: web-chart
LAST DEPLOYED: Sun Mar 13 19:44:46 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
部署成功。。。
# 查看部署结果
[root@k8s-master pv]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
web-chart default 1 2022-03-13 19:44:46.901207389 +0800 CST deployed chart-0.1.0 1.16.0
[ root@k8s-master charts]# kubectl get pods
web-helm-7cfc9bf95c-7wtc4 1/1 Running 0 6m29s
web-helm-7cfc9bf95c-blm27 1/1 Running 0 6m29s
web-helm-7cfc9bf95c-jj5wg 1/1 Running 0 6m29s
[root@k8s-master charts]# kubectl get svc
web-helm NodePort 10.97.52.28 <none> 80:30097/TCP 6m50s
但是在这个案例中没有体现出helm的特性出来,只是类似于kubectl apply -f的作用,接下来通过案例来了解helm的特性
Helm的核心是模板,即模板化K8s YAML文件。部署多个应用时,将需要改动的字段进行模板化,可动态传入。
下面就不通过实际部署,来测试一下如何使用Helm的特性
# 上面的案例可以看到我在/root下创建了如下结构的目录
[root@k8s-master charts]# tree
.
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── NOTES.txt
│ └── services.yaml
└── values.yaml
# 我需要去修改templates目录下的yaml文件,需要将yaml文件中每次部署需要修改的地方设置为变量,和去在values.yaml设置的值去做匹配
[root@k8s-master templates]# pwd
/root/charts/templates
# 修改deployment.yaml文件
[root@k8s-master templates]# vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: {{ .Release.Name }}
# 在helminstall时会输入一个名称,该参数标识表示传入的就是这个名称
name: {{ .Release.Name }}
spec:
# 在上级目录中的values.yaml文件中有做定义
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
containers:
# 多层定义,在上级目录中的values.yaml文件中定义了image.repository等参数
- image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
name: {{ .Values.image.name }}
-----------------------------------------------------------------------------------------
# 修改services.yaml
[root@k8s-master templates]# vim services.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: {{ .Release.Name }}
name: {{ .Release.Name }}
spec:
ports:
- name: http
port: {{ .Values.server.ports }}
protocol: TCP
targetPort: {{ .Values.server.targetPort }}
selector:
app: {{ .Release.Name }}
type: {{ .Values.server.type }}
---------------------------------------------------------------------------------------
# 在values.yaml中设置变量
[root@k8s-master templates]# vim ../values.yaml
replicaCount: 3
image:
repository: "nginx"
tag: "1.18"
name: "nginx-web"
server:
ports: "80"
targetPort: "80"
type: "NodePort"
# 查看部署结果,不实际运行,可以看到我设置的参数以变量的形式传入了其中,而"web2"就是参数{{ .Release.Name }}传入的变量
[root@k8s-master templates]# helm install web2 /root/charts/ --dry-run
NAME: web2
LAST DEPLOYED: Wed Mar 16 11:39:29 2022
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: chart/templates/services.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: web2
name: web2
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: web2
type: NodePort
---
# Source: chart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web2
# 在helminstall时会输入一个名称,该参数标识表示传入的就是这个名称
name: web2
spec:
# 在上级目录中的values.yaml文件中有做定义
replicas: 3
selector:
matchLabels:
app: web2
template:
metadata:
labels:
app: web2
spec:
containers:
# 多层定义,在上级目录中的values.yaml文件中定义了image.repository等参数
- image: nginx:1.18
name: nginx-web
NOTES:
部署成功。。。
# 部署副本
[root@k8s-master templates]# helm install web2 /root/charts/
# 查看状态
[root@k8s-master templates]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
web2 default 1 2022-03-16 11:45:59.227499938 +0800 CST deployed chart-0.1.0 1.16.0
通过另一种方式进行部署
# 打包
[root@k8s-master templates]# helm package /root/charts/
Successfully packaged chart and saved it to: /root/charts/templates/chart-0.1.0.tgz
# 通过tgz包部署
[root@k8s-master templates]# helm install web2 /root/charts/templates/chart-0.1.0.tgz
一般都时通过tgz的方式进行部署,但是这样子就不再好修改内些变量
为了实现Chart复用,可动态传参修改values.yaml中的变量值,有以下两种方式:
- –values, -f
- –set
例如将升级应用版本:
helm upgrade --set imageTag=1.19 web chart
# 验证--valyes,-f方式
# 随便创建一个yaml文件
[root@k8s-master charts]# vim updata.yaml
# 写入需要更新的参数,格式与chart的values.yaml一致
image:
tag: "1.19"
# 通过该yaml修改参数,可以看到,我们将nginx的镜像版本换为了1.19
[root@k8s-master charts]# helm install web3 -f updata.yaml /root/charts/templates/chart-0.1.0.tgz --dry-run
NAME: web3
LAST DEPLOYED: Wed Mar 16 12:05:16 2022
NAMESPACE: default
STATUS: pending-install
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: chart/templates/services.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: web3
name: web3
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: web3
type: NodePort
---
# Source: chart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web3
# 在helminstall时会输入一个名称,该参数标识表示传入的就是这个名称
name: web3
spec:
# 在上级目录中的values.yaml文件中有做定义
replicas: 3
selector:
matchLabels:
app: web3
template:
metadata:
labels:
app: web3
spec:
containers:
# 多层定义,在上级目录中的values.yaml文件中定义了image.repository等参数
- image: nginx:1.19
name: nginx-web
NOTES:
部署成功。。。
# 验证--set方式
[root@k8s-master templates]# helm install web2 --set image.tag="1.16" /root/charts/templates/chart-0.1.0.tgz --dry-run
NAME: web3
LAST DEPLOYED: Wed Mar 16 13:20:28 2022
NAMESPACE: default
STATUS: pending-install
# 版本号为1
REVISION: 1
TEST SUITE: None
HOOKS:
MANIFEST:
---
# Source: chart/templates/services.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: web3
name: web3
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: web3
type: NodePort
---
# Source: chart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web3
# 在helminstall时会输入一个名称,该参数标识表示传入的就是这个名称
name: web3
spec:
# 在上级目录中的values.yaml文件中有做定义
replicas: 3
selector:
matchLabels:
app: web3
template:
metadata:
labels:
app: web3
spec:
containers:
# 多层定义,在上级目录中的values.yaml文件中定义了image.repository等参数
- image: nginx:1.16
name: nginx-web
NOTES:
部署成功。。。
更新
# 更新web2
[root@k8s-master templates]# helm upgrade web2 --set image.tag="1.16" /root/charts/templates/chart-0.1.0.tgz
Release "web2" has been upgraded. Happy Helming!
NAME: web2
LAST DEPLOYED: Wed Mar 16 13:31:05 2022
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
部署成功。。。
# 查看历史版本,用这个可以方便回滚
[root@k8s-master templates]# helm history web2
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Wed Mar 16 11:45:59 2022 superseded chart-0.1.0 1.16.0 Install complete
2 Wed Mar 16 13:31:05 2022 deployed chart-0.1.0 1.16.0 Upgrade complete
# 回滚版本
[root@k8s-master templates]# helm rollback web2
Rollback was a success! Happy Helming!
# 回滚到指定版本
[root@k8s-master templates]# helm rollback web2 2
Rollback was a success! Happy Helming!
# 卸载版本
[root@k8s-master templates]# helm uninstall web2
release "web2" uninstalled