K8s当中部署应用都是特定的资源组成的,这些资源可以独立于某个文件或者写到一个文件当中
由于Kubernetes缺少对发布的应用版本管理和控制,使得部署的应用维护和更新等面临诸多的挑战,主要面临以下问题:
• 如何将这些服务作为一个整体管理?
• 这些资源文件如何高效复用?
• 不支持应用级别的版本管理
上面这种部署方式适用于服务比较少,数量比较少,不是很复杂的应用。
K8s缺少对应用级别的管理和控制,现在做任何事情都是基于单个yml,比如修改service就打开一个文件对里面的内容进行修改。修改deployment也一样。
我们要怎么统一的管理,配置,更新这些分散的yml文件,例如怎么一键式的部署应用,上线,升级,回滚,下线。
下面是对deploy的回滚,但是这种命令是针对单个deploy完成的,不支持整个应用的回滚,这里的应用可以理解为这里涉及的所有的yml,回滚只是对deploy回滚,并不会对service等资源回滚。
Helm是一个Kubernetes的包管理工具,就像Linux下的包管理器,如yum/apt等,可以很方便的将之前打包好的yaml文件部署到kubernetes上。(就像一个模板一样,改变不同应用差异化的地方,通过传参的形式,动态的去覆盖它就可以适配多个应用的部署)
Helm有3个重要概念:
• helm:一个命令行客户端工具,主要用于Kubernetes应用chart的创建、打包、发布和管理。
• Chart:应用描述,一系列用于描述 k8s 资源相关文件的集合。(将yml组织起来)
• Release:基于Chart的部署实体,一个 chart 被 Helm 运行后将会生成对应的一个 release,将在k8s中创建出真实运行的资源对象
简而言之的好处是一个应用包可以在多个地方部署,可以部署多个应用就像一个模板一样.,只需要修改有差异的地方就行,通过传参数的形式动态修改。
Helm目前有两个大版本:v2和v3
2019年11月Helm团队发布v3版本,相比v2版本最大变化是将Tiller删除,并大部分代码重构。
v2 写chart使用helm客户端部署,通过GRPC调用连接到tiller这个服务,这个服务又去连接k8s的api,然后完成相关yml的部署(需要配置rbac的权限,主要是在heml这块)
v3 和kubectl命令行一样,直接走的是kubeconfig的配置文件,直接连到apiserver去部署
使用helm很简单,你只需要下载一个二进制客户端包即可,会通过kubeconfig配置(通常$HOME/.kube/config)来连接Kubernetes。
下载Helm客户端:
wget https://get.helm.sh/helm-v3.2.4-linux-amd64.tar.gz
tar zxvf helm-v3.2.4-linux-amd64.tar.gz
mv linux-amd64/helm /usr/bin/
[root@k8s-master ~]# tar xf helm-v3.2.4-linux-amd64.tar.gz
[root@k8s-master ~]# mv linux-amd64/helm /usr/bin/
• helm create 制作Chart
• helm install 部署
• helm upgrade 更新
• helm rollback 回滚
• helm uninstall 卸载
Helm通过chart抽象的概念就将这些yml组织在一起了,包括后面所有的操作都是基于chart去完成的,不再只是单独的文件
创建chart:helm create mychart 会生成chart模板的目录结构,在上面完善修改
打包chart:helm package mychart
• Chart.yaml:用于描述这个 Chart的基本信息,包括名字、描述信息以及版本等。
[root@node1 nginxchart]# cat Chart.yaml
apiVersion: v2
name: nginxchart
description: A Helm chart for Kubernetes
type: application
version: 0.1.0
appVersion: 1.16.0
• values.yaml :用于存储 templates 目录中模板文件中用到变量的值。(变量文件)
• charts:目录里存放这个chart依赖的所有子chart。
Templates: 目录里面存放所有yaml模板文件。
• NOTES.txt :用于介绍Chart帮助信息, helm install 部署后展示给用户。
例如:如何使用这个 Chart、列出缺省的设置等。
• _helpers.tpl:放置模板的地方,可以在整个 chart 中重复使用。
[root@k8s-master ~]# helm create mychart
Creating mychart
[root@k8s-master mychart]# ls
charts Chart.yaml templates values.yaml
这是默认的几个目录
部署应用
[root@k8s-master ~]# helm install web mychart/
NAME: web
LAST DEPLOYED: Wed Mar 10 15:22:40 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=web" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:80
这些输出就是这个文件的输出
[root@k8s-master ~]# cat mychart/templates/NOTES.txt
查看发布的状态
[root@k8s-master ~]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
web default 1 2020-12-10 22:50:12.791974185 +0800 CST deployed mychart-0.1.0 1.16.0
应用卸载
[root@k8s-master ~]# helm uninstall web
release "web" uninstalled
[root@k8s-master ~]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
获取详细的信息
[root@k8s-master ~]# helm status web
NAME: web
LAST DEPLOYED: Wed Jan 20 16:04:07 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=web" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:80
• --values,-f:指定YAML文件覆盖值
• --set:在命令行上指定覆盖值
注:如果一起使用,--set优先级高
--values的方式就是要覆盖values.yml里面的内容
这里面只需要写需要覆盖的字段,这个文件可以放在任意目录下,升级需要指定release的名称,这个意思就是将values里面的值覆盖mychat里面values里面的值
-set:在命令行上指定覆盖值
[root@k8s-master ~]# vim values.yml
[root@k8s-master ~]# cat values.yml
image:
repository: nginx
tag: "1.17"
[root@k8s-master ~]# helm upgrade -f values.yml web mychart/
Release "web" has been upgraded. Happy Helming!
NAME: web
LAST DEPLOYED: Thu Jan 21 23:10:15 2021
NAMESPACE: default
STATUS: deployed
REVISION: 2
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=web" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:80
[root@k8s-master ~]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
web default 2 2021-01-21 23:10:15.847583253 +0800 CST deployed mychart-0.1.0 1.16.0
[root@k8s-master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
web-mychart-5b58c47cd6 0 0 0 16m
web-mychart-84d9764bd5 1 1 1 6m31s
这里看到是2,因为每次升级都会加1,这里就相当于发布版本号,可以针对其版本号去回滚
上面是对镜像的升级,其他参数的升级也是一样,可以看到升级成功
这就是通过-f指定一个文件去覆盖里面已有的变量的值从而做到升级
--values,-f:指定YAML文件覆盖值
第二种方式是在命令行指定--set对版本去进行升级,这个要参照values的值去写,而不是乱写,可以看到是有层级关系,层级关系使用的话就是使用set以点的方式去引用
[root@k8s-master mychart]# cat values.yaml
image:
repository: nginx
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
image.repository去改镜像名称
Image.tag 修改版本
[root@k8s-master ~]# helm upgrade --set image.tag=1.18 web mychart/
Release "web" has been upgraded. Happy Helming!
NAME: web
LAST DEPLOYED: Thu Jan 21 23:30:59 2021
NAMESPACE: default
STATUS: deployed
REVISION: 3
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=web" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:80
上面下来你可以看到:
[root@k8s-master mychart]# ls
charts Chart.yaml templates values.yaml
变量通过两种方式去更新,也就是覆盖,覆盖的目的是可以将部署多个应用差异化的地方,通过变量的方式去配置。
到后面就可以部署多个应用差异化的时候去完成默认值的覆盖,从而实现部署多个应用,其实可以对其里面的任意参数进行升级。
假如你的应用出问题了需要对其回滚,那么可以使用rollback进行回滚
默认就是帮你回滚到了上一个版本
[root@k8s-master ~]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
web default 3 2021-01-21 23:30:59.144427304 +0800 CST deployed mychart-0.1.0 1.16.0
[root@k8s-master ~]# helm rollback web
Rollback was a success! Happy Helming!
[root@k8s-master ~]# helm history web
REVISION UPDATED STATUS CHART APP VERSION DESCRIPTION
1 Wed Jan 20 16:04:07 2021 superseded mychart-0.1.0 1.16.0 Install complete
2 Thu Jan 21 23:10:15 2021 superseded mychart-0.1.0 1.16.0 Upgrade complete
3 Thu Jan 21 23:30:59 2021 superseded mychart-0.1.0 1.16.0 Upgrade complete
4 Thu Jan 21 23:48:25 2021 deployed mychart-0.1.0 1.16.0 Rollback to 2
如果你想要查看之前版本部署的信息
[root@k8s-master ~]# helm get all web --revision 1
指定回滚到指定版本
[root@k8s-master ~]# helm rollback web 1
* 安装`local-static-provisioner`
#下载
git clone https://github.com/kubernetes-sigs/sig-storage-local-static-provisioner.git
cd sig-storage-local-static-provisioner
#修改以下配置
vi helm/provisioner/values.yaml
66 classes:
67 - name: fast-disks
70 hostDir: /data/pgdata
76 volumeMode: Filesystem
81 fsType: xfs
116 image: quay.io/external_storage/local-volume-provisioner:v2.4.0
#安装
helm install localprovi . -n kube-system
#检查pod及pv状态
kubectl get po -n kube-system -l app.kubernetes.io/name=provisioner
NAME READY STATUS RESTARTS AGE
localprovi-provisioner-h4sc4 1/1 Running 0 5h39m
localprovi-provisioner-mkl2t 1/1 Running 0 5h39m
localprovi-provisioner-vf274 1/1 Running 0 5h39m
```
[root@k8s-master ~]# helm install web2 mychart
NAME: web2
LAST DEPLOYED: Fri Jan 22 00:00:49 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=web2" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:80
[root@k8s-master ~]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
web default 4 2021-01-21 23:48:25.024165124 +0800 CST deployed mychart-0.1.0 1.16.0
web2 default 1 2021-01-22 00:00:49.666441668 +0800 CST deployed mychart-0.1.0 1.16.0
这个相当于使用一个镜像启动多个容器一样
[root@k8s-master ~]# helm install web3 --set image.repository=httpd --set image.tag=latest mychart
NAME: web3
LAST DEPLOYED: Fri Jan 22 00:05:22 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=mychart,app.kubernetes.io/instance=web3" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace default port-forward $POD_NAME 8080:80
[root@k8s-master ~]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
web default 4 2021-01-21 23:48:25.024165124 +0800 CST deployed mychart-0.1.0 1.16.0
web2 default 1 2021-01-22 00:00:49.666441668 +0800 CST deployed mychart-0.1.0 1.16.0
web3 default 1 2021-01-22 00:05:22.335360998 +0800 CST deployed mychart-0.1.0 1.16.0
可以看到一个模板部署多个应用,通过变量的方式去覆盖
[root@k8s-master ~]# helm uninstall web
release "web" uninstalled
[root@k8s-master ~]# helm uninstall web2
release "web2" uninstalled
[root@k8s-master ~]# helm uninstall web3
release "web3" uninstalled
[root@k8s-master ~]# helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
当使用helm的时候就会将里面的yml清单与values里面的值做一个整合,整合之后就相当于动态渲染之后的结果,动态差异化的地方写到values里面。