Kubernetes学习之路(三十)Helm程序包管理器

_____egon新书来袭请看:https://egonlin.com/book.html

一 Helm介绍

1、什么是helm?

helm是k8s的另外一个项目,相当于linux的yum

在yum的仓库中,yum不光要解决包之间的依赖关系,还要提供具体的程序包

而在helm的仓库里面只有配置清单文件,而没有镜像,镜像还是由镜像仓库来提供,比如hub.docker.com、私有仓库.

2、为何要用helm

举个例子,我们需要部署一个MySQL服务,Kubernetes则需要部署以下对象:

① 为了能够让外界访问到MySQL,需要部署一个mysql的service;

②需要进行定义MySQL的密码,则需要部署一个Secret;

③Mysql的运行需要持久化的数据存储,此时还需要部署PVC;

④保证后端mysql的运行,还需要部署一个Deployment,以支持以上的对象。

针对以上对象,我们可以使用YAML文件进行定义并部署,但是仅仅对于单个的服务支持,如果应用需要由一个甚至几十个这样的服务组成,并且还需要考虑各种服务的依赖问题,可想而知,这样的组织管理应用的方式就显得繁琐。为此就诞生了一个工具Helm,就是为了解决Kubernetes这种应用部署繁重的现象。

3、helm核心概念

  • 1、Chart:---》类似与yum的软件包
    • 比如对于一个nginx,我们需要一个deployment的清单文件、一个service的清单文件、一个hpa的清单文件,把这三个文件打包到一起,就是一个应用程序的程序包,称之为Chart,或称helm的程序包,其实质只是一个模板,我们可以对这个模板进行赋值(value),形成我们自定义的清单文件,也就实现我们生产个性化的需求
  • 2、Repository:存放Chart的仓库,用于集中存储和分发Chart;

 

  • 3、Config:应用程序实例化安装运行时所需要的配置信息;
  • 4、Release:特定的Chart部署于目标集群上的一个实例,代表这一个正在运行的应用。当chart被安装到Kubernetes集群,就会生成一个release,chart可以多次安装到同一个集群,每次安装都是一个release。

4、helm程序架构与工作流程

 

Helm主要由Helm客户端、Tiller服务器和Charts仓库组成,如下图:

 

1、在客户端(helm工具,Chart仓库)

Helm把Kubernetes资源打包到一个chart中,而chart被保存到chart仓库中,通过chart仓库可用来存储和分享chart。

helm工作在k8s集群之外,helm管理的Chart仓库存放于本地,helm不直接操作apiserver,而是和Tiller交互,用于发送Chart,实例安装、查询、卸载等操作。

2、服务端(Tlller)

通常运行在K8S集群之上。用于接收helm发来的Charts和Conifg,合并生成release,完成部署。

ps

19年发布的helm 3 的一个很大变化就是移除了heml2中非常重要的组成部分Tiller,即helm3只需要当前用户家目录下有admin.conf就可以与k8s集群通信了,第三小节部署Tiller这一步就不需要了

在helm2中Tiller是helm的一个重要组成部分。它可以在一个共享的集群中管理复杂的应用发布。
从kubernetes 1.6开始默认开启RBAC。这是Kubernetes安全性/企业可用的一个重要特性。但是在RBAC开启的情况下管理及配置Tiller变的非常复杂。为了简化helm的尝试成本我们给出了一个不需要关注安全规则的默认配置。但是,这会导致一些用户意外获得了他们并不需要的权限。并且,管理员/SRE需要学习很多额外的知识才能将Tiller部署的到关注安全的生产环境的多租户K8S集群中并使其正常工作。
在了解了社区成员通常的使用场景后,我们发现Tiller的发布管理系统不需要依靠集群内的Operator来维护状态或充当Helm发布信息的中央枢纽。相反,我们可以简单地从Kubernetes API服务器中获取信息,渲染Charts客户端,并在Kubernetes中存储安装记录。
没有Tiller也能实现所有的功能,所以我们针对Helm 3做出的第一个决定就是彻底删除Tiller。

移除掉Tiller大大简化了hlem的安全模型实现方式。Helm3现在可以支持所有的kubernetes认证及鉴权等全部安全特性。Helm和本地的kubeconfig flie中的配置使用一致的权限。管理员可以按照自己认为合适的粒度来管理用户权限。
了解历史

 

 

二 部署Helm

Helm的部署方式有两种:预编译的二进制程序和源码编译安装,这里使用二进制的方式进行安装

# 官方部署文档:https://helm.sh/docs/intro/install/
curl -O https://get.helm.sh/helm-v3.7.1-linux-amd64.tar.gz
tar -zxvf helm-v3.0.0-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/helm

三 部署Tiller

helm第一次init时,需要链接api-server并进行认证,所以在运行helm时,会去读取kube-config文件,所以必须确认当前用户存在kube-config文件。

Tiller运行在K8s集群之上,也必须拥有集群的管理权限,也就是需要一个serviceaccount,进行一个clusterrolebinding到cluster-admin。

Tiller的RBAC配置示例链接:

# https://github.com/helm/helm/blob/master/docs/rbac.md

cd mainfests/
mkdir helm
cd  helm
cat > tiller-rbac.yaml << EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: tiller
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tiller
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: tiller
    namespace: kube-system

EOF

创建rbac

# kubectl apply -f tiller-rbac.yaml 

# kubectl get sa -n kube-system |grep tiller
tiller                               1         18s

 

安装tiller

# 下载或者从本地导入镜像
docker load -i /home/repos/images/k8s-images/tiller-v2.16.1.tar

# 注意把标签打成gcr.io/kubernetes-helm/tiller:v2.16.1,如果已经打好了则忽略
docker tag 自己的镜像 gcr.io/kubernetes-helm/tiller:v2.16.1

# helm init --service-account tiller   --tiller-image gcr.io/kubernetes-helm/tiller:v2.16.1 --stable-repo-url https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts
helm init --service-account tiller   --tiller-image gcr.io/kubernetes-helm/tiller:v2.16.1

# 
kubectl get pods -n kube-system |grep tiller 
tiller-deploy-759cb9df9-ls47p 1/1 Running 0 16m

四 helm的使用

官方可用的Chart列表:

https://hub.kubeapps.com

helm常用命令:
- helm search:    搜索charts
- helm fetch:     下载charts到本地目录
- helm install:   安装charts
- helm list:      列出charts的所有版本

用法:
  helm [command]

命令可用选项:
  completion  为指定的shell生成自动补全脚本(bash或zsh)
  create      创建一个新的charts
  delete      删除指定版本的release
  dependency  管理charts的依赖
  fetch       下载charts并解压到本地目录
  get         下载一个release
  history     release历史信息
  home        显示helm的家目录
  init        在客户端和服务端初始化helm
  inspect     查看charts的详细信息
  install     安装charts
  lint        检测包的存在问题
  list        列出release
  package     将chart目录进行打包
  plugin      add(增加), list(列出), or remove(移除) Helm 插件
  repo        add(增加), list(列出), remove(移除), update(更新), and index(索引) chart仓库
  reset       卸载tiller
  rollback    release版本回滚
  search      关键字搜索chart
  serve       启动一个本地的http server
  status      查看release状态信息
  template    本地模板
  test        release测试
  upgrade     release更新
  verify      验证chart的签名和有效期
  version     打印客户端和服务端的版本信息

总结

helm repo list                         #查看仓库
helm ls                                 #查看release
helm install 仓库名/包名               #安装
helm template 仓库名/包名 > test.yaml        #把要安装的软件包注入到yaml文件中,然后可以kubectl apply -f来应用
helm uninstall release名字                #卸载release
helm repo add 自定义仓库名字 仓库路径         #添加仓库
helm repo remove 仓库名称                #删除仓库
helm lint 软件包目录                       #检查里面文件的语法
helm upgrade 仓库名/包名 或者 软件包名称        #更新helm之前部署的应用
helm create 名称                       #创建自定义chart
helm plugin add 插件网址                #安装插件,比如helmpush
helm pull 仓库名/包名                   #拉去helm镜像,一般为tgz结尾
helm status release名称                #查看release状态
helm version                            #查看helm版本
helm show values release名称             #查看release的values文件
helm show all release名称                 #查看release的所有信息
helm show chart release名称               #查看release中Chart信息
helm repo update                           #更新仓库信息
helm packages 路径                            #打包 

helm install命令可以从多个来源安装:

  1. 通过chart仓库: helm install stable/mariadb
  2. 通过本地 chart 压缩包: helm install ./nginx-1.2.3.tgz
  3. 通过解压后的chart目录 helm install ./nginx
  4. 通过完整URL: helm install https://example.com/charts/nginx-1.2.3.tgz
命令
helm install /home/nginx-1.2.3.tgz --version 1.1 --namespace nginx --name nginx --values=/home/nginx.conf

有用参数:
--name release的名字
--namespace release的命名空间
-dry-run 模拟一次安装,常和--debug一起使用,调试chart模板是否正常
--no-hooks 在安装过程中不使用hooks
--values 使用YAML文件中指定值

helm upgrade的策略

Helm会尝试执行最小侵入式升级。它只会更新自上次发布以来发生更改的内容。

helm upgrade --install prometheus --namespace prometheus prometheus -f /tmp/prometheus \
  --set manifests.job=true \
  --set storege.requests.size=100Gi

helm upgrde 的时候无法修改job的标签

 当部署一个Chart,其中部署了Job和CronJob等。我们需要更新部署为Job/CronJob的容器的标签,并且在update --install --atomic收到此错误期间:

Error: UPGRADE FAILED: release X failed, and has been rolled back due to atomic being set: cannot patch "X" with kind Job: Job.batch "Y" is invalid: spec.template: Invalid value: [skipped]: field is immutable
  • 原因:
    问题是Kubernetes认为某些事情是不可变的。您不能在某些类型的Kubernetes对象上升级某些值。但是,Helm不知道这些值是什么值,因为它们不会被架构公开。因此,Helm将清单发送给Kubernetes,Kubernetes会以不可变的字段列表作为响应。部署失败,因为无法升级对象。
    解决方案是让您的图表不尝试修改不可变字段。您可以在Kubernetes文档https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/中找到更多信息

如果确定要重新运行该Job,我们建议在Job名称后添加一个随机字符串

metadata:
  name: {{ template "fullname" . }}-{{ randAlphaNum 5 | lower }}

helm 加上--dry-run --debug做调试

我们用模板来生成资源文件的清单,但是如果我们想要调试就非常不方便了,不可能我们每次都去部署一个release实例来校验模板是否正确,所幸的时 Helm 为我们提供了--dry-run --debug这个可选参数,在执行helm install的时候带上这两个参数就可以把对应的 values 值和生成的最终的资源清单文件打印出来,而不会真正的去部署一个release实例,比如我们来调试上面创建的 chart 包:
helm install  /home/ceilometer-6.0.1-beta.164.tgz --dry-run  --debug --version 6.0.1-beta.164 --namespace openstack --name ceilometer --values=/tmp/ceilometer

 

五 charts解读

5.1 常用文件

tree hello-helm/
hello-helm/
├── charts/
├── Chart.yaml
├── templates/
├── requirements.yaml
└── values.yaml

 

  • charts/   (可选项)是一个目录,存放一些调用的charts
  • Chart.yaml (必需项)定义一些基础信息。例如作者、版本等
  • templates/  (必需项)是应用需要的yaml文件模板
  • requirements.yaml  (可选项)同charts一样的。
  • values.yaml  (必需项)默认配置值。例如定义的一些变量等。

5.2 Chart.yaml 描述

  • apiVersion:api版本(v1)
  • name:chart的名称
  • version:版本
  • kubeVersion:k8s的兼容版本
  • description:描述本项目
  • keywords:关于本项目
  • home:本项目主页
  • maintainers:作者
  • icon:图标
  • appVersion:应用版本
  • deprecated:是否已弃用
  • tillerVersion:tiller版本

5.3 requirements.yaml 描述

样例:

dependencies:
  - name: apache
    version: 1.2.3
    repository: http://example.com/charts
  - name: mysql
    version: 3.2.1
    repository: http://another.example.com/charts
使用dependencies引用一个列表。每个对象列表都是要依赖到的chart。
  • name: chart的名称
  • version: chart的版本
  • repository: chart所在的仓库

5.4 templates描述

├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── NOTES.txt
│   └── service.yaml

 

  • NOTES.txt:chart 的 “帮助文本”。这会在用户运行 helm install 时显示给用户。
  • deployment.yaml:创建 Kubernetes deployment 的基本 manifest
  • service.yaml:为 deployment 创建 service 的基本 manifest
  • ingress.yaml: 创建 ingress 对象的资源清单文件
  • _helpers.tpl:放置模板助手的地方,可以在整个 chart 中重复使用

如何创建模版

1、我们删除templates下的所有文件。创建一个configmap.yaml

# rm -rf ./templates/*.*

# vim templates/t1.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mychart-configmap
data:
  myvalue: "Hello World"

2、安装这个charts

[root@localhost test]# helm install --generate-name ./hello-helm/  # 或者指定名字helm install xxx ./hello-helm/
NAME: xxx
LAST DEPLOYED: Wed Dec  1 19:56:02 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

# 如果报错Error: validation: chart.metadata.version is required
那是因为hello-helm/Chart.yaml内没有定version

[root@localhost test]# cat hello-helm/Chart.yaml 
name: xxx
version: 1.1  # 新增这一行

 

 

 3、查看渲染后的资源文件

[root@localhost test]# helm list
NAME                   NAMESPACE    REVISION    UPDATED                                    STATUS      CHART                         APP VERSION
。。。
xxx                    default      1           2021-12-01 19:56:02.315445984 +0800 CST    deployed    xxx-1.1                                  
[root@localhost test]# helm get manifest xxx
---
# Source: xxx/templates/t1.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mychart-configmap
data:
  myvalue: "Hello World"

 

4、 通过变量创建一个简单的模版

Helm Chart 模板使用的是Go语言模板编写而成,并添加了Sprig中的50多个附件模板函数以及一些其他特殊的函

现在我们来重新定义下上面的 configmap.yaml 文件:

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-configmap
data:
  myvalue: "Hello World"

我们将名称替换成了 {{ .Release.Name }}-configmap ,其中包含在{{}}之中的就是模板指令, {{ .Release.Name }}  将 release 的名称注入到模板中来,这样最终生成的 ConfigMap 名称就是以 release 的名称开头的了。这里的 Release 模板对象属于 Helm 内置的一种对象,还有其他很多内置的对象,稍后我们将接触到。

# 1、删除
helm uninstall xxx  # helm delete xxx

# 2、重新安装
helm install xxx666 ./hello-helm/ --dry-run --debug  

会发现变量{{ .Release.Name }}被替换成xxx666

内置对象

刚刚我们使用 {{.Release.Name}} 将 release 的名称插入到模板中。这里的 Release 就是 Helm 的内置对象,下面是一些常用的内置对象,在需要的时候直接使用就可以:

  • Release:这个对象描述了 release 本身。它里面有几个对象:
    • Release.Name:release 名称
    • Release.Time:release 的时间
    • Release.Namespace:release 的 namespace(如果清单未覆盖)
    • Release.Service:release 服务的名称(始终是 Tiller)。
    • Release.Revision:此 release 的修订版本号,从1开始累加。
    • Release.IsUpgrade:如果当前操作是升级或回滚,则将其设置为 true。
    • Release.IsInstall:如果当前操作是安装,则设置为 true。
  • Values:从values.yaml文件和用户提供的文件传入模板的值。默认情况下,Values 是空的。
  • Chart:Chart.yaml文件的内容。所有的 Chart 对象都将从该文件中获取。chart 指南中Charts Guide列出了可用字段,可以前往查看。
  • Files:这提供对 chart 中所有非特殊文件的访问。虽然无法使用它来访问模板,但可以使用它来访问 chart 中的其他文件。请参阅 "访问文件" 部分。
    • Files.Get 是一个按名称获取文件的函数(.Files.Get config.ini)
    • Files.GetBytes 是将文件内容作为字节数组而不是字符串获取的函数。这对于像图片这样的东西很有用。
  • Capabilities:这提供了关于 Kubernetes 集群支持的功能的信息。
    • Capabilities.APIVersions 是一组版本信息。
    • Capabilities.APIVersions.Has $version 指示是否在群集上启用版本(batch/v1)。
    • Capabilities.KubeVersion 提供了查找 Kubernetes 版本的方法。它具有以下值:Major,Minor,GitVersion,GitCommit,GitTreeState,BuildDate,GoVersion,Compiler,和 Platform。
    • Capabilities.TillerVersion 提供了查找 Tiller 版本的方法。它具有以下值:SemVer,GitCommit,和 GitTreeState。
  • Template:包含有关正在执行的当前模板的信息
  • Name:到当前模板的文件路径(例如 mychart/templates/mytemplate.yaml)
  • BasePath:当前 chart 模板目录的路径(例如 mychart/templates)

上面这些值可用于任何顶级模板,要注意内置值始终以大写字母开头。这也符合Go的命名约定。当你创建自己的名字时,你可以自由地使用适合你的团队的惯例。

 

https://www.cnblogs.com/xzkzzz/p/10445807.html

https://www.cnblogs.com/fengzi7314/p/13824992.html

 

 

 

posted @ 2021-11-19 16:25  linhaifeng  阅读(1414)  评论(0编辑  收藏  举报