初探云原生应用管理(二): 为何你必须尽快转向 Helm v3

在研究了一番“开放云原生应用中心(AppHub)”以后,程序员小张彷佛已经明白了“云原生应用”究竟是怎么一回事情。mysql

“不就是 Helm 嘛!”git

这不,小张这就准备把本身开发多年的“图书馆管理系统”经过 Helm 打包成 Charts,提交到 AppHub 上个线试试。程序员

“这样,全中国的开发者就都能使用到我开发的图书馆管理系统了!” 
想一想还有点小激动呢! 
然而,还没等编译完,小张就发现 Helm 官方文档上有这么一句提示很是辣眼睛:github

这,究竟是咋回事儿?web

Helm 项目的缘起

Helm 是目前云原生技术体系中进行应用管理最被普遍使用的开源项目,没有之一。根据 CNCF 刚刚发布的 KubeCon EU 2019 的总结报告,Kubernetes(k8s),Prometheus 和 Helm 这三个项目,再次蝉联 KubeCon 上最被关注的开源项目前三名。sql

Helm 项目自己的发布,则要追述到 Deis 仍是一家独立创业公司的时代。api

2016 年,容器 PaaS (所谓的 CaaS)创业方兴未艾,但也开始呈现出同质化竞争和低附加值的种种苗头,而在这片红海当中,当时已经委身卖给 Engine Yard 的 Deis 尤为寸步难行。幸运的是,敏锐的技术嗅觉在最困难的时刻拯救了这个的团队。 2016 年末,Deis 开始全面转向 K8s 体系,很快就发布了一系列专门为 k8s 进行应用管理的开源项目。这其中,定位为“k8s 应用包管理器”的 Helm,是最受欢迎的一个。安全

咱们知道,K8s 自己是没有“应用”这个概念的。好比,小张要在 K8s 上部署的“图书馆管理系统”,实际是由四个 YAML 文件组成的:架构

  1. web-deploy.yaml,用 K8s 的 Deployment 描述的 Java Web 程序;
  2. web-svc.yaml,用 K8s 的 Service 描述的程序访问的入口;
  3. mysql.yaml,用 K8s StatefulSet 描述的 MySQL 实例;
  4. mysql-svc.yaml,用 K8s Service 描述的 MySQL 实例的访问入口。

而后,小张须要执行四次 kubectl apply -f 把这些 YAML 文件都提交给 K8s 来负责运行和管理这个应用。这里面的麻烦之处在于,怎么样去管理这个应用对应的全部 k8s 资源?app

因而 Helm 项目提供了一种简单的思路:它定义了一种新的应用打包格式叫 Chart。一个 myapp 应用的文件布局以下所示:

col 1col 2myapp/  Chart.yaml            values.yaml             templates/

其中,Chart.yaml 里面用来写应用元数据,好比:

col 1col 2apiVersion: v1name:  图书馆管理系统version:  0.1description: 全中国最受欢迎的图书馆管理系统maintainers:   - name: 小张

在 templates/ 目录下,则存放小张编写好的四个 YAML 文件。

此外,小张还能够将这些 YAML 里须要修改的字段定义成“模板变量”,在部署时由 Helm 去负责注入。好比 web-deploy.yaml:

col 1col 2apiVersion: apps/v1kind: Deploymentmetadata:  name: 图书馆管理系统网站spec:  replicas: {{ .Values.replicaCount }}  template:    ...    spec:      containers:        ...

经过上面的语法,小张就把这个 Deployment 的 replicas 值定义成了一个变量,未来就能够在部署的时候经过传参来决定这个图书馆管理系统启动后具体有几个实例了,好比,指定 100 个实例:

col 1col 2helm install apphub/ 图书馆管理系统 --set replicaCount=100

最后,Helm 项目容许你把上面这一系列文件和目录,作成一个压缩包上传到网上,从而被别人经过 helm install 下载安装到。这个上传的地址,就是 Helm Hub 了。

这种应用打包的方法,很大程度上解决了 K8s 应用管理能力缺失的问题,因此在推出以后就很快赢得了开发者的青睐。而 Helm Hub 也成为了继 Docker Hub 以后云原生技术体系里第二个重要的应用分发中心。

Helm 的架构问题

不过,上面这个流程听起来很简单,可是 Helm 在项目的一开始设计中,却使用了一种让人“匪夷所思”的架构。

能够想象,不管是安装仍是更新应用,Helm 其实均可以在客户端调用 K8s API 来完成这些功能。但现实状况是,Helm 必定须要在 Kubernetes 集群里部署了一个叫作 Tiller 的 Server 端,而后把请求都提交给 Tiller,再由 Tiller 去跟 K8s APIServer 进行交互,完成应用的安装操做,这个复杂的过程,能够用下图表示清楚:

图片来源:Helm 官方文档

而这个“多此一举”的架构,不但成为了 Helm 发布之处的一个假设,也贯穿了 Helm v2 的整个项目生命周期。

为何 Helm 要坚持在 K8s 放置一个 Server 端呢?

这里其中一个重要的缘由,在于 Helm 项目最初并不仅但愿作一个简单“应用包管理工具”。

做为一个地道的 PaaS 服务商,Deis 公司从一开始就知道“应用打包”只是本身完整拼图的入口,而 Tiller 的存在,则是让 Helm 成为将来云原生时代“新 PaaS” 的重要伏笔。

Tiller 这个服务端组件,其实至关于 Helm 在 K8s 内插入的一个应用管理控制器。有了它,Helm 不只能够很容易在 K8s 侧存储应用相关的状态,还能够基于 Tiller 在 K8s 内逐步构建出一个微型 PaaS 的功能。而且,这些功能的设立和发展,都不须要依赖于 K8s 自己的应用管理能力。

这也解释了为什么 Helm v2 为何将不少本来能够在客户端上实现的功能都放到 Tiller 中,而且很快就提出了 Release 的概念,发布了 helm upgrade、 helm rollback 等应用升级和回滚的能力。这些设计,其实都与 Helm 最终 PaaS 化的思路有着千丝万缕的联系。

Helm v3:“无可奈何”,与“势在必行”

不过,Helm 的这条演进路线,在 Kubernetes 这个天生以“应用”为中心的基础设施体系里,却栽了个跟头。

咱们知道,Kubernetes 是围绕着声明式 API 来设计的。Kubernetes 的容器编排理念以及 APIServer 实现与扩展机制,其本质目的都是为了帮助用户屏蔽掉基础设施管理的复杂性,容许用户经过统一而整洁的声明式 API 来描述本身的意图和诉求,这正是 Kubernetes 成为“The Platform of Platform”的重要基础。

这也是为什么,Kubernetes 从一开始就对容器进行组合,以便借助 Pod 的概念来模拟进程组的行为;而且坚持使用声明式 API 搭配控制器模型来进行应用编排,经过 API 资源对象的建立与更新(PATCH)来驱动整个系统的持续运转。

这种设计的最终效果,就是用户只须要将一个“描述”应用的 YAML 文件,放在 etcd 里存起来,而后经过控制器模型驱动整个基础设施的状态不断地向用户声明的状态逼近,就也就是 Kubernetes 的核心工做原理了。这套理论,正是 Google Borg/Omega 进行应用管理和编排的核心与基础,同时也是 K8s 同 Mesos 这种资源管理器项目最大的区别。

这时候,咱们也就不难发现。Helm 试图依托 Tiller 推动的应用生命周期管理功能,跟 K8s 的设计发生了冲突。

理论上来说,Helm 只须要将应用描述文件提交给 K8s,剩下的应用启动、发布和回滚等操做,就都交给 K8s 便可。好比在 K8s 的 Deployment 语义中,已经为用户提供了很是详细的滚动更新策略,这些都是应用描述(YAML 文件)里的主要字段:

col 1col 2strategy:  type: Rolling  rollingParams:    updatePeriodSeconds: 1     intervalSeconds: 1     timeoutSeconds: 120     maxSurge: "20%"     maxUnavailable: "10%"

可是如今,Helm 本身也内置了应用的更新和回滚策略,而且它们与 K8s 的策略没有什么关系、都经过 Tiller 帮你完成。这种“喧宾夺主”的体验,让很多人尤为是资深 K8s 用户对 Helm 项目望而却步。

另外一方面,Tiller 的存在,致使 Helm v2 从一开始就引入了不少“奇葩”的设计。

好比,在 Helm v2 中,应用名称(Release Name)必须是个全局惟一的名字,而不是像正常的 K8s API 资源同样,是被 Namespace 隔离开的。

这是由于 Helm 经过一个 Release 对象来记录 Release 的信息,而运行在 K8s 端的 Tiller 要可以访问 Release 对象,就必须保证该对象必须和 Tiller 在同一个 Namespace ,这就致使了全集群的 Release 名字都不能重复。

这个问题,在 Helm v3 中终于得以被修复了。相似的,Helm 的 Revision(应用版本)在 v2 中也是一个全局对象,而如今在 v3 中,一个应用终于能够由本身的 Revision 对象,而且每次升级或者回滚时关联到对应的 Revision 便可。

不过,如今回头来看,Helm 项目当初走向这样的架构,其实也是能够理解的。

在 2016~2017 年,应用管理并非 K8s 主要透出来的核心能力,不多有人可以意识到 K8s 异常复杂的声明式 API 、尤为是 PACTH API 到底意味着什么————哪怕“K8s 声明式应用配置”的大部分理论实际上一直存在于 K8s 文档库最不显眼的一个角落中。因此,在那个时候,你们在 K8s 之上进行应用管理第一个想到的 idea,基本都是在 K8s 里安装一个 Controller 来实现。实际上,当时 Google Cloud 团队本身也提出了一个叫作 Deployment Manager 的插件,这个插件后来跟 Tiller 部分合并在了一块儿。

但开源社区魔力就在于用户“用脚投票”的神奇力量。

Helm 项目做为 “K8s 包管理工具”的设定,让这个项目在云原生社区风生水起;但与此同时, Tiller 这个奇怪的存在,也成为了 Helm 项目进一步向前发展的绊脚石。长久以来,Tiller 组件带来的使用困惑、安全隐患、部署维护的复杂度,几乎占据了 Helm 社区的绝大多数板块。一些厂商甚至干脆本身发布了“去 Tiller 版”的 Helm 发行版来表示“抗议“。

而另外一方面, K8s 的声明式应用管理思路也没有走向外置 Controller 的方式去解决,而是选择继续在 K8s 自己去丰富和完善应用管理与发布能力,这很快也成为了整个 K8s 社区投入的重中之重(这个故事,咱们在后续的《云原生应用管理系列文章》中会为你进行进一步的介绍)。这也就使得 Helm 自己内置的应用管理体系开始与上游社区渐行渐远。

当生态和社区都开始与项目的发展背道而驰的时候,“自我革命”就天然成为了一个势在必行的选择。

Helm v3,云原生应用管理的重要里程碑

除了移除 Tiller、让 Helm 变成纯客户端工具以外,Helm v3 相对于 v2,还有以下一些重要变化:

  • Release 名字缩小至 Namespace 范围:

    • Triller 移除后,Release (应用)名称和 Revision(版本)再也不是全局值,用户能够很是天然的在不一样 namespace 里使用相同的 Release 名字;
  • 合并描述应用依赖的 requirements.yaml 到 Chart.yaml:

    • 进一步减少用户的学习和使用 Helm 进行应用包管理负担
  • 支持 helm push 到远端 Helm Hub,支持登录认证;
  • 支持在容器镜像 Registry 中存储 Charts:

    • 消除 Helm Hub 和 Docker Registry 的重合定位
  • 支持 LUA 语法:

    • Helm 现有的模板变量的参数定义方法,实际上有不少问题,咱们在后续文章中会详细介绍;
  • 能够对 values.yaml 里的内容进行验证(Validation);

关于 Helm v3 的详细解读和实例,你能够继续阅读这篇《深度解读 Helm 3: 犹抱琵琶半遮面》来一探究竟。

经历了这样的重构以后,Helm v3 已经开始调整本身的发展方向,淡化了作一个“微型 PaaS”的思路,更多的关注于应用打包和包管理这两个核心功能上,将更多的应用管理的自由度交换给了 K8s 社区。

这个变化,不管是对于 Helm 社区仍是云原生应用开发者来讲,都是喜闻乐见的。不难预料,Helm v3 很大几率会成为将来云原生应用管理体系中的一个重要工具,而与之相对应的 App Hub,也会成为云应用分发与托管过程当中的重要环节。

若是更向前延伸一些,将来在 K8s 上部署应用,极可能上只须要提交一个应用定义便可。这个应用定义,很大程度上会是相似 Helm Charts 这样的、自包含的应用描述文件,用户在客户端就能够完成这个应用的设置和配置,而后提交给 K8s。接下来,这个应用的建立、更新和发布流程,就均可以由 K8s 以及它所集成的应用服务能力(好比 OpenKruise、Tekton、Istio 和 Knative) 来完成。这种工做形态,极可能正是面向将来的、“云原生应用”的最终走向。

云原生时代,你还有什么理由不去尝试一下 Helm v3 呢?

即刻开始!

虽然还有一些疑惑,小张彷佛也摸索出了 Helm v3 背后的一些“大计划”。

说干就干!

因为 Helm v3 如今还在预览版,没有正式的下载渠道,小张只能打开 GitHub 从 Release 页面下载二进制文件。然而 …………

“怎么会这么卡!”

因为不可描述的缘由,GitHub 托管 Release 的存储在国内访问很是困难。不过,善于利用“百度搜索”的小张,仍是找到了好心人在国内托管的 Helm v3 镜像和安装方法:

https://github.com/cloudnativeapp/workshop/tree/master/kubecon2019china/charts/guestbook#installing-helm-v3

在有了 Helm v3 以后,小张到底能不能顺利的把“图书馆管理系统”作成 Charts,上传到开放云原生应用中心(AppHub)让全国的开发者使用到呢?

咱们拭目以待!

相关文章: 
初探云原生应用管理(一): Helm 与 App Hub

 

本文做者:木环

原文连接

本文为云栖社区原创内容,未经容许不得转载。

相关文章
相关标签/搜索