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

简介: 微服务和容器化给复杂应用部署与管理带来了极大的挑战。Helm是目前Kubernetes服务编排领域的唯一开源子项目,做为Kubernetes应用的一个包管理工具,可理解为Kubernetes的apt-get / yum,由Deis 公司发起,该公司已经被微软收购。

微服务和容器化给复杂应用部署与管理带来了极大的挑战。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开发者使用:

  • pre-install:在模板文件被渲染之后、而在Kubernetes创建任何资源创建之前执行。
  • post-install:在Kubernetes加载全部的资源之后执行。
  • pre-delete:在Kubernetes删除任何resource之前执行。
  • post-delete:在一个release的全部资源被删除之后执行。
  • pre-upgrade:在模板渲染之后,而在Kubernetes加载任何资源之前执行。
  • post-upgrade:在Kubernetes更新完全部resource之后执行。
  • pre-rollback:在模板被渲染之后、而在Kubernetes执行对全部resource的回滚之前。
  • post-rollback:在Kubernetes的全部resource已经被修改之后执行。

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。

 annotations: "helm.sh/hook": post-install,post-upgrade

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秒)。

apiVersion: batch/v1 kind: Job metadata: name: "{{.Release.Name}}" labels: heritage: {{.Release.Service | quote }} release: {{.Release.Name | quote }} chart: "{{.Chart.Name}}-{{.Chart.Version}}" annotations: # This is what defines this resource as a hook. Without this line, the # job is considered part of the release. "helm.sh/hook": post-install "helm.sh/hook-weight": "-5" "helm.sh/hook-delete-policy": hook-succeeded spec: template: metadata: name: "{{.Release.Name}}" labels: heritage: {{.Release.Service | quote }} release: {{.Release.Name | quote }} chart: "{{.Chart.Name}}-{{.Chart.Version}}" spec: restartPolicy: Never containers: - name: post-install-job image: "alpine:3.3" command: ["/bin/sleep","{{default "10" .Values.sleepyTime}}"]

Hook资源删除

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

  • hook-succeeded
  • hook-failed

当使用"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删除策略举例:

 annotations: "helm.sh/hook-delete-policy": hook-succeeded

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

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

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

apiVersion: batch/v1
kind: Job
metadata:
 name: "{{.Release.Name}}"
 labels:
 chart: "{{.Chart.Name}}-{{.Chart.Version}}"
 annotations: "helm.sh/hook": pre-install
 "helm.sh/hook-weight": "-5"
spec: template:
 metadata:
 name: "{{.Release.Name}}"
 labels:
 chart: "{{.Chart.Name}}-{{.Chart.Version}}"
 spec:
 restartPolicy: Never
 containers: - name: pre-install-job
 image: "registry.docker.dev.fwmrm.net/busybox:latest"
 command: ['sh', '-c', "curl --connect-timeout 3 --max-time 5 --retry 10 --retry-delay 5 --retry-max-time 60 --retry-connrefused serviceB:portB/pathB/"]

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也就失败了,这就达到了服务启动依赖的处理效果。

本文转自中文社区-简化Kubernetes应用部署工具-Helm之Hook

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
3天前
|
Kubernetes 应用服务中间件 nginx
Kubernetes详解(六)——Pod对象部署和应用
在Kubernetes系列中,本文聚焦Pod对象的部署和管理。首先,通过`kubectl run`命令创建Pod,如`kubectl run pod-test --image=nginx:1.12 --port=80 --replicas=1`。接着,使用`kubectl get deployment`或`kubectl get pods`查看Pod信息,添加`-o wide`参数获取详细详情。然后,利用Pod的IP地址进行访问。最后,用`kubectl delete pods [Pod名]`删除Pod,但因Controller控制器,删除后Pod可能自动重建。了解更多细节,请参阅原文链接。
11 5
|
3天前
|
Kubernetes Linux Docker
Kubernetes详解(四)——基于kubeadm的Kubernetes部署
Kubernetes详解(四)——基于kubeadm的Kubernetes部署
14 2
|
6天前
|
Kubernetes Cloud Native 持续交付
【Docker专栏】Kubernetes与Docker:协同构建云原生应用
【5月更文挑战第7天】本文探讨了Docker和Kubernetes如何协同构建和管理云原生应用。Docker提供容器化技术,Kubernetes则负责容器的部署和管理。两者结合实现快速部署、自动扩展和高可用性。通过编写Dockerfile创建镜像,然后在Kubernetes中定义部署和服务进行应用暴露。实战部分展示了如何部署简单Web应用,包括编写Dockerfile、构建镜像、创建Kubernetes部署配置以及暴露服务。Kubernetes还具备自动扩展、滚动更新和健康检查等高级特性,为云原生应用管理提供全面支持。
【Docker专栏】Kubernetes与Docker:协同构建云原生应用
|
7天前
|
Kubernetes Cloud Native 持续交付
构建高效云原生应用:Kubernetes与微服务架构的融合
【5月更文挑战第6天】 在数字化转型的浪潮中,企业正迅速采纳云原生技术以实现敏捷性、可扩展性和弹性。本文深入探讨了如何利用Kubernetes这一领先的容器编排平台,结合微服务架构,构建和维护高效、可伸缩的云原生应用。通过分析现代软件设计原则和最佳实践,我们提出了一个综合指南,旨在帮助开发者和系统架构师优化云资源配置,提高部署流程的自动化水平,并确保系统的高可用性。
29 1
|
13天前
|
Kubernetes 应用服务中间件 nginx
K8S二进制部署详解,一文教会你部署高可用K8S集群(二)
K8S二进制部署详解,一文教会你部署高可用K8S集群(二)
|
13天前
|
Kubernetes 网络安全 数据安全/隐私保护
K8S二进制部署详解,一文教会你部署高可用K8S集群(一)
K8S二进制部署详解,一文教会你部署高可用K8S集群(一)
|
14天前
|
SQL Kubernetes 调度
【一文看懂】部署Kubernetes模式的Havenask集群
本次分享内容为havenask的kubernetes模式部署,由下面2个部分组成(部署Kubernetes模式Havenask集群、 Kubernetes模式相关问题排查),希望可以帮助大家更好了解和使用Havenask。
38 1
|
14天前
|
Kubernetes 网络协议 Python
一文教会你,如何通过kubeadm,在生产环境部署K8S高可用集群(二)
一文教会你,如何通过kubeadm,在生产环境部署K8S高可用集群(二)
|
14天前
|
Kubernetes 应用服务中间件 开发工具
一文教会你,如何通过kubeadm,在生产环境部署K8S高可用集群(一)
一文教会你,如何通过kubeadm,在生产环境部署K8S高可用集群(一)
|
15天前
|
Kubernetes Cloud Native 持续交付
构建高效云原生应用:以Kubernetes为核心
【4月更文挑战第27天】 在当今数字化转型的浪潮中,企业急需构建灵活、可扩展的应用来应对不断变化的市场需求。云原生技术以其独特的优势应运而生,成为推动现代应用开发和部署的重要力量。本文深入探讨了云原生的核心组件之一——Kubernetes,解析其如何通过容器编排优化资源利用,提高应用的弹性和可维护性。同时,文章将展示如何在云平台上实现高效的服务发现、自动扩缩容以及持续集成和持续部署(CI/CD),进一步阐述云原生架构下的最佳实践和面临的挑战。