应用部署工具 Helm v2

本文基于helm v2版本书写,当前主流使用helm v3版本。

helm v2和v3的区别 之一是移除tiller,基本使用的区别不大,helm v3可以参考本文。

 

简化Kubernetes应用部署工具-Helm简介

 

【编者的话】微服务和容器化给复杂应用部署与管理带来了极大的挑战。Helm是目前Kubernetes服务编排领域的唯一开源子项目,做为Kubernetes应用的一个包管理工具,可理解为Kubernetes的apt-get / yum,由Deis 公司发起,该公司已经被微软收购。Helm通过软件打包的形式,支持发布的版本管理和控制,很大程度上简化了Kubernetes应用部署和管理的复杂性。

随着业务容器化与向微服务架构转变,通过分解巨大的单体应用为多个服务的方式,分解了单体应用的复杂性,使每个微服务都可以独立部署和扩展,实现了敏捷开发和快速迭代和部署。但任何事情都有两面性,虽然微服务给我们带来了很多便利,但由于应用被拆分成多个组件,导致服务数量大幅增加,对于Kubernetest编排来说,每个组件有自己的资源文件,并且可以独立的部署与伸缩,这给采用Kubernetes做应用编排带来了诸多挑战:

  1. 管理、编辑与更新大量的K8s配置文件
  2. 部署一个含有大量配置文件的复杂K8s应用
  3. 分享和复用K8s配置和应用
  4. 参数化配置模板支持多个环境
  5. 管理应用的发布:回滚、diff和查看发布历史
  6. 控制一个部署周期中的某一些环节
  7. 发布后的验证

而Helm恰好可以帮助我们解决上面问题。

Helm把Kubernetes资源(比如deployments、services或 ingress等) 打包到一个chart中,而chart被保存到chart仓库。通过chart仓库可用来存储和分享chart。Helm使发布可配置,支持发布应用配置的版本管理,简化了Kubernetes部署应用的版本控制、打包、发布、删除、更新等操作。

本文简单介绍了Helm的用途、架构与实现。

 

Helm产生原因

利用Kubernetes部署一个应用,需要Kubernetes原生资源文件如deployment、replicationcontroller、service或pod 等。而对于一个复杂的应用,会有很多类似上面的资源描述文件,如果有更新或回滚应用的需求,可能要修改和维护所涉及的大量资源文件,且由于缺少对发布过的应用版本管理和控制,使Kubernetes上的应用维护和更新等面临诸多的挑战,而Helm可以帮我们解决这些问题。

Helm架构

Helm基本架构如下:

img

 

Helm用途:

做为Kubernetes的一个包管理工具,Helm具有如下功能:

Helm有三个重要概念:

Helm组件

Helm有以下两个组成部分:

Helm Client是用户命令行工具,其主要负责如下:

Tiller Server是一个部署在Kubernetes集群内部的server,其与Helm client、Kubernetes API server进行交互。Tiller server主要负责如下:

简单的说,client管理charts,而server管理发布release。

Helm实现

Helm client

Helm server

说明:配置文件尽可能使用YAM格式

 

欢迎转载,请注明作者出处:张夏,FreeWheel Lead Engineer,Kubernetes中文社区

原文:简化Kubernetes应用部署工具-Helm简介

简化Kubernetes应用部署工具-Helm安装

Kubernetes中文社区 于 2017-10-16 15:47:22 发布

 

【编者的话】微服务和容器化给复杂应用部署与管理带来了极大的挑战。Helm是目前Kubernetes服务编排领域的唯一开源子项目,做为Kubernetes应用的一个包管理工具,可理解为Kubernetes的apt-get / yum,由Deis 公司发起,该公司已经被微软收购。Helm通过软件打包的形式,支持发布的版本管理和控制,很大程度上简化了Kubernetes应用部署和管理的复杂性。

Helm把Kubernetes资源(比如deployments、services或 ingress等) 打包到一个chart中,而chart被保存到chart仓库。通过chart仓库可用来存储和分享chart。Helm使发布可配置,支持发布应用配置的版本管理,简化了Kubernetes部署应用的版本控制、打包、发布、删除、更新等操作。

本文展示了Helm的Client、Server与本地Chart仓库的安装过程。

关于Helm简介请参考:简化Kubernetes应用部署工具-Helm简介

 

Helm安装

Helm CLINET安装

Helm Client安装过程如下:

  1. 下载 Helm 2.6.1:https://storage.googleapis.com/kubernetes-helm/helm-v2.6.1-linux-amd64.tar.gz

  2. 解包:tar -zxvf helm-v2.6.1-linux-amd64.tgz

  3. helm二进制文件移到/usr/local/bin目录:

    mv linux-amd64/helm /usr/local/bin/helm

Helm TILLER安装

Helm Tiller是Helm的server,Tiller有多种安装方式,比如本地安装或以pod形式部署到Kubernetes集群中。本文以pod安装为例,安装Tiller的最简单方式是helm init, 该命令会检查helm本地环境设置是否正确,helm init会连接kubectl默认连接的kubernetes集群(可以通过kubectl config view查看),一旦连接集群成功,tiller会被安装到kube-system namespace中。

执行helm init,该命令会在当前目录下创建helm文件夹即~/.helm,并且通过Kubernetes Deployment 部署tiller. 检查Tiller是否成功安装:

Tiller其他安装形式:
Helm TILLER删除

由于 Tiller的数据存储于Kubernetes ConfigMap中,所以删除、升降级Tiller,原Helm部署的应用数据并不会丢失。

删除Tiller:

Chart仓库

chart仓库用来存储和分享打包的chart,官方chart仓库由Kubernetes Charts维护, Helm允许我们创建私有chart仓库。

创建chart仓库

chart仓库是一个可用来存储index.yml与打包的chart文件的HTTP server,当要分享chart时,需要上传chart文件到chart仓库。任何一个能能够提供YAML与tar文件的HTTP server都可以当做chart仓库,比如Google Cloud Storage (GCS) bucket、Amazon S3 bucket、Github Pages或创建你自己的web服务器。

Chart仓库结构

一个chart仓库由一个chart包与index.yaml文件组成,index.yaml记录了chart仓库中全部chart的索引,一个本地chart仓库的布局例子如下:

~/.helm/repository/local/index.yaml文件中记录了chart的诸如名称、url、version等一些metadata信息。
创建本地chart仓库

创建chart仓库有多种方式,本文以创建一个本地仓库为例:

管理chart仓库

上面步骤中,已经创建了一个本地的chart仓库,接下来讲述如何在chart仓库中维护chart。chart须遵循 SemVer 2 规则填写正确的版本格式。

一旦chart目录已经存在,将chart打包,并移动到的一个新建目录,通过helm repo index 命令将chart的metadata记录在index.yaml文件中。

上传chart到chart仓库,通过helm repo add命令上传chart到chart仓库:

查看chart是否上传仓库成功:

查找上传的chart:

 

欢迎转载,请注明作者出处:张夏,FreeWheel Lead Engineer,Kubernetes中文社区

原文:简化Kubernetes应用部署工具-Helm安装

简化Kubernetes应用部署工具-Helm之应用部署

weixin_34387468 于 2017-10-11 14:05:00 发布

 

【编者的话】微服务和容器化给复杂应用部署与管理带来了极大的挑战。Helm是目前Kubernetes服务编排领域的唯一开源子项目,做为Kubernetes应用的一个包管理工具,可理解为Kubernetes的apt-get / yum,由Deis 公司发起,该公司已经被微软收购。Helm通过软件打包的形式,支持发布的版本管理和控制,很大程度上简化了Kubernetes应用部署和管理的复杂性。

随着业务容器化与向微服务架构转变,通过分解巨大的单体应用为多个服务的方式,分解了单体应用的复杂性,使每个微服务都可以独立部署和扩展,实现了敏捷开发和快速迭代和部署。但任何事情都有两面性,虽然微服务给我们带来了很多便利,但由于应用被拆分成多个组件,导致服务数量大幅增加,对于Kubernetest编排来说,每个组件有自己的资源文件,并且可以独立的部署与伸缩,这给采用Kubernetes做应用编排带来了诸多挑战:

  1. 管理、编辑与更新大量的K8s配置文件
  2. 部署一个含有大量配置文件的复杂K8s应用
  3. 分享和复用K8s配置和应用
  4. 参数化配置模板支持多个环境
  5. 管理应用的发布:回滚、diff和查看发布历史
  6. 控制一个部署周期中的某一些环节
  7. 发布后的验证

而采用Helm,可以轻松的解决上面的问题。

Helm把Kubernetes资源(比如deployments、services或 ingress等) 打包到一个chart中,而chart被保存到chart仓库。通过chart仓库可用来存储和分享chart。Helm使发布可配置,支持发布应用配置的版本管理,简化了Kubernetes部署应用的版本控制、打包、发布、删除、更新等操作。

本文的目标是展示Helm的一次发布的生命周期,包含了chart创建、更新、回滚、删除等,另外会展示helm的强大版本管理功能。

关于Helm安装、简介请参考: 简化Kubernetes应用部署工具-Helm安装 简化Kubernetes应用部署工具-Helm简介

 

部署Kubernetes应用

获取chart

获取版本为0.2.8的mysql并解压缩包:

利用helm lint命令检查下载的chart是否存在问题:

 

创建chart

利用helm create mychart命令创建一个mychart目录:

生成的mychart的文件结构如下:

 

生成chart目录里有Chart.yaml, values.yaml 与 NOTES.txt等文件,下面分别对chart中几个重要文件解释: Chart.yaml 包含了chart的meta

chart安装有以下几种方式:

覆盖chart中的默认值,通过指定配置文件方式:

或者通过–set key=value形式:

安装release名称为mysql例子如下,请注意NOTES中对Mysql的使用说明:

通过helm status查看release状态:

或通过helm list -a查看全部的release,tag “-a”是查看全部的release,包括已部署、部署失败、正在删除、已删除release等。

 

更新release

Helm使用helm upgrade更新已安装的release:

查看指定release的历史部署版本信息:

查看指定release的历史版本部署时部分配置信息,以resources.requests.memory为例,符合查看部署符合预期:即第一次部署resources.requests.memory设置为512Mi,第二次的升级resources.requests.memory设置为1024Mi:

 

版本回滚

回滚到第一次的版本:

查看mysql release的版本信息,当前已经回滚到REVISION为1的版本:

 

删除chart

利用helm delete命令删除一个chart:

确认chart是否删除:

即使删除的chart,其发布的历史信息还是继续被保存。

可以恢复一个已经删除的release:

如果希望彻底删除一个release,可以用如下命令:

再次查看刚被删除的mysql release,提示已经无法找到,符合预期:

 

Helm对release的版本管理

在上面例子中,已经展示了Helm对release的非常强大的版本管理功能,比如通过”helm list -a”查看有哪些release,通过” helm hist“查看某一个具体的release发布过的历史版本,以及通过” helm get --revision”,查看某个release的一次历史版本对应的具体应用配置信息等。即使已经被删除的release仍然有记录,并且通过Helm能够快速回滚到已删除release的某个发布过的历史版本。Helm的这些版本管理功能,Kubernetes原生并不支持。

 

欢迎转载,请注明作者出处:张夏,FreeWheel Lead Engineer,DockOne社区

原文发布时间为:2017-09-14

本文作者:张夏

本文来自云栖社区合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。

 

原文标题:简化Kubernetes应用部署工具-Helm之应用部署

简化Kubernetes应用部署工具-Helm之Release配置

weixin_34310369 于 2017-10-11 14:03:00 发布

【编者的话】微服务和容器化给复杂应用部署与管理带来了极大的挑战。Helm是目前Kubernetes服务编排领域的唯一开源子项目,做为Kubernetes应用的一个包管理工具,可理解为Kubernetes的apt-get / yum,由Deis 公司发起,该公司已经被微软收购。Helm通过软件打包的形式,支持发布的版本管理和控制,很大程度上简化了Kubernetes应用部署和管理的复杂性。

随着业务容器化与向微服务架构转变,通过分解巨大的单体应用为多个服务的方式,分解了单体应用的复杂性,使每个微服务都可以独立部署和扩展,实现了敏捷开发和快速迭代和部署。但任何事情都有两面性,虽然微服务给我们带来了很多便利,但由于应用被拆分成多个组件,导致服务数量大幅增加,对于Kubernetest编排来说,每个组件有自己的资源文件,并且可以独立的部署与伸缩,这给采用Kubernetes做应用编排带来了诸多挑战:

  1. 管理、编辑与更新大量的K8s配置文件
  2. 部署一个含有大量配置文件的复杂K8s应用
  3. 分享和复用K8s配置和应用
  4. 参数化配置模板支持多个环境
  5. 管理应用的发布:回滚、diff和查看发布历史
  6. 控制一个部署周期中的某一些环节
  7. 发布后的验证

而采用Helm,可以轻松的解决上面的问题。

Helm把Kubernetes资源(比如deployments、services或 ingress等) 打包到一个chart中,而chart被保存到chart仓库。通过chart仓库可用来存储和分享chart。Helm使发布可配置,支持发布应用配置的版本管理,简化了Kubernetes部署应用的版本控制、打包、发布、删除、更新等操作。

本文的目标是展示Helm如何做应用配置管理以及服务依赖的处理。

关于Helm安装、简介以及使用请参考: 简化Kubernetes应用部署工具-Helm安装 简化Kubernetes应用部署工具-Helm简介 简化Kubernetes应用部署工具-Helm之应用部署

 

配置发布

前面 简化Kubernetes应用部署工具-Helm之应用部署 文章中展示了一次Helm发布的生命周期,包含了chart创建、更新、回滚、删除等。但这并不是我们使用Helm的唯一原因,我们还需要一个管理配置发布的工具。

Helm Chart模板采用go模板语言编写 Go template language,模板的值记录在values.yaml文件中。values.yaml文件中的值可以在安装chart过程中,通过参数–values YAML_FILE_PATH或–set key1=value1, key2=value2替换。

注意:模板语言中的引用数值型需要注意,不加引号,会被解释为数值。

创建自定义chart

查看mychart结构:

生成chart目录里有Chart.yaml, values.yaml and NOTES.txt等文件,下面分别对chart中几个重要文件解释:

其中mychart/templates/的文件及其作用如下:

创建mychart/templates/configmap.yaml文件,内容如下:

一个模板指令由{{}}标记。{{ .Release.Name }}会把release name插入模板。传入模板的值可被认作是namespaces对象,通过”.”来分隔namespaces元素。

内置对象

对象通过模板引擎传给模板,有几种方式在模板内创建新的对象,比如后面要讲到的tuple。 模板内置对象请参见: https://docs.helm.sh/chart_tem ... jects

Values文件

上面章节提到Helm模板提供了内置的对象,而Values做为4个内置对象之一,有4种来源:

说明:values.yaml默认会被引用,但其会被父chart中的values.yaml文件内容覆盖(overridden),而父chart中的values.yaml文件会被户用-f指定的文件内容覆盖,而用户用-f指定的文件会被–set参数传的值覆盖。简单的说,也就是上面4种Values来源的重要性由上到下的顺序,优先级由低到高。

 

删除默认键值

如需要删除键值对中删除默认key,需要将key的值设置为null, helm也会将从覆盖的键值对中将其剔除。举例说明,期望将下面例子中的livenessProbe替换为 exec

在helm install 时,使用–set livenessProbe.exec.command=[cat,docroot/CHANGELOG.txt],结果如下:

这并非我们的预期,而通过将livenessProbe.httpGet赋值为null:

 

模板功能和Pipeline

前面展示的模板例子中,模板内容基本不去修改,但有一些情况下,我们希望提供给模板的数据对我们更加简单易用。例如对于 .Values对象注入模板的键值可利用模板提供的 quote功能引用。

 

Helm 提供了超过60功能函数,其中一些定义在Go模板语言自身: Go template language . 这些函数是 Sprig template library的一部分。

 

PIPELINES

Pipelines是模板语言的非常强大的特性之一,与Linux/Unix的pipeline类似,pipelines是把模板语言的多个命令通过 (|)的分隔形式,以描述的顺序的实现命令聚合功能。

 

上面例子中,对.Values.favorite.drink | repeat 5 | quote的值coffee重复了5次后引用,而对.Values.favorite.food先做了一次大写转换然后加以引用。类似结果如下:

使用 DEFAULT功能

default是模板中经常使用一个功能,该功能是在模板中指定一个默认值。例如下面例子中,如果.Values.favorite.drink没有被赋值,那么模板被引用时,tea便为其默认值。

 

 

操作符和函数

对于Helm模板,类似eq, ne, lt, gt, and, or等操作符已经实现为函数,

 

控制流(Flow Control)

Helm模板语言提供了如下控制结构:

除此之外,Helm还提供了一些命名模板的行为:

 

IF/ELSE

条件基本的控制结构如下:

 

pipeline会被认为是false 如果值是下面几种类型:

下面configmap例子中,mug预期结果为true:

 

执行helm install --dry-run --debug mychart命令:

 

空格敏感

Helm模板语言对空格非常敏感,左侧有{{-(破折号后面有一个空格)表明空格需要被移除,而右侧 -}}表示空格会被消费。

 

如果不加-,举例如下:

 

那么输出时会移除 {{ 与 }}而留下空格:

或者:

 

结果如下,因为-}}已经把其所在的行移除了。

food: "PIZZA"mug:true

 

使用 with限制引用范围

通过 with 与(.) 指定当前范围到某一个指定的对象,例如下面例子中 .Values.favorites,后面再引用drink与food 时,无需再指定Values.favorite

 

 

RANGE循环

像多数编程语言支持 for 与 foreach 等循环一样,Helm模板语言通过支持range操作符遍历一个集合。

下面例子中 values.yaml 文件部分内容如下:

在ConfigMap中需要遍历Values.pizzaToppings的全部值,可以采用下面形式:

 

其中 |-的作用是生成一个占用多行的字符串。

另外Helm提供了 tuple函数,可以在模板内建立一个list并且遍历它。例如:

 

结果如下:

 

模板变量

模板变量在 range的循环中非常有用,变量的定义格式为$name ,可通过 :=赋值。举例如下:

 

每循环一次 $index的值从0开始递增,并且将遍历的值赋给$topping

或者,对应存在键值对的对象,可以用 range获取:

 

结果如下:

 

命名模板

Helm允许我们创建一个命名模板,通过模板名称,可以在任何地方引用它。一般情况下命名模板会写在_helpers.tpl 中,并以形式 ({{/* ... */}})加上模板说明。比如下面例子中定义了一个my_labels命名模板,并且用 include通过 {{- include "my_labels" }}嵌入到configmap的metadata中。通常 include也可以用 template代替,但是 include在处理YAML文件的格式输出上会更胜一筹,另外 include可以包含一个变量的模板{{ include $mytemplate }}。

 

在configmap.yaml文件中引用该命名模板:

 

需要注意的是,命名模板名称是全局的,如果存在多个同名的模板,最后被load到Tiller中的模板会被最终使用。另外模板的命名通常以chart的名字做为前缀,比如 {{ define "mychart.labels" }} 或 {{ define "mychart_labels" }}。

 

设置模板使用范围

前面的命名模板中,并没有使用模板的内置对象。下面例子中在命名模板中使用了内置对象:

 

在configmap中消费这个命名模板,注意在命名模板调用的末尾加上 ., indent 2表示引用的模板内容向右缩进2格。

 

 

模板访问文件

上个章节中展示了几种创建和访问命名模板的方式,通过命名模板,可以很容易在一个模板中引用另外一个模板。但有的时候,我们还有导入一个普通文件内容来渲染模板的需求,而不仅仅是以模板的形式。Helm提供了一个内置 .Files对象。

Helm支持chart中存在一个普通类型的文件,这些文件也会被与其他模板文件一同打包发给给Tiller,但文件大小目前被限制在1M以内。由于安全原因,一般情况下 templates/的.Files对象不可访问,另外,chart并不会保留 UNIX mode的信息,文件层面的权限并不会影响对.Files对象的访问控制。

 

NOTES.txt文件

在 chart install 或 chart upgrade的尾部,会打印出用户帮助信息,该信息在 templates/NOTES.txt中定制。Helm并不强制提供用户帮助信息,但为了用户更加方便了解和使用所安装的应用,强烈建议在templates/NOTES.txt加上用户帮助信息。举例如下:

 

 

SubChart和全局变量

所谓subchart,指的是一个chart依赖其他chart,被依赖的chart即被称为subchart。

关于subchart的几点说明:

 

操作subchart

创建subchart

创建subchart的过程与普通chart基本一致,唯一需要注意的是,subchart需要创建在父chart的charts文件夹内,举例如下:

为sub chart添加模板和values:

添加 values.yaml 到 mychart/charts/mysubchart :

在 mychart/charts/mysubchart/templates/configmap.yaml 中创建ConfigMap模板:

 

subchart可以单独安装:

父chart的values可以覆盖子chart,在mychart/values.yaml添加:

然后执行 helm install --dry-run --debug mychart命令:

从结果可知,子chart的dessert的已由cake被替换为ice cream。

 

全局chart values

全部chart,包括子chart都可以访问全局chart values。一般全局chart values记录在父chart Values.global中。以mychart/values.yaml为例:

那么在mysubchart/templates/configmap.yaml 中,即可以通过 .Values.global.salad 访问:

 

 

父子chart共享模板

Helm中父子chart之间可以共享模板,在任何一个chart中定义的块,对其他chart均可访问。

 

调试模板

模板在Tiller server端渲染,而非Helm client端。经过Tiller server渲染的模板,最后发送给Kubernetes API server,而YAML文件除了格式问题外,可能还有其他多种因为会被Kubernetes API server拒绝。

 

欢迎转载,请注明作者出处:张夏,FreeWheel Lead Engineer,DockOne社区

原文发布时间为:2017-09-14

本文作者:张夏

本文来自云栖社区合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。

 

原文标题:简化Kubernetes应用部署工具-Helm之Release配置

简化Kubernetes应用部署工具-Helm之Hook

Kubernetes中文社区 于 2017-10-16 15:42:38 发布

【编者的话】微服务和容器化给复杂应用部署与管理带来了极大的挑战。Helm是目前Kubernetes服务编排领域的唯一开源子项目,做为Kubernetes应用的一个包管理工具,可理解为Kubernetes的apt-get / yum,由Deis 公司发起,该公司已经被微软收购。Helm通过软件打包的形式,支持发布的版本管理和控制,很大程度上简化了Kubernetes应用部署和管理的复杂性。

随着业务容器化与向微服务架构转变,通过分解巨大的单体应用为多个服务的方式,分解了单体应用的复杂性,使每个微服务都可以独立部署和扩展,实现了敏捷开发和快速迭代和部署。但任何事情都有两面性,虽然微服务给我们带来了很多便利,但由于应用被拆分成多个组件,导致服务数量大幅增加,对于Kubernetest编排来说,每个组件有自己的资源文件,并且可以独立的部署与伸缩,这给采用Kubernetes做应用编排带来了诸多挑战:

  1. 管理、编辑与更新大量的K8s配置文件
  2. 部署一个含有大量配置文件的复杂K8s应用
  3. 分享和复用K8s配置和应用
  4. 参数化配置模板支持多个环境
  5. 管理应用的发布:回滚、diff和查看发布历史
  6. 控制一个部署周期中的某一些环节
  7. 发布后的验证

而Helm可以帮助我们解决这些问题。

Helm把Kubernetes资源(比如deployments、services或 ingress等) 打包到一个chart中,而chart被保存到chart仓库。通过chart仓库可用来存储和分享chart。Helm使发布可配置,支持发布应用配置的版本管理,简化了Kubernetes部署应用的版本控制、打包、发布、删除、更新等操作。

本文主要对Helm Hook进行简单的介绍和使用说明。

 

关于Helm的安装、介绍与使用请参考:

简化Kubernetes应用部署工具-Helm安装 简化Kubernetes应用部署工具-Helm简介 简化Kubernetes应用部署工具-Helm之应用部署 简化Kubernetes应用部署工具-Helm之Release配置

 

Helm Hook

简化Kubernetes应用部署工具-Helm之应用部署文章中,展示了采用Helm的一次应用release的生命周期过程,涵盖了发布(helm install)、更新(helm upgrade)、回滚(helm rollback)与删除(helm delete)等部分。为了允许chart开发者在应用release的生命周期中某些关键的时间点上,执行一些操作来更好的服务于release的需求,为此Helm提供了hook机制。

举例说明什么是一个Helm hook,比如ConfigMap或Secret要先于其他chart被加载,或希望在更新/回滚/删除一个release之前能够安全的关闭服务,都可以通过Helm hook实现。

Hook和普通模板文件基本相同,但其可以通过加入一些特殊的注释(annotation)与普通模板文件加以区分,下文会介绍hook的基本格式和用法。

支持Hook类型

Helm提供了如下hook供chart开发者使用:

Hook与Release生命周期

上面已经提到,Hook允许chart开发者在release生命周期的一些时间点上可以执行一些操作。以helm install为例,默认情况下其基本生命周期如下:

  1. 用户执行helm install foo
  2. Chart被加载到Helm server-Tiller
  3. 经过一些用户自定义case验证,Tiller用chart中的Values.yaml等渲染foo模板
  4. Tiller加载渲染好的Kubernetes resource到Kubernetes集群
  5. Tiller返回release名称等数据给Helm client
  6. Helm Client退出

如果在install的生命周期内定义pre-install与post-install 2个hook,那么install的生命周期会变成如下序列:

  1. 用户执行helm install foo
  2. Chart被加载到Helm server-Tiller
  3. 经过一些用户自定义case验证,Tiller用chart中的Values.yaml等渲染foo模板
  4. Tiller准备执行pre-install hook(加载hook resource到Kubernetes)
  5. Tiller按hook的权重对hook进行排序,对相同权重的hook按照字母从a-z顺序排序
  6. Tiller按照权重由低到高顺序加载hook
  7. Tiller等待hook状态变为就绪(”Ready”)
  8. Tiller加载resource到Kubernetes
  9. Tiller执行post-install hook(加载hook resource)
  10. Tiller等待hook状态变为就绪
  11. Tiller返回release名称等数据给Helm client
  12. Helm Client退出

所谓hook就绪状态,取决于hook中定义的Kubernetes resource的类型,比如,对于Job类型的resource,就绪状态是job成功构建完成,如果job构建失败,release也失败了。而对于其他类型的resource,一旦resource加载(添加或更新)到Kubernetes,其状态被认为是就绪状态。

Hook权重

前面提到,一个hook可以对应多个resource,例如, secret与config map做为一个pre-install hook. 同时一个resource也可以有多个hook。

 

Helm支持一个hook中的resource设置权重,Helm推荐通过对resource设置权重的方式,按权重大小加载resource。对于权重数值可以设为负数,权重的大小由负数到正数顺序。如果未设置权重,resource的加载是顺序执行的,但执行顺序并不会保证(Helm 2.3.0开始,相同权重的执行顺序按照字母a-z顺序执行,但未来版本可能会对相同权重的资源执行顺序有所变化)。

写一个Hook

Hook与普通的Kubernetes声明文件一样,只是在文件metadata中加了特殊的注释(annotations)。但由于Hook文件是模板文件,所以其也具备全部的模板文件特性,包括从内置对象 .Values, .Release, and .Template获取渲染值等。

例如下面的模板中,定义了一个Job类型的Kubernetes resource,并定义了一个post-install hook,该hook的用途是当Kubernetes加载全部resource完毕后,按照Values对象设置的值sleepyTime执行sleep操作(如sleepyTime未设置,那么sleep 10秒)。

 

Hook资源删除

Helm支持2种删除hook resource策略:

当使用"helm.sh/hook-delete-policy" 注释(annoation)时,删除hook resource支持2种策略:"hook-succeeded""hook-failed"。当删除策略为 "hook-succeeded"时,hook执行成功后,该hook会被Tiller删除。而删除策略为 "hook-failed"时,hook在执行过程中失败后,该hook会被Tiller删除。

Hook resource删除策略举例:

 

利用Hook处理服务启动顺序依赖

所谓服务依赖指的是启动一个服务,依赖于另外服务。这个时候我们就需要设置服务依赖关系来处理了。可以通过Helm hook来实现服务启动依赖的处理:

举例:serviceA服务依赖serviceB, serviceA的pre-install hook中实现

Helm hook的是一种串行且阻塞式操作(blocking operation),所谓阻塞指的同一个chart,在同一个时刻只有一个hook执行,其他hook以及release的生命周期的其他行为活动(helm install, helm upgrade, helm rollback等)都会被阻塞(block),而串行指的是只有当一个hook成功执行完毕才会执行其他hook。

以上面的pre-install hook的例子说明,pre-install hook的job会先于helm install 执行,且在pre-install hook的job执行过程中,其他的release周期活动已经其他hook都不会被执行。当且仅当serviceB:portB/pathB/在指定时间内服务可达时,pre-install hook才会成功执行,余下的hook以及release其他操作才可以继续执行。

把被依赖的服务是否启动的逻辑判断,放在依赖服务的pre-install hook中,利用Helm hook的是一种串行且阻塞式操作(blocking operation)的特性,如果hook执行失败,那么对应的一次release也就失败了,这就达到了服务启动依赖的处理效果。

欢迎转载,请注明作者出处:张夏,FreeWheel Lead Engineer,Kubernetes中文社区

原文:简化Kubernetes应用部署工具-Helm之Hook

 

 

Helm v2与Helm v3的差异及适配方案

更新时间:2025-04-22 GMT+08:00

随着Helm v2 发布最终版本Helm 2.17.0,Helm v3 现在已是 Helm 开发者社区支持的唯一标准。为便于管理,建议用户尽快将模板切换至Helm v3格式

当前社区从Helm v2演进到Helm v3,主要有以下变化:

  1. 移除tiller

    Helm v3 使用更加简单和灵活的架构,移除了 tiller,直接通过kubeconfig连接apiserver,简化安全模块,降低了用户的使用壁垒。

  2. 改进了升级策略,采用三路策略合并补丁

    Helm v2 使用双路策略合并补丁。在升级过程中,会对比最近一次发布的chart manifest和本次发布的chart manifest的差异,来决定哪些更改会应用到Kubernetes资源中。如果更改是集群外带的(比如通过kubectl edit),则修改不会被Helm识别和考虑。结果就是资源不会回滚到之前的状态。

    Helm v3 使用三路策略来合并补丁,Helm在生成一个补丁时,会考虑之前原来的manifest的活动状态。因此,Helm在使用原来的chart manifest生成新补丁时会考虑当前活动状态,并将其与之前原来的 manifest 进行比对,并再比对新的 manifest 是否有改动,并进行自动补全,以此来生成最终的更新补丁。

    详情及示例请见Helm官方文档:https://v3.helm.sh/docs/faq/changes_since_helm2

  3. 默认存储驱动程序更改为secrets

    Helm v2 默认情况下使用 ConfigMaps 存储发行信息,而在 Helm v3 中默认使用 Secrets。

  4. 发布名称限制在namespace范围内

    Helm v2 只使用tiller 的namespace 作为release信息的存储,这样全集群的release名字都不能重复。Helm v3只会在release安装的所在namespace记录对应的信息,这样release名称可在不同命名空间重用。应用和release命名空间一致。

  5. 校验方式改变

    Helm v3 对模板格式的校验更加严格,如Helm v3 将chart.yaml的apiVersion从v1切换到v2,针对Helm v2的chart.yaml,强要求指定apiVersion为v1。可安装Helm v3客户端后,通过执行helm lint命令校验模板格式是否符合v3规范。

    适配方案:根据Helm官方文档 https://helm.sh/docs/topics/charts/适配Helm v3模板,apiVersion字段必填。

  6. 废弃crd-install

    Helm v3删除了crd-install hook, 并用chart中的crds目录替换。需要注意的是,crds目录中的资源只有在release安装时会部署,升级时不会更新,删除时不会卸载crds目录中的资源。若crd已存在,则重复安装不会报错。

    适配方案:根据Helm官方文档 https://helm.sh/docs/chart_best_practices/custom_resource_definitions/, 当前可使用crds目录或者将crd定义单独放入chart。考虑到目前不支持使用Helm升级或删除CRD,推荐分隔chart,将CRD定义放入chart中,然后将所有使用该CRD的资源放到另一个 chart中进行管理。

  7. 未通过helm创建的资源不强制update,release默认不强制升级

    Helm v3强制升级逻辑变化,不再是升级失败后走删除重建,而是直接走put更新逻辑。因此当前CCE release升级默认使用非强制更新逻辑,无法通过Patch更新的资源将导致release升级失败。若环境存在同名资源且无Helm V3的归属标记app.kubernetes.io/managed-by: Helm,则会提示资源冲突。

    适配方案:删除相关资源,并通过Helm创建。

  8. Release history数量限制更新

    为避免release 历史版本无限增加,当前release升级默认只保留最近10个历史版本。

 

更多变化和详细说明请参见Helm官方文档