亚马逊AWS官方博客

使 Helm 达到企业就绪

部署到 Kubernetes 的典型应用程序由多个清单组成,例如每个微服务的部署与服务清单。部署这些单独的清单可能极具挑战 — 这是 Helm 等包装管理器将发挥作用的地方。此博文由 JFrog 的 Baruch Sadogursky 撰写,介绍了为使 Helm 达到企业就绪而正在实施的工作以及您如何为它做贡献。- Arun


TL/DR:包装管理器总体上非常棒但 Kubernetes 的包装管理器 Helm 也……完全不差。在包装管理器的七大致命罪恶中,Helm 仅出现了两个,并且很容易纠正。下面我们将解释这是如何实现的。虽然我们还没有达到那一步,但您可以预期 Helm 会在未来达到企业就绪水平。还可以做得更好,您可以贡献力量!阅读如何进行贡献。此博文不涉及如何开始使用 Helm,此方面的信息请参阅 Helm 网站,该网站提供了非常优秀的文档。此博文涉及的是一些 Helm 设计和实施决策、优点、缺点以及如何纠正。

包装管理器与打印机有哪些共同点

您也许有过经历(并从电影 the Oatmeal)知道打印机来自地域,就是为了给我们制造各种不幸。包装管理器也是一样。Sam Boyer 参与了一个 Go 包装管理器实施项目,在他的博文“你为什么要写包装管理器”中非常完美地概括了编写和使用包装管理器时遇到的问题。一般而言,我们在 JFrog 与包装管理器打交道已经超过十年,我们的经验是每个包装管理器都至少存在我们所称包装管理器的七大致命罪恶的一个(但通常会更多):

  1. 过度架构
  2. 对企业场景缺乏规划(例如无私有存储库、不会扩展等)
  3. 可下载的索引
  4. CSDR(跨站依赖项解析)漏洞
  5. 缺乏恰当的包装身份验证
  6. 缺乏版本管理
  7. 为中央存储库使用错误的服务(并硬编代码)

Helm 不仅仅是可以!

我们非常喜欢 Helm。它成功避免了上述大多数问题。它非常简单(第 1 项)、依赖项有版本控制(第 6 项)、不允许随意使用 URL(第 4 项)、作者通过公开身份验证(第 5 项)以及使用 Blob 存储实施中央存储库(第 7 项)。几乎一切都好。

没有身份验证?这不能称之为“企业就绪”!

这是在您的扩展行程中,您需要知道谁部署和下载了什么,以及您需要开始向某些人和及其授予允许或不允许作出某些事情的权限的时候。一旦事情暴露出来,往往都太晚了。直到最近以前,您都无法使用 Helm 做到这一点。虽然您可以轻松在自己的网络内部启动自己的私有存储库,它只在一段时间内支持小团队,但不足以满足严肃的开发组织的要求,特别是拥有跨团队依赖项和贡献要求的组织。为每个团队单独安装以强制执行某种类型的隔离?跨团队元数据的缺乏和维护开销属于严肃的障碍。

解决颁发:提供凭证

Helm 接受了我们的 pull 请求,解决了此问题。从 Helm 2.9 开始,您可以将“用户名”和“密码”交给存储库,由它强制执行身份验证,并最终根据这些凭证完成授权。

图表越多,问题越多

在解决了这一问题后,我们现在面临的是可下载索引的问题。首先,它为什么会成为一个问题?能够执行在线搜索难道不好吗?我们认为可下载的索引尽管在第一次创建时勉强能够站住脚,但现在制造的问题要多过它解决的问题。过去执行集中的并发搜索十分困难,但现在(例如 Google)是不是不再困难

那么假设您喜欢离线搜索。您下载了最新的索引(它在服务器上持续更新,因此您本地的索引始终会过期),找到一个没有互联网的地方(我过去常说“到飞机上”,但现在也不再可能了),运行图表搜索,发现一张神奇的图表。接下来该怎么办呢?您仍然无法下载该图表。此外,我是不是提到您的本地索引也许已经过期,您需要在每次希望搜索时更新?因此,Helm 索引实施的真正问题在于:可扩展性。Helm 的整个存储库只有一个索引文件。它包含所有图表的列表、有关每张图表的元数据、每张图表的所有版本的列表、以及有关每个版本的元数据。这有许多文本,大量重复。我们运行一些基准,但如果您有许多图表 ,效果就不太好:

Helm 基准比较结果

正如您可以看到,如果您有许多图表,客户端解析下载的索引消耗的内存直线飙升,原因有如下几个:

  1. 客户端解析 YAML 文件,利用它创建 JSON 对象并进行处理。
  2. 每个事物一个索引。这不仅仅是巨大。
  3. 其中还有无数的重复。每个版本的元数据都是重复自身。

索引的集中和重复

让我们来看可以解决这一问题的一些措施:

解决办法 1 — 压缩

让我们 gzip 一下传输中的索引。这对处理时间没有帮助(实际上,解压缩会增加处理时间),但会极大地减少传输中的索引大小(实际上达到一个量级)。但我们为什么没有说我们减少了处理负载?我们将稍后讨论这个问题,但请注意,不论一个人说什么,延迟总是存在的。如果我们可以通过这种简单的解决办法将负载大小减少十倍,那就做!现在回到减少处理时间和负载。

解决办法 2 — 停止过多转换

不要传输到 YAML 然后再转换为 JSON。我们发现 JSON 要比 YAML 更容易解析,因此也许我们应该直接传输压缩后的 JSON 文件。

解决办法 3 — 分解攻克

将索引分解为允许按微量下载和解析的结构,而不是下载和解析一个庞大的文件:

  • 主索引:应用程序列表(最新版本)
    • `artifactory:5.8.3`
  • 应用程序索引:版本列表(以及应用程序级的元数据)
    • `description`
    • `maintainers`
    • `keywords`
    • `sources`
  • 版本索引:版本详细信息
    • `appVersion`
    • `created`
    • `digest`
    • `url`

如要搜索某个图表,您只需下载和解析顶级索引,因为它不包含任何元数据,非常小。如要描述图表并获取版本列表,而不是最新版本,则只需要下载和解析应用程序索引。由于它仅包含有关一个图表的元数据以及版本列表,因此也很小。最后,如果我们需要下载图表,我们会下载并解析有关该图表的特定版本的元数据,使用 URL 进行下载,使用摘要进行验证等。

布局

我们刚刚自己制造了一个复杂性。这种分解后的索引要求有存储库布局。在根中有一组 tar.gz 和一个 YAML 索引不会再将它切开。现在我们需要类似于下面的东西:

repo
       |---app
            |---ver1
            |---ver2

这不是什么大事,Helm 存储库客户端应当封装存储库的结构,同时搜索、检索和推送命令也应当有存储库的意识,对不对?但 Helm 从来都没有推送命令。这在过去并不是问题,因为没有布局的情况下,任何 curl 上传都会搞定事情 — 您只需以 HTTP 方式将图表发布到存储库的根即可。但推出布局后,情况就变了。

解决办法:增加推送命令

在增加推送命令的问题上一直都有许多讨论。它将充分包含传输协议的变更(从 YAML 改为压缩后的 JSON)以及存储库布局的变更。这一工作正在进行中,是 Helm 3 的一部分;Matt Butcher 描述了他们计划在下一个大版本中推出的许多改进。虽然大多数变更都在运行时和 Helm 的模板部分,他也提到“图表存储库性能方面的改变”,并且官方设计方案包含了一个“向存储库推送包装的命令”。

社群巨作!

正如您所看到,Helm 已经避免了其他包装管理器的大多数缺陷。虽然还有改进空间,但在 JFrog 和其他社群成员的帮助下(如此博文所描述),我们将会解决盘桓在 Helm 和大规模企业采用之间的最后一个技术问题。由于身份验证问题已经得到解决,索引优化、存储库布局和增加推送命令也在研究中,我们可以预期 Helm 将成为最先进的包装管理器之一。当然仍有许多工作要做。Helm 让开始作出贡献变得十分容易。只需寻找标记为“good first issue”的问题,加入这个令人向往的社群即可。


Baruch SadogurskyBaruch Sadogursky 热爱就技术问题发声。言简意赅,在技术上的亲身经历让他非常聪明,17 年的高科技经验也有很大帮助。当他没有在讲台(或乘坐飞机前往讲台)时,他研究技术、人以及它们的工作机制,或更准确地说,研究它们不正常的机制。Baruch 是 JFrog 开发发布总监和开发人员代表、CNCF 大使、积极的开发运营、Java 和 Groovy 问题会议发言人,经常出席行业顶级的活动,包括 JavaOne(他荣获 Rock Star 奖)、DockerCon、Devoxx、DevOps Days、OSCON、Qcon 等等。请在 Twitter 上关注他(他非常有趣!):@jbaruch本博文中的内容和观点均源自第三方作者,AWS 对本博文中的内容或准确性不承担任何责任。