|
关于我们
新书资讯 新书推荐 |
从零构建编排器(Go语言) Kubernetes和Nomad这样的编排框架,使得管理容器化应用变得异常简单。从零开始构建一个编排器,能帮助你深入理解如何部署和扩展容器、集群、Pod以及现代分布式系统中的其他组件。《从零构建编排器(Go语言)》将一步一步指导你从头开始创建自己的编排器。《从零构建编排器(Go语言)》为你提供了一个全方位的视角,深入探讨编排框架和分布式容器化应用的底层运作机制。翻开这本书,你将踏上一段有趣的旅程,利用DockerAPI和GoSDK构建一个简单而实用的编排器。在这个过程中,你将深入理解Kubernetes,并学习一种模式,帮助你在需要时创建自己的个性化编排解决方案。核心亮点?在工作节点上调度容器?使用DockerAPI启动和停止容器?通过简易的API管理工作节点集群?使用GoogleBorg系统的算法进行操作 《从零构建编排器(Go语言)》一书提供了一条极具启发性的学习路径。作者没有从现有平台的使用方法入手,而是通过构建一个简化的编排系统,让读者逐步理解编排系统的核心机制。全书围绕一个名为Cube的示例系统展开,通过清晰的步骤实现任务调度、节点管理、任务运行及系统接口等关键功能,使读者能够从整体上理解编排系统的基本结构和工作方式。书中使用较为精简的代码实现这些功能,使复杂系统的核心思想得以直观呈现。本书不仅介绍了编排系统的基本概念,更重要的是展示了现代基础设施软件的设计思路。通过构建完整的系统原型,读者可以理解任务、调度器、管理节点和工作节点之间的协作关系,以及系统状态管理和资源调度的基本逻辑。这种从原理出发的学习方式,对于理解云原生技术体系具有重要价值。 译 者 序 近年来,随着云计算和容器技术的发展,应用系统的部署方式正在发生深刻变化。容器编排系统已经成为现代软件基础设施的重要组成部分。 Kubernetes 、Mesos 、Nomad 等系统广泛应用于互联网企业和云平台,但对很多开发者而言,这些系统往往规模庞大、结构复杂,理解其内部原理并非易事。 《从零构建编排器(Go语言)》一书提供了一条极具启发性的学习路径。作者没有从现有平台的使用方法入手,而是通过构建一个简化的编排系统,让读者逐步理解编排系统的核心机制。全书围绕一个名为 Cube 的示例系统展开,通过清晰的步骤实现任务调度、节点管理、任务运行及系统接口等关键功能,使读者能够从整体上理解编排系统的基本结构和工作方式。书中使用较为精简的代码实现这些功能,使复杂系统的核心思想得以直观呈现。 本书不仅介绍了编排系统的基本概念,更重要的是展示了现代基础设施软件的设计思路。通过构建完整的系统原型,读者可以理解任务、调度器、管理节点和工作节点之间的协作关系,以及系统状态管理和资源调度的基本逻辑。这种从原理出发的学习方式,对于理解云原生技术体系具有重要价值。 作为一名从事计算机教学二十余年的教师,我长期关注计算机系统与软件工程教育的发展。近年来,我的研究方向逐渐扩展到通用人工智能以及人工智能在医学领域的应用。在这些领域,大规模计算资源的管理和任务调度同样至关重要,而容器编排技术正是支撑这些系统运行的重要基础设施。因此,理解编排系统的基本原理,对于从事现代计算平台和智能系统研究的读者具有现实意义。 本书结构清晰,实践性强,适合具有一定编程基础并希望深入理解云原生基础设施的读者阅读。通过动手实现一个简化的编排系统,读者不仅可以理解相关技术原理,也能够体会复杂系统设计中的工程思维。希望本书能够帮助读者从更底层的角度理解现代软件基础设施的工作机制,并从学习和实践中获得启发。 最后,谨向清华大学出版社王军老师表示衷心感谢。多年来,他的支持与帮助使我得以翻译并出版多部机器学习、人工智能、云计算和高性能计算领域的著作,也让我有机会通过翻译这一方式与读者分享知识。 殷海英 埃尔赛贡多市,加利福尼亚州 2026年3月 致珍妮弗: 即便在我对自己失去信心时,你也始终对我满怀信任。 自 序 2007年,我加入谷歌时第一次接触到了编排器。当时,我接触的并不是Borg,而是Ganeti 。Ganeti是谷歌内部开发的集群管理系统,在虚拟机上运行。那时,它其实只是一个基于Xen开源版本的简单封装工具,提供了一个集群化的解决方案,使我们能够为工程师提供虚拟机器,而不是物理机器。 我们当时并没有把Ganeti称为编排器,也没有像谈论Borg那样深入讨论它。回过头看,我认为将Ganeti看作一种编排器其实并不为过。它不是操作任务(以容器形式),而是操作虚拟机。在谷歌内部,Ganeti起到了桥梁的作用,它帮助团队从部分工程师在物理机上运行应用的阶段,过渡到每位工程师都能在 Borg 上部署并运行应用的新阶段。 几年后,当我们重写了用于管理Ganeti集群和虚拟机的生命周期管理系统时,我才真正接触到Borg。我们将系统运行在Borg上。转眼到了2020年,新冠疫情暴发,像其他人一样,我开始居家办公。突然,我每天多出了三个多小时的工作时间,因为不再需要通勤到曼哈顿的办公室。那么,我该用这些时间做些什么呢? 显然,最直接的选择是启动一个个人项目。但做什么项目呢?鉴于已与编排器打了13年交道,我觉得从零开始写一个编排器应该是挺有趣的。这会有多难呢? 2020年夏天,我花了大量时间开发我的编排器。我把它命名为Cube,沿用《星际迷航》的主题。出乎意料的是,仅用了不到3000行代码,就让它成功运行了。 就在那时,我读了Thorsten Ball的《用Go语言编写解释器》 (Writing an Interpreter in Go)。虽然我并不特别对解释器或编程语言感兴趣,但我想了解它们是如何工作的。然后,我灵感一闪!我可以写一本关于用Go语言编写编排器的书。这本书就是我2007年时所希望拥有的那本书!于是,这本书应运而生。 在写作过程中,我很快意识到,编排是一个庞大的话题。在谈论编排系统时,很容易被次要问题分心。比如,如何处理服务发现?如何处理DNS?如何处理共识机制?我希望能避免所有这些附加的内容,专注于编排系统的核心——支撑所有其他功能的基础。并非说服务发现、DNS和负载均衡等内容不重要,但在编排系统的背景下,我们讨论这些问题是因为它们是为实现编排器的核心功能服务的:将应用调度到一组节点上运行,并管理它们的生命周期。 简而言之,本书的主要内容就是接收用户提交的运行应用的请求,找出一台能够运行该应用的机器,然后向该机器发送请求,启动应用。听起来很简单,是不是? 除了介绍编排系统的基础概念,我写这本书的另一个目标是让它惠及更广泛的读者群体。所以,虽然我选择用Go语言编写Cube编排器,但我希望即使你从未写过Go代码,也能跟随本书一步步操作并使代码运行起来。本书中的代码使用的是Go的基本特性,其中使用了goroutine(Go语言的轻量级线程)来处理一些并发操作,但并没有使用通道(如果你感兴趣,有很多资源可供学习)。此外,本书也没有使用泛型(在Go 1.18发布后,我尝试过将代码重构,加入泛型。虽然最终让代码成功运行,但发现这为书籍增加了不必要的复杂性,反而成了一个需要解释的新内容,让书的内容变得冗杂)。 我希望你在阅读这本书时能感到愉悦,像我写作时一样,在享受过程的同时从中学到很多知识。 致 谢 生活中的许多事情都离不开他人相助,这本书的创作也不例外。 首先,我要感谢曼宁出版社的所有工作人员,有了他们的帮助,这本书才得以问世。特别感谢Andy Waldron,他接手了我的书稿,并在本书多次修改、完善的过程中始终支持我,给予我信心。Katie Sposato Johnson在本书的出版过程中发挥了重要作用,没有她的帮助,这本书恐难出版。我还要感谢曼宁出版社的其他团队成员,他们在书籍的制作和营销过程中提供了帮助。 我还要感谢在不同阶段阅读手稿并提供宝贵反馈意见的审稿人: Alain Lompo 、 Alessandro Campeis 、Andres Sacco 、Becky Huett 、Bobby Lin 、Christopher Villanueva 、 Clifford Thurber 、David Paccoud 、Emanuele Piccinelli 、Ernesto Bossi 、Fernando Bernardino 、 Fernando Rodrigues 、Geert Van Laethem 、Gregory Reshetniak 、Katia Patkin 、Kosmas Chatzimichalis 、Larry Cai 、Lucian Enache 、Madiha Khalid 、Matthias Busch 、Michael Bright 、 Muneeb Shaikh 、Nathan B. Crocker 、Nghia To 、Richard Vaughan 、Sanket Naik 、Simone Sguazza 、Thomas Dybdahl 、Timothy R. J. Langford 、Tim van Deurzen 和 Vamsi Krishna。 特别感谢技术校对员Mike Haller,他在书籍出版前仔细审查了代码。保持书中的代码与源代码一致是一项极具挑战的任务; Mike帮助我整理和修正了代码中的不一致之处,发挥了不可估量的作用。 前 言 本书旨在帮助你更好地理解编排系统的基本组成部分。无论你是DevOps工程师、站点可靠性工程师(SRE)还是软件工程师,今天的许多技术看起来都像一个“闷葫芦”:你只需要将应用部署到云端,神奇的事情就会发生。大家都知道,当这些神奇技术正常工作时,体验确实很棒!但当它出现故障时—而且它肯定会出现故障—这种“神秘感”就可能成为我们快速识别并解决问题的障碍。随着越来越多的开发者将应用迁移到云端,他们将在编排系统上运行这些应用(或者很快会这样做)。除非他们在配备专门DevOps或SRE团队的大公司工作,否则他们很可能需要亲自部署和管理应用,其中也包括处理运行时出现的问题。本书的目标是帮助你驱散应用在编排器上运行时的神秘感。 目标读者 本书既适合那些负责部署和维护编排系统的人员(比如DevOps工程师和SRE),也适合那些负责在编排系统上部署和管理应用程序的开发人员(比如软件工程师)。如果你想了解编排器是如何工作的,可以阅读Kubernetes或Nomad的源代码,这两个开源项目都可以在GitHub上找到。Kubernetes的代码超过200万行,全部用Go语言编写;而Nomad的代码量虽然少一些,但也有50万行以上。说实话,我自己也不太理解如何从50万行代码中获得有效信息,更不用说200万行代码了。 本书结构 本书分为5部分,共13章。第Ⅰ部分介绍了Cube编排器的思维模型,并搭建了一个贯穿全书实现过程的基础代码框架。 ● 第 1 章简要说明了编排系统的用途,并介绍了Cube 编排器的思维模型,Cube 是本书将要实现的编排器。 ● 第 2 章基于第 1 章中的思维模型,为 Cube 编排器的核心概念构建代码框架。 ● 第 3 章通过详细实现 Task 对象的代码,展示了如何在这个基础框架上扩展和完善功能。 第Ⅱ部分实现了工作节点组件所需的概念。 ● 第 4 章详细介绍了Worker 对象的实现过程。 ● 第 5 章为 Worker 对象构建了 API。 ● 第 6 章设计了一个框架,使工作节点能够展示自身状态和所运行任务状态的监控数据。第Ⅲ部分实现了管理器组件所需的概念。 ● 第 7 章详细介绍了 Manager 对象的实现过程。 ● 第 8 章为 Manager 对象构建了 API。 ● 第 9 章探讨了故障场景,并实现了相关的解决方案。 第Ⅳ部分指导读者重构初期实现的两个组件。 ● 第 10 章介绍了调度器接口,并实现了一种更复杂的调度算法。 ● 第 11 章设计并构建了存储接口,使得管理器和工作节点组件能够将任务数据保存在内存中或持久化存储到数据库中。 第Ⅴ部分实现了一个命令行接口(CLI),方便读者操作编排器。 ● 第 12 章构建了一个 CLI,支持启动管理器和工作节点、启动和停止任务,并查询系统中任务的状态。 ● 第 13 章总结了本书的内容,并提供了一些后续的学习建议。关于代码 本书包含许多源代码示例,这些示例既以带编号的代码清单的形式呈现,也会穿插在正文段落中。无论哪种形式,源代码都使用等宽字体格式,以便与普通文本区分开来。有时,代码也会以粗体显示,用来强调与本章前文步骤中的代码有所不同的部分,例如添加新功能到现有代码行时。 在许多情况下,本书对原始源代码格式进行了调整,增加了换行符,并调整了缩进,以适应本书页面的排版空间。在极少数情况下,即使这样调整仍无法满足排版需求,代码清单中还会加入行连接符()。此外,当代码内容已在正文中有详细说明时,源代码中的注释通常会被省略。许多代码清单还配有注释,帮助强调重要概念。 书中所有示例的完整代码可以从GitHub上获取,网址如下: https://github. com/buildorchestratoringo/code。也可以扫右侧二维码获取。 关于本书封面 本书封面上的插图名为《巴什基尔女人》(Femme Baschkirienne),选自雅克 · 格拉塞 ·德 ·圣索韦尔(Jacques Grasset de Saint-Sauveur)于1788年出版的作品集。这幅插图经过了精细的手工绘制和上色处理。 在那个时代,人们仅凭衣着就能轻易分辨出一个人的居住地、职业或社会地位。曼宁出版社通过这种封面设计,展示了几百年前地区文化的丰富多元性,并通过这些珍贵藏品插图让昔日的文化风貌重焕生机,彰显了计算机行业的创造力与开创精神。 作 者 简 介 蒂姆 · 博林是一位拥有20多年行业经验的软件工程师。在其职业生涯的大部分时间里,他一直是编排系统的实际使用者,所接触的系统包括Borg 、Kubernetes和Nomad等。 蒂姆·博林是一位拥有20多年行业经验的软件工程师。在其职业生涯的大部分时间里,他一直是编排系统的实际使用者,所接触的系统包括Borg、Kubernetes和Nomad。 目 录 第1章 编排器概述 2 1.1 为什么从零开始实现一个编排器 2 1.2 苦乐参半的往日时光 3 1.3 什么是容器,它与虚拟机有何不同 4 1.4 什么是编排器 6 1.5 编排系统的组件 6 1.5.1 任务 7 1.5.2 作业 7 1.5.3 调度器 8 1.5.4 管理器 8 1.5.5 工作节点 8 1.5.6 集群 9 1.5.7 命令行接口 9 1.6 认识Cube 11 1.7 本书将使用哪些工具 12 1.8 关于硬件 13 1.9 本书未涉及的内容 15 1.9.1 分布式计算 15 1.9.2 服务发现 15 1.9.3 高可用性 15 1.9.4 负载均衡 16 1.9.5 安全性 17 本章小结 17 第2章 从思维模型到基础代码 18 2.1 任务框架 20 2.2 工作节点框架 22 2.3 管理器框架 24 2.4 调度器框架 25 2.5 其他框架 26 2.6 让框架运转起来 27 本章小结 30 第3章 为任务框架补充细节 31 3.1 Docker:通过命令行启动、停止和检查容器 32 3.2 Docker:通过API启动、停止和检查容器 34 3.3 任务配置 36 3.4 启动和停止任务 37 本章小结 44 第4章 Cube的工作节点们,团结起来 47 4.1 Cube的工作节点 47 4.2 任务与Docker 50 4.3 队列的作用 50 4.4 数据库的作用 51 4.5 计数任务 51 4.6 实现工作节点的方法 51 4.6.1 实现StopTask方法 52 4.6.2 实现StartTask方法 53 4.6.3 关于任务状态的插曲 54 4.6.4 实现RunTask方法 57 4.7 整合所有内容 58 本章小结 60 第5章 工作节点的API 61 5.1 工作节点API概述 62 5.2 数据格式、请求与响应 63 5.3 API结构体 65 5.4 处理请求 66 5.5 提供API 69 5.6 整合所有内容 70 本章小结 75 第6章 指标 76 6.1 应该收集哪些指标数据 77 6.2 从/proc文件系统获取的指标数据 78 6.3 使用goprocinfo收集指标数据 80 6.4 在API上暴露指标数据 84 6.5 整合所有内容 86 本章小结 88 第7章 管理器的引入 90 7.1 Cube管理器 91 7.2 Manager结构体 92 7.3 实现管理器的方法 93 7.3.1 实现SelectWorker方法 93 7.3.2 实现SendWork方法 95 7.3.3 实现UpdateTasks方法 96 7.3.4 向管理器添加任务 98 7.3.5 创建管理器 98 7.4 故障与弹性能力的讨论 99 7.5 整合所有内容 99 本章小结 104 第8章 管理器的 API 105 8.1 管理器API概述 105 8.2 路由 106 8.3 数据格式、请求和响应 107 8.4 API结构体 108 8.5 处理请求 109 8.6 提供API服务 111 8.7 提升便利性的几项重构 112 8.8 整合所有内容 113 本章小结 118 第9章 可能出现的问题 119 9.1 新场景概述 119 9.2 故障场景 120 9.2.1 应用启动失败 120 9.2.2 应用程序错误 121 9.2.3 资源问题导致的任务启动失败 121 9.2.4 Docker守护进程崩溃和重启导致的任务失败 121 9.2.5 机器崩溃和重启导致的任务失败 122 9.2.6 工作节点故障 122 9.2.7 管理器故障 122 9.3 恢复选项 122 9.3.1 从应用故障中恢复 123 9.3.2 从环境故障中恢复 123 9.3.3 从任务级故障中恢复 123 9.3.4 从工作节点故障中恢复 124 9.3.5 从管理器故障中恢复 125 9.4 实现健康检查 126 9.4.1 检查工作节点上的任务 126 9.4.2 在工作节点上实现任务更新 128 9.4.3 健康检查与重启 129 9.5 整合所有内容 133 本章小结 138 第10章 实现一个更复杂的调度器 140 10.1 调度问题 140 10.2 调度时应考虑的事项 141 10.3 调度器接口 141 10.4 将轮询调度器适配到调度器接口 143 10.5 使用新的调度器接口 145 10.5.1 向Manager结构体添加新字段 145 10.5.2 修改New帮助函数 146 10.5.3 修改管理器的多个方法 147 10.6 你注意到这个bug了吗 149 10.7 整合所有内容 150 10.8 E-PVM调度器 153 10.8.1 相关理论 153 10.8.2 实践中的应用 154 10.9 完成 Node 实现 158 10.10 使用E-PVM调度器 161 本章小结 162 第11章 实现任务的持久化存储 163 11.1 存储问题 163 11.2 Store接口 164 11.3 实现任务的内存存储 166 11.4 实现任务事件的内存存储 168 11.5 重构管理器以使用新的内存存储 169 11.6 重构工作节点 174 11.7 整合所有内容 178 11.8 引入BoltDB 179 11.9 实现持久化任务存储 180 11.10 实现持久化任务事件存储 184 11.11 将内存存储替换为持久化存储 187 本章小结 188 第12章 构建命令行接口 190 12.1 CLI的核心组件 191 12.2 引入Cobra框架 192 12.3 设置Cobra应用程序 192 12.4 理解新的main.go 193 12.5 理解root.go 193 12.6 实现worker命令 195 12.7 实现manager命令 200 12.8 实现run命令 203 12.9 实现stop命令 208 12.10 实现status命令 210 12.11 实现node命令 212 本章小结 215 第13章 展望未来 216 13.1 参与Kubernetes及相关工具的开发 216 13.2 管理器-工作节点模式与工作流系统 217 13.3 管理器-工作节点模式与集成系统 217 13.4 结束语 218 附录 环境设置 219
你还可能感兴趣
我要评论
|

新书资讯




