K8s当中部署应用都是特定的资源组成的,这些资源可以独立于某个文件或者写到一个文件当中

为什么需要Helm


由于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介绍


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客户端


Helm管理应用生命周期


• helm create 制作Chart

• helm install 部署

• helm upgrade 更新

• helm rollback 回滚

• helm uninstall 卸载

Helm通过chart抽象的概念就将这些yml组织在一起了,包括后面所有的操作都是基于chart去完成的,不再只是单独的文件

Helm基本使用:制作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

使用Chart升级应用有两种方法


• --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

上面下来你可以看到:

  • Helm命令行是对相关应用的部署的操作,操作对象就是我们创建的chart包,不管是安装还是升级都要带着chart包,这是helm和chart的关系
  • Chart包里面是有其目录组织的关系,在目录里面通过类似于变量引用的方式
  • 内置的机制就是通过变量引用渲染这个模板,渲染之后在k8s去运行
[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


* 安装`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
  ```

Chart模板的复用


[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里面。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐