Kubernetes的包管理器—Helm

家资是何物,积帙列梁梠。这篇文章主要讲述Kubernetes的包管理器—Helm相关的知识,希望能为你提供帮助。
Kubernetes的包管理器---Helm Helm的概念在没使用helm之前,向kubernetes部署应用,我们要依次部署deployment、svc等,步骤较繁琐。
况且随着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复杂,helm通过打包的方式,支持发布的版本管理和控制,很大程度上简化了Kubernetes应用的部署和管理。
【Kubernetes的包管理器—Helm】Helm本质就是让K8s的应用管理(Deployment、Service等)可配置,可以通过类似于传递环境变量的大式能动态生成。通过动态生成KBs资源清单文件(deployment.yaml、service.yaml)。然后调用Kubectl自动执行K8s资源部署。
Helm是官方提供的类似于YUM的包管理器,是部署环境的流程封装。Helm有两个重要的概念:Chart、 Repository和Release

  • Chart:Helm的软件包,采用TAR格式。类似于APT的DEB包或者YUM的RRM包,其包含了一组定义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和releasename。可以将release想象成应用程序发布的版本号。
总结:Helm安装charts到Kubernetes集群中,每次安装都会创建一个新的release。你可以在Helm的chart repositories中寻找新的chart。
Kubernetes的包管理器—Helm

文章图片

Helm3与Helm2的区别:Helm2是C/S架构,主要分为客户端 helm和服务端Tiller。在Helm2中,Tiller是作为一个Deployment部署在kube-system命名空间中,很多情况下,我们会为Tiller 准备一个ServiceAccount,这个ServiceAccount通常拥有集群的所有权限。
用户可以使用本地Helm命令,自由地连接到Tiller中并通过Tiller创建、修改、删除任意命名空间下的任意资源。
在Helm 3中,Tiller被移除了。新的Helm客户端会像kubectl命令一样,读取本地的kubeconfig文件,使用我们在kubeconfig中预先定义好的权限来进行一系列操作。
==Helm的官方网站==:https://helm.sh/
==Helm软件包官方网站==:https://helm.sh/zh/docs/topics/version_skew/
Helm部署1、安装helm
#下载二进制 Helm client 安装包 https://github.com/helm/helm/tagstar -zxvf helm-v3.6.0-linux-amd64.tar.gz mv linux-amd64/helm /usr/local/bin/helm helm version#命令补全 source < (helm completion bash)

2、使用helm安装Chart
#添加常用的 chart 仓库, helm repo add bitnami https://charts.bitnami.com/bitnami helm repo add stable http://mirror.azure.cn/kubernetes/charts helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts helm repo add incubator https://charts.helm.sh/incubator#更新charts列表 helm repo update helm repo list#查看stable仓库可用的charts列表 helm search repo stable#删除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 的 namespacehelm install bitnami/redis --generate-name#不指定 release 的名字时,需使用 –generate-name 随机生成一个名字#查看所有 release helm ls helm list#查看指定的release状态 helm status my-redis#删除指定的release helm uninstall my-redis

Helm命令
completion命令补全 create创建一个给定名称的chart dependency管理chart的依赖关系 envhelm环境信息 get获取给定release的扩展信息 help命令帮助 history获取release历史 install部署chart lint对chart进行语法检查 listreleases列表,list可简写为ls package打包chart plugininstall、list、uninstall Helm插件 pull从repo中下载chart并(可选)将其解压到本地目录 repoadd、 list、remove、update、 index Helm的repo rollback回滚release到一个以前的版本 search查询在charts中的关键字 show显示chart的信息 status显示给定release的状态 template本地渲染模板 test测试运行release uninstall删除release upgrade升级release verify验证给定路径的chart是否已签名且有效 version显示helm的版本信息

Helm自定义模板charts 除了可以在 repo 中下载,还可以自己自定义,创建完成后通过 helm 部署到 k8s。
拉取 chart
mkdir /opt/helm cd /opt/helmhelm pull stable/mysqlls mysql-1.6.9.tgztar xf mysql-1.6.9.tgzyum install -y treetree mysql mysql ├── Chart.yaml ├── README.md ├── templates │├── configurationFiles-configmap.yaml │├── deployment.yaml │├── _helpers.tpl │├── initializationFiles-configmap.yaml │├── NOTES.txt │├── pvc.yaml │├── secrets.yaml │├── serviceaccount.yaml │├── servicemonitor.yaml │├── service.yaml │├── ingress.yaml │└── tests │├── test-configmap.yaml │└── test.yaml └── values.yaml#可以看到,一个 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 中重复使用
创建自定义的 chart
helm create nginxtree 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.yamlcat 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 "cat nginx/values.yaml | grep repository repository: nginx #以上变量值是在 create chart 的时候就自动生成的默认值,你可以根据实际情况进行修改。

修改 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: 1image: repository: nginx pullPolicy: IfNotPresent tag: "latest"#设置镜像标签imagePullSecrets: [] nameOverride: "" fullnameOverride: ""serviceAccount: create: true annotations: name: ""podAnnotations: podSecurityContext: # fsGroup: 2000securityContext: # capabilities: #drop: #- ALL # readOnlyRootFilesystem: true # runAsNonRoot: true # runAsUser: 1000service: type: ClusterIP port: 80ingress: enabled: true#开启 ingress className: "" annotations: # kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" hosts: - host: www.jzm.com#指定ingress域名 paths: - path: / pathType: Prefix#指定ingress路径类型 tls: [] #- secretName: chart-example-tls #hosts: #- chart-example.localresources: limits: cpu: 100m memory: 128Mi requests: cpu: 100m memory: 128Miautoscaling: enabled: false minReplicas: 1 maxReplicas: 100 targetCPUUtilizationPercentage: 80 # targetMemoryUtilizationPercentage: 80nodeSelector: tolerations: []affinity:

打包 chart
helm lint nginx#检查依赖和模版配置是否正确 helm package nginx#打包 chart,会在当前目录下生成压缩包 nginx-0.1.0.tgz

部署 chart
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.yamlhelm ls NAMENAMESPACEREVISIONUPDATEDSTATUSCHARTAPP VERSION nginxdefault12022-01-18 23:43:06.170248683 +0800 CST deployednginx-0.1.0 1.16.0kubectl get pod,svc NAMEREADYSTATUSRESTARTSAGE pod/nginx-67779bd969-kq2fm1/1Running058mNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE service/kubernetesClusterIP10.96.0.1< none> 443/TCP37h service/nginxClusterIP10.100.0.171< none> 80/TCP58s

部署 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.yamlkubectl get pod,svc -n ingress-nginx NAMEREADYSTATUSRESTARTSAGE pod/nginx-ingress-controller-54b86f8f7b-jjlnj1/1Running079sNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE service/ingress-nginxNodePort10.101.36.34< none> 80:30665/TCP,443:30363/TCP6skubectl get ingress NAMECLASSHOSTSADDRESSPORTSAGE nginx< none> www.jzm.com10.101.36.348058mvim /etc/hosts ..... 192.168.80.12 node02 www.jzm.comcurl http://www.jzm.com:30665

修改为 NodePort 访问后,升级
vim nginx/values.yaml service: type: NodePort port: 80 nodePort: 30080ingress: enabled: falsevim 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 kubectl get svc NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGE kubernetesClusterIP10.96.0.1< none> 443/TCP38h nginxNodePort10.100.0.171< none> 80:30080/TCP79mcurl 192.168.80.14:30080

回滚
#根据 release 版本回滚 helm history nginx#查看 release 版本历史helm rollback nginx 1#回滚 release 到版本1helm history nginx#nginx release 已经回滚到版本 1 REVISIONUPDATEDSTATUSCHARTAPP VERSION DESCRIPTION 1Tue Jan 18 23:43:06 2022supersedednginx-0.1.0 1.16.0Install complete 2Wed Jan 19 01:02:42 2022supersedednginx-0.1.0 1.16.0Upgrade complete 3Wed Jan 19 01:04:52 2022deployednginx-0.1.0 1.16.0Rollback to 1#通常情况下,在配置好 templates 目录下的 kubernetes 清单文件后,后续维护一般只需要修改 Chart.yaml 和 values.yaml 即可。在命令行使用 --set 指定参数来部署(install,upgrade)release #注:此参数值会覆盖掉在 values.yaml 中的值,如需了解其它的预定义变量参数,可查看 helm 官方文档。 helm upgrade nginx nginx --set image.tag=1.15

Helm仓库
  • helm 可以使用 harbor 作为本地仓库,将自定义的 chart 推送至 harbor 仓库。
安装 harbor
#上传 harbor-offline-installer-v1.9.1.tgz 和 docker-compose 文件到 /opt 目录 cd /opt cp docker-compose /usr/local/bin/ chmod +x /usr/local/bin/docker-composetar zxf harbor-offline-installer-v1.9.1.tgz cd harbor/vim harbor.yml hostname: 192.168.80.13 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

安装 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.gzmkdir ~/.local/share/helm/plugins/helm-push tar -zxvf helm-push_0.8.1_linux_amd64.tar.gz -C ~/.local/share/helm/plugins/helm-pushhelm repo ls#登录 Harbor WEB UI 界面,创建一个新项目 浏览器访问:http://192.168.80.10 ,默认的管理员用户名和密码是 admin/Harbor12345 点击 “+新建项目” 按钮 填写项目名称为 “chart_repo”,访问级别勾选 “公开”,点击 “确定” 按钮,创建新项目#添加仓库 helm repo add harbor http://192.168.80.13/chartrepo/chart_repo --username=admin --password=Harbor12345 #注:这里的 repo 的地址是< Harbor URL> /chartrepo/< 项目名称> ,Harbor 中每个项目是分开的 repo。如果不提供项目名称, 则默认使用 library 这个项目。#推送 chart 到 harbor 中 cd /opt/helm helm push nginx harbor#查看 chart_repo 项目中的 Helm Charts


    推荐阅读