每个成功的软件平台都有一个优秀的打包系统,比如Debian、Ubuntu 的 apt,RedHat、CentOS 的 yum。Helm 则是 Kubernetes上 的包管理器,方便我们更好的管理应用。
一、Helm 的相关知识
1.1 Helm的简介
在没使用 helm 之前,向 kubernetes 部署应用,我们要依次部署 deployment、svc 等,步骤较繁琐。 况且随着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复杂,helm 通过打包的方式,支持发布的版本管理和控制, 很大程度上简化了 Kubernetes 应用的部署和管理。
Helm 本质就是让 K8s 的应用管理(Deployment、Service 等)可配置,可以通过类似于传递环境变量的方式能动态生成。通过动态生成 K8s 资源清单文件(deployment.yaml、service.yaml)。然后调用 Kubectl 自动执行 K8s 资源部署。
Helm 是官方提供的类似于 YUM 的包管理器,是部署环境的流程封装。
Helm 的官方网站 Helm
1.2 Helm 有三个重要的概念
Helm 有三个重要的概念:Chart 、Repository 和 Release
●Chart:Helm 的软件包,采用 TAR 格式。类似于 APT 的 DEB 包或者 YUM 的 RPM 包,其包含了一组定义 Kubernetes 资源相关的 YAML 文件。
●Repository(仓库):Helm 的软件仓库,Repository 本质上是一个 Web 服务器,该服务器保存了一系列的 Chart 软件包以供用户下载,并且提供了一个该 Repository 的 Chart 包的清单文件以供查询。Helm 可以同时管理多个不同的 Repository。
●Release:使用 helm install 命令在 Kubernetes 集群中部署的 Chart 称为 Release。可以理解为 Helm 使用 Chart 包部署的一个应用实例。一个 chart 通常可以在同一个集群中安装多次。每一次安装都会创建一个新的 release。
以 MySQL chart 为例,如果你想在你的集群中运行两个数据库,你可以安装该 chart 两次。每一个数据库都会拥有它自己的 release 和 release name。可以将 release 想象成应用程序发布的版本号。
总结:Helm 安装 charts 到 Kubernetes 集群中,每次安装都会创建一个新的 release。你可以在 Helm 的 chart repositories 中寻找新的 chart。
还有一个在Helm3版本中就被移除的概念:
Tiller: Helm 2.x版本中,Helm采用Client/Server的设计,Tiller就是Helm的Server部分,需要具备集群管理员权限才能安装到K8s集群中运行。Tiller与Helm client进行交互,接收client的请求,再与K8s API Server通信,根据传递的Charts来生成Release。而在最新的Helm 3.x中,据说是为了安全性考虑移除了Tiller。
1.3 Helm3 与 Helm2 的区别
(1)helm2的部署方式与使用
Helm2 是 C/S 架构,主要分为客户端 helm 和服务端 Tiller。在 Helm 2 中,Tiller 是作为一个 Deployment 部署在 kube-system 命名空间中,很多情况下,我们会为 Tiller 准备一个 ServiceAccount ,这个 ServiceAccount 通常拥有集群的所有权限。
用户可以使用本地 Helm 命令,自由地连接到 Tiller 中并通过 Tiller 创建、修改、删除任意命名空间下的任意资源。
(2)Helm3的部署与使用
在 Helm 3 中,Tiller 被移除了。新的 Helm 客户端会像 kubectl 命令一样,读取本地的 kubeconfig 文件,使用我们在 kubeconfig 中预先定义好的权限来进行一系列操作。
二、Helm在k8s集群中的部署
1、安装 helm 到master节点上
//下载二进制 Helm client 安装包
https://github.com/helm/helm/tags
tar -zxvf helm-v3.6.0-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/helm
helm version
添加helm的自动补全功能,方便后续使用:
vim /root/.bashrc
source <(helm completion bash)
2、使用 helm 安装 Chart
###helm添加chat的语法格式:
helm repo add chart仓库名 chart仓库地址
###添加常用的chart仓库############
#一个开源项目的仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
#微软chart仓库,推荐使用,内容基本与官方仓库保持一致
helm repo add stable http://mirror.azure.cn/kubernetes/charts
#阿里chart仓库,应有尽有
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
#官方仓库,国内网络问题,不太推荐应用
helm repo add incubator https://charts.helm.sh/incubator #可不用下载
3、对chart仓库的基本使用
更新和查看 charts 列表
helm repo update
helm repo list
官方仓库可不用更新,下面会删除。
查看某chart仓库的可用chart列表
查看 stable 仓库可用的 charts 列表
helm search repo stable
删除指定的chart仓库
//eg:因为官方仓库使用起来太慢,删除 incubator 仓库
helm repo remove incubator
查看 chart 信息
helm show chart stable/mysql #查看指定 chart 的基本信息
helm show all stable/mysql #获取指定 chart 的所有信息
安装 chart
helm install my-redis bitnami/redis [-n default] #指定 release 的名字为 my-redis,-n 指定部署到 k8s 的 namespace
helm install bitnami/redis --generate-name #不指定 release 的名字时,需使用 –generate-name 随机生成一个名字
搭建动态创建pv 详见:k8s 之存储卷-CSDN博客
对chart的基本管理
查看所有的release
helm ls
helm list
查看指定的 release 状态
helm status my-redis
删除指定的release
helm uninstall my-redis
三、Helm的自定义模板
charts 除了可以在 repo 中下载,还可以自己自定义,创建完成后通过 helm 部署到 k8s。
3.1 在镜像仓库中拉取chart,查看chart的包结构
mkdir /opt/helm
cd /opt/helm#拉取chart 到本地目录(现在所在的目录中)
helm pull stable/mysql
#对该拉取的chart压缩包进行解压
tar xf mysql-1.6.9.tgz
可以看到,一个 chart 包就是一个文件夹的集合,文件夹名称就是 chart 包的名称。
#chart 是包含至少两项内容的helm软件包:
(1)软件包自描述文件 Chart.yaml,这个文件必须有 name 和 version(chart版本) 的定义
(2)一个或多个模板,其中包含 Kubernetes 清单文件:
●NOTES.txt:chart 的“帮助文本”,在用户运行 helm install 时显示给用户
●deployment.yaml:创建 deployment 的资源清单文件
●service.yaml:为 deployment 创建 service 的资源清单文件
●ingress.yaml: 创建 ingress 对象的资源清单文件
●_helpers.tpl:放置模板助手的地方,可以在整个 chart 中重复使用
3.2 自定义创建一个chart
(1)使用命令行创建生成一个模板
helm create nginx
tree nginx
cat nginx/templates/deployment.yaml
在 templates 目录下 yaml 文件模板中的变量(go template语法)的值默认是在 nginx/values.yaml 中定义的,只需要修改 nginx/values.yaml 的内容,也就完成了 templates 目录下 yaml 文件的配置。
比如在 deployment.yaml 中定义的容器镜像:
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
以上变量值是在 create chart 的时候就自动生成的默认值,你可以根据实际情况进行修改。
总结:所以实际操作中,大多数情况下,我们只需要通过操作 Chart.yaml 和 values.yaml 文件进行自定义chart的设置,其他文件均是由变量来获取values.yaml中的值
(2)进行模板文件的修改,生成自定义chart
vim nginx/Chart.yaml
apiVersion: v2
name: nginx #chart名字
description: A Helm chart for Kubernetes
type: application #chart类型,application或library
version: 0.1.0 #chart版本
appVersion: 1.16.0 #application部署版本
vim nginx/values.yaml
replicaCount: 1
image:
repository: nginx
pullPolicy: IfNotPresent
tag: "latest" #设置镜像标签
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
create: true
annotations: {}
name: ""
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
ingress:
enabled: true #开启 ingress
className: ""
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: www.benet.com #指定ingress域名
paths:
- path: /
pathType: Prefix #指定ingress路径类型
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources: #资源限制,注意若要进行限制需要把原来resources:后面的括号删除。
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 100m
memory: 128Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
(3)进行chart打包
//打包 chart
helm lint nginx #检查依赖和模版配置是否正确helm package nginx #打包 chart,会在当前目录下生成压缩包 nginx-0.1.0.tgz
(4)利用自定义 chart 包进行k8s资源部署
helm install nginx ./nginx --dry-run --debug #使用 --dry-run 参数验证 Chart 的配置,并不执行安装
helm install nginx ./nginx -n default #部署 chart,release 版本默认为 1
或者
helm install nginx ./nginx-0.1.0.tgz
#可根据不同的配置来 install,默认是 values.yaml
helm install nginx ./nginx -f ./nginx/values-prod.yaml
同时k8s也部署好了pod和svc资源
(5)部署 ingress
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/mandatory.yaml
wget https://gitee.com/mirrors/ingress-nginx/raw/nginx-0.30.0/deploy/static/provider/baremetal/service-nodeport.yaml
kubectl apply -f mandatory.yaml
kubectl apply -f service-nodeport.yaml
kubectl get pod,svc -n ingress-nginx
kubectl get ingress
进行客户机测试:(随便启用一台k8s集群以外的客户机)
vim /etc/hosts
192.168.80.12 www.benet.com
(6)进行修改变动,进行chart的升级更新
//修改为 NodePort 访问后,升级
vim nginx/values.yaml
service:
type: NodePort #service类型改成NodePort
port: 80
nodePort: 31280 #指定nodePort的端口
ingress:
enabled: false #关闭ingress
vim nginx/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ include "nginx.fullname" . }}
labels:
{{- include "nginx.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
nodePort: {{ .Values.service.nodePort }} #指定 nodePort
selector:
{{- include "nginx.selectorLabels" . | nindent 4 }}
升级 release,release 版本加 1
helm upgrade nginx ./nginx
进行访问测试:
http://www.benet.com:31280
(7)自定义chart的版本回滚 (根据release版本)
helm history nginx #查看 release 版本历史
helm rollback nginx 1 #回滚 release 到版本1
#通常情况下,在配置好 templates 目录下的 kubernetes 清单文件后,后续维护一般只需要修改 Chart.yaml 和 values.yaml 即可。
在命令行使用 --set 指定参数来部署(install,upgrade)release
#注:此参数值会覆盖掉在 values.yaml 中的值,如需了解其它的预定义变量参数,可查看 helm 官方文档。
helm upgrade nginx nginx --set image.tag='1.15' (相当于k8s中打补丁设置的方式)
四、Helm 的私有仓库-Harbor
前面介绍了 Harbor 作为docker镜像的私有仓库,其实Harbor还可以成为Helm的私有仓库,用来存放打包好的chart包
具体部署步骤
(1)在新主机上安装harbor和docker-compose(前提是已经安装好docker)
//安装 harbor
#上传 harbor-offline-installer-v1.9.1.tgz 和 docker-compose 文件到 /opt 目录
官方地址:https://github.com/goharbor/harbor/releases/tag/v1.9.1
若无法下载请科学上网。
cd /opt
cp docker-compose /usr/local/bin/
chmod +x /usr/local/bin/docker-compose
tar zxf harbor-offline-installer-v1.9.1.tgz
cd harbor/
vim harbor.yml
hostname: 192.168.80.16
harbor_admin_password: Harbor12345 #admin用户初始密码
data_volume: /data #数据存储路径,自动创建
chart:
absolute_url: enabled #在chart中启用绝对url
log:
level: info
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harbor #日志路径
#安装带有 Clair service 和 chart 仓库服务的 Harbor
./install.sh --with-clair --with-chartmuseum
(2)在helm主机上安装好push插件
#在线安装
helm plugin install https://github.com/chartmuseum/helm-push
#离线安装
wget https://github.com/chartmuseum/helm-push/releases/download/v0.8.1/helm-push_0.8.1_linux_amd64.tar.gz
mkdir -p ~/.local/share/helm/plugins/helm-push
tar -zxvf helm-push_0.8.1_linux_amd64.tar.gz -C ~/.local/share/helm/plugins/helm-push
helm repo ls
(3)在habor主机创建项目,在helm主机添加chart仓库
打开浏览器:访问http://192.168.80.16,,默认的管理员用户名和密码是 admin/Harbor12345
点击 “+新建项目” 按钮
填写项目名称为 “chart_repo”,访问级别勾选 “公开”,点击 “确定” 按钮,创建新项目
在helm主机上进行操作 :
添加仓库
helm repo add harbor http://192.168.80.16/chartrepo/chart_repo --username=admin --password=Harbor12345
#注:这里的 repo 的地址是<Harbor URL>/chartrepo/<项目名称>,Harbor 中每个项目是分开的 repo。
如果不提供项目名称, 则默认使用 library 这个项目。
(4)进行推送拉取测试
推送chart包测试:
#推送 chart 到 harbor 中
cd /opt/helm
helm push nginx-0.1.0.tgz harbor
拉取chart包测试:
注意:第一次拉取私有仓库chart包时,需要先进行helm repo update 更新helm仓库源
mkdir repo.bak
mv nginx/ ./repo.bak
mv nginx-0.1.0.tgz repo.bak/
#因为harbor仓库是第一次使用,需要先对仓库源进行更新
helm repo update
helm pull harbor/nginx
Helm的命令总结
(1)Helm的常用命令总结
helm #查看helm基本操作命令
helm version #查看helm的版本
helm env #查看环境变量
helm create chartName #创建chart目录(含基本配置文件和目录)
helm package chartDir #将chart目录打包
helm template chartName #渲染template目录下的模板文件(即将这些模板文件的字段内容用values.yaml填充,然后直接输出到终端)
helm search repo keyword #根据关键字检索chart包
helm search hub keyword
#上面2个命令仅仅在第3个字段有区别,repo表示在本地所添加的仓库中进行检索;
hub表示在Helm Hub中进行检索。
helm list #查看发布到k8s中的chart对应的release
helm push chart.tgz repoName 上传chart到chart仓库
例:helm push demo.tgz harbor-10.30.12.211 --username=admin --password=Harbor12345
#有些仓库是有账号密码验证的,所以需要加上账号、密码的参数(比如Harbor提供的chart仓库功能,
可参考下面的私有仓库搭建先搭建一个私有仓库出来,再进行仓库相关命令的测试)
命令:helm pull repoName/keyword #从chart仓库中拉取chart到本地
例:helm pull harbor-10.30.12.211/demo
#harbor-10.30.12.211/demo的结构是本地起的仓库名/chart包的名字前缀,
只要在harbor-10.30.12.211仓库中含有demo为前缀的chart包,就会被下载到本地
helm lint chartName #检查chart包中的文件内容是否正确
(即该chart包去k8s中是否能够成功安装部署)
#包可以是chart目录、chart压缩包
helm install releaseName chartName #将chart包发布到k8s集群中安装部署
#releaseName为release的名字,chartName为chart包名,chart可以是未打包的chart,也可以是打包的
chart,也可以是仓库中的chart。【chart和release的关系可以大致理解为程序和进程的关系,一个是静态
的,一个是动态的】
helm install chartName --generate-name
#可以不指定release的名字,只需要指定–generate-name即可随机生成一个名字
#创建完后可以使用helm list查看是否有对应的release
helm uninstall releaseName #将部署到k8s中的release卸载掉
#卸载完后使用helm list查看relDemo是否被删除了,同时可以使用kubectl get pods查看相应的pod等与
release相关的资源是否全部删除干净
helm upgrade releaseName chartName #将部署到k8s中的release升级,即相当于应用升级
#relName指定一个release,该release对应一个k8s中的应用,chartName指定一个chart包,整个
过程为直接使用指定的chart包替换部署release。就helm而言release还是原来那个,不过对应的
chart包被替换了。对k8s而言,仅仅是将原先资源删除,然后用新的chart包创建资源。
#使用helm list查看release的CHART字段是否更新,同时可以使用kubectl get pods查看相应的
pod等与release相关的资源是否全部更新(看名字、运行时间)
helm rollback releaseName revision #将release回退到前一个或若干个版本(k8s中会同步回退)
#revision为第几个版本,1表示第一个版本,2表示第二个版本,以此类推。通常回滚会搭配
helm history releaseName使用,通过该命令查看所有的关于本release的发布历史,然后
选择回退到哪个版本
#回滚成功后使用helm list查看该release的CHART和APP VERSION是否更新(具体得看chart中的
chart.yaml中的version和appVersion有没有相应的修改),同时可以使用kubectl get pods查看
相应的pod等与release相关的资源是否全部更新(看名字、运行时间)
helm history releaseName #查看release的发布历史(包括安装、升级、回滚)
helm status releaseName #查看release的基本信息
(2)查看chart包的操作命令
helm show chart chartName #查看chart包中的chart.yaml文件内容
#chart包可以是本地的未打包的chart目录(即helm create 创建出来的chart目录),
也可以是打包的chart压缩包(由helm package打包),也可以是保存在仓库中的chart包
helm show values chartName #查看chart包中的values.yaml文件内容
#包同上有3种选择
helm show readme chartName #查看chart包中README文件内容
#包同上有3种选择
helm show all chartName #查看chart包中chart.yaml、values.yaml、README文件内容
#包同上有3种选择
(3)查看release指定内容(与helm show作用、格式相同)
helm get notes releaseName #查看release的说明信息(相当于chart中的NOTES.TXT)
helm get manifest releaseName #查看release在k8s中创建出来的资源
helm get hooks releaseName #查看release的回调创建资源
helm get values releaseName #查看release的values配置
helm get all releaseName #查看上述所有内容
(4)helm plugin —— 插件管理
helm plugin list #查看本地安装好的插件 (插件管理)
helm plugin install pluginURL #安装插件
例:helm plugin install https://github.com/chartmuseum/helm-push
#最后的url地址为插件的下载地址,可参考 https://github.com/chartmuseum/helm-push
helm plugin uninstall pluginName #卸载插件
helm plugin update pluginName #更新插件,将插件升级到最新版本
#在下载插件的时候会保存插件及其下载地址,更新的时候使用原本的下载地址直接下载最新版本替换
(5)helm repo —— 仓库管理
helm repo list #(仓库管理)查看添加的chart仓库,可在这些chart仓库中拉取chart
(实际上就相当于一个应用的安装包)
helm repo add repoName repoURL #本地添加chart仓库
例:helm repo add abc http://mirror.azure.cn/kubernetes/charts/
#repoName是你自己起的一个名字,用来代表这个repoURL,后续操作仓库的命令中直接用repoName来代替
repoURL,只要指定了repoName,就表示要去操作repoName指向的repoURL的仓库
helm repo remove repoName #本地删除chart仓库
helm repo update #将本地所添加的chart仓库的最新信息缓存到本地
#helm search命令是检索某仓库中的chart包,假设仓库中一开始是没有所指定的chart包,
所以helm search是检索不到的。这时候如果将chart包上传至该仓库,本地需要执行一遍
helm repo update以更新本地的缓存数据才能检索到该指定的chart,因为helm search就是
读取本地缓存数据的
helm repo index repoDir --url=repoURL #根据指定仓库目录下的chart包生成index.yaml索引文件
例:helm repo index repo --url=http://192.168.73.108:8080/
#repoDir指定一个仓库的目录,该目录用来存放chart包及索引文件index.yaml。url指定仓库的访问路径,
生成的索引文件中会以该url为地址前缀拼接上chart包名作为chart包的访问路径