前言
本书只找到英文版,全文均为机译版本,如果想要理解准确意思建议阅读英文原本。
2007 年,我刚加入 Google 时,就接触到了编排器。我接触的不是 Borg,而是 Ganeti。Ganeti 是一个内部开发的集群管理系统,可在虚拟机上运行。当时,它是 Xen 开源版本的基本包装器,它提供了一种集群解决方案,使我们能够为工程师提供虚拟(而非物理)机器。
我们并没有将 Ganeti 称为编排器,也没有将其与 Borg 相提并论。事后看来,我认为将 Ganeti 视为一种编排器并不过分。它不是在任务(以容器的形式)上运行,而是在虚拟机上运行。在 Google 内部,Ganeti 充当了一座桥梁,将一些工程师可以在物理机器上运行其应用程序的世界与每个工程师都在 Borg 上运行其应用程序的世界连接起来。
几年后,当我们重写为管理 Ganeti 集群和虚拟机而构建的生命周期管理系统时,我对 Borg 有了正式的了解。我们在 Borg 上运行它。快进到 2020 年。新冠疫情来袭,和其他人一样,我发现自己在家工作。突然间,由于不必通勤到曼哈顿的办公室,我每天多了三个多小时。该怎么办?
当然,最明显的选择是开始某种个人项目。但是做什么呢?在与编排器合作了 13 年后,我认为尝试从头开始编写一个编排器可能会很有趣。这能有多难呢?
2020 年夏天的大部分时间我都在开发我的编排器。我把它命名为 Cube,以延续《星际迷航》的主题。令人惊讶的是,我用了不到 3,000 行代码就让它运行起来了。
大约在同一时间,我读了 Thorsten Ball 的《用 Go 编写解释器》。虽然我对解释器或编写编程语言并不一定感兴趣,但我对了解它们的工作原理很感兴趣。然后我突然想到!我可以写一本关于用 Go 编写编排器的书。我希望 2007 年就能拥有这本书!因此,你面前的这本书就诞生了。
我在写作过程的早期就意识到编排是一个大话题。在谈论编排系统时,很容易被次要问题分散注意力。你如何处理服务发现?你如何处理 DNS?那共识呢?我想剥离所有堆积在编排系统之上的东西,只展示核心,即所有其他东西所依赖的基础。并不是说服务发现、DNS 和负载平衡之类的东西不重要。但是在编排系统的上下文中,我们讨论这些东西是因为它们是服务于编排器核心功能的工具:调度应用程序在节点池上运行并管理它们的生命周期。
简而言之,这就是本书的内容:接收用户运行应用程序的请求,确定可以运行该应用程序的机器,然后向所选机器发送启动该应用程序的请求。这样说似乎很简单,不是吗?
除了介绍编排系统的基本概念外,编写本书的另一个目标是让广大读者都能理解内容。因此,虽然我选择用 Go 编程语言编写 Cube 编排器,但我希望任何人都可以通读本书并让代码运行起来,即使你一生中从未写过一行 Go 代码。所有代码都使用基本的 Go 功能。虽然我们确实使用 goroutine 来执行一些基本的并发操作,但我们不使用通道(如果您有兴趣,有很多很棒的资源可以了解并发)。而且我们不使用泛型。(Go 1.18 发布后不久,我确实尝试重构代码和手稿以使用泛型。虽然我让代码运行起来,但我意识到它给这本书带来了不必要的复杂性。它成为已经很长的要解释的事情清单中的另一件要解释的事情。)
我希望你在阅读本书时能获得乐趣。在享受乐趣的过程中,我希望你能从本书中学到与我写作时一样多的东西。
有关本书
《用 Go 构建编排器(从头开始)》旨在帮助您更好地理解编排系统的基本组件。无论您是开发运营工程师、站点可靠性工程师 (SRE) 还是软件工程师,当今的许多技术看起来都像黑匣子。您只需将其部署到云中,然后神奇的“事情”就会发生。众所周知,神奇的技术在发挥作用时非常棒!当它失败时——它肯定会失败!——这种神奇的方面可能会成为快速识别问题并解决问题的障碍。随着越来越多的开发人员将他们的应用程序迁移到云中,他们正在(或将会)在编排系统上运行它们。除非他们在拥有专门的开发运营或 SRE 人员的大型公司工作,否则他们可能需要自己部署和管理他们的应用程序。这包括在问题出现时处理问题。我希望这本书能够消除应用程序在编排器上运行的一些魔力。
谁应该读这本书
用 Go 构建编排器适合负责部署和运行协调系统的人(即 DevOps 工程师和 SRE),以及负责部署和管理在协调系统上运行的应用程序的人(即软件工程师)。如果你想了解协调器是如何工作的,可以阅读 Kubernetes 或 Nomad 的源代码,这两个开源项目都可以在 GitHub 上找到。Kubernetes 有 500 万行 Go 代码。Nomad 的代码库要小得多,但仍有 50 多万行 Go 代码。我不知道你怎么想,但我很难从 50 万行代码中获得什么价值,更不用说 500 万行了!
本书的组织结构:路线图
本书分为 5 部分,共 13 章。
第 1 部分介绍了 Cube 协调器的思维模型,并设置了将在本书其余部分实现的骨架代码库:
- 第 1 章简要介绍了编排系统的目的,然后描述了 Cube 的心智模型,Cube 是本书其余部分所使用的编排器。
- 第 2 章使用第 1 章中的心智模型为 Cube 协调器的核心概念创建骨架代码库。
- 第 3 章通过任务对象的骨架和细节,说明我们将如何实现代码库。
第 2 部分实现了工作组件所需的概念:
- 第 4 章详细说明了 Worker 对象的实现细节。
- 第 5 章为 Worker 构建 API。
- 第 6 章为 Worker 创建了一个框架,用于公开有关其状态和正在运行的任务状态的指标。
第 3 部分实现了管理器组件所需的概念:
- 第 7 章详细描述了 Manager 对象的实现细节。
- 第 8 章为 Manager 构建 API。
- 第 9 章探讨了故障情况,并提出了相应的解决方案。
第 4 部分引导读者重构最初实现的两个组件:
- 第 10 章描述了调度程序接口并实现了更为复杂的调度算法。
- 第 11 章设计并构建了一个存储接口,允许管理器和工作组件将其任务存储在内存中或持久存储在数据库中。
第 5 部分实现了一个命令行界面(CLI),允许读者操作协调器:
- 第 12 章构建了一个 CLI,用于实现启动管理器和 Worker、启动和停止任务以及获取系统中任务状态的命令。
- 第 13 章总结了我们已经取得的成就,并给出了一些下一步行动的建议。
关于代码
本书包含许多源代码示例,既有编号列表,也有与普通文本一起显示的示例。在这两种情况下,源代码都采用等宽字体进行格式化,就像这样,以将其与普通文本区分开来。有时,代码也会以粗体显示,以突出显示与本章中前面的步骤不同的代码,例如,当在现有代码行中添加新功能时。
在许多情况下,原始源代码已被重新格式化;我们添加了换行符并重新设计了缩进以适应书中可用的页面空间。在极少数情况下,即使这样也不够,列表包括行连续标记 (➥)。此外,当在文本中描述代码时,源代码中的注释通常会从列表中删除。许多列表都附有代码注释,突出显示重要概念。
你可以从本书的 liveBook (在线)版本获得可执行的代码片段, liveBook.manning.com/book/build-… Manning 网站( www.Manning.com/books/build… )和 GitHub ( GitHub.com/buildorches… )下载。
关于封面插图
(Build a Orchestrator in Go, From Scratch)封面上的人物是“巴什基里安女人”(Femme Baschkirienne),摘自雅克·格拉塞·德·圣索维尔(Jacques Grasset de Saint-Sauveur) 1788年出版的一本合集。这幅插图是手工绘制和上色的。
在那个年代,人们很容易从衣着打扮中辨别出他们的居住地、职业或生活地位。Manning 以几个世纪前丰富多彩的地区文化为基础,通过图片集(如本作品集)还原了当时的生活,通过书籍封面来颂扬计算机行业的创造性和主动性。