前言
写在前面
Hello! 谢谢你愿意与我一起度过一段时光。
我并不是一个善于写作的人,生活中也会出现因为用错成语而引起误会的糗事。 写书对我来说是一件困难的事情,不管是章节编排,叙事顺序或者代码的难易程度,每一点都会影响到知识的传达和读者的阅读体验。 另外,我也只是一名普通的Kubernetes学习者,为了尽可能确保书中每一个论述都是正确可靠的,有时需要花费大量的时间从文档和源码中寻找答案。
但是即便如此,我总觉得把知识分享给需要的人是一件有意义的事情,哪怕可以帮助到一个人呢。生活总需要一点浪漫主义。
动机
如果你对Kubernetes自定义控制器(Custom Controller)有所了解, 你或许已经接触过像kubebuilder,operator-sdk 这些帮助你构建一个完备并且可用于生产的控制器框架1。然而这些框架对于刚接触自定义控制器的初学者来说过于庞大和复杂,想要透过它们去真正了解自定义控制器的原理是一件十分困难的事情。
本书将在不借助任何框架以及框架本身所依赖的库2和工具3的情况下,仅依赖k8s.io/apimachinery
以及k8s.io/client-go
这两个基础库
实现一个极为简单的自定义控制器。
我们希望这本书可以成为了解和实现Kubernetes自定义控制器的入门读物。另外我们也希望这本书可以作为kubebuilder的预备读物,但愿她能够帮助你更好地去理解
kubebuilder以及其他更上层的控制器框架。
同时,我们希望阅读完本书的读者对实现自定义控制器的基本步骤和所需的核心模块
有一个清晰的认知,这也是我们的初衷。
希望你始终怀揣着这个目的来阅读:对实现自定义控制器基本步骤和核心模块要有一个清晰的认知。
谁适合阅读本书
- 想要知道如何基于Go实现一个Kubernetes自定义控制器的初学者;
- 对Go语言有一定4基础;
- 了解Kubernetes5以及Kubernetes 自定义资源(Custom Resource)的相关概念6;
- 对client-go编程有一定7基础。
你还能从本书学到什么
- 与Kubernetes二次开发相关API术语的严格描述;
apimachiery
库中- 如何抽象Kubernetes API类型系统;
- 如何对Kubernetes资源序列化/反序列化;
client-go
库中- 基础组件
RESTClient
的用法和原理; Informer
组件的剖析;
- 基础组件
- 如何实现Kubernetes原生资源控制器。
本书结构
本书的最后一章才会正式介绍一个极简的自定义控制器的代码实现,在此之前的章节都可以算作是最后一章的铺垫。
具体来说,第一章和第二章我们会分别介绍apimachinery
库与client-go
库中涉及到实现控制器的理论知识和必要的组件,
第三章的定位是"putting it all together",我们不会对代码做任何讲解或者提供解释性的注释,你可以通过代码中的索引跳转到前两章中对应的知识点。
这样编排的目的是我们希望你进入最后一章时可以理解每行代码背后的意图,真正做到知其然知其所以然。
本书风格及约定
风格
本书的一个特点是"忠于文档"——本书出现的术语、概念以及论述会尽可能地给出官方引用。我们所说的官方引用来源有两处:我们所说的官方引用来源有两处: 一个是Kubernetes正式发布到kubernetes.io站点的文档或博客,另一个是仅收录在Kubernetes github community仓库中但未发布到站点的文档。 对于这两种文档来源我们会分别在引用处加上 "" 标记以及 "" 以作区分。
另外,为了阅读本书时思维的整体连贯性,同时也为了减轻读者的阅读负担, 我们不会过分追求Kubernetes源码细节,更不会对Kubernetes源码大段的走读。 我们所选取的所有内容都恰好可以用于实现我们最后所编写的控制器。 通俗地说,本书致力于解释"为这么要使用这个Kubernetes组件来实现控制器"以及"如何使用这个Kubernetes组件",而不是"死抠这个Kubernetes组件内部实现的细节"。
除此以外,对于特别复杂的知识体系,为了便于读者理解,我们甚至会根据它们对应的PR来介绍它们的历史和演化过程。
本书的定位更偏向于教程,我们采用一种我们认为合适的路线,希望能够循序渐进地引导读者去理解最后自定义控制器的实现。
约定
- 斜体:专有名词;
- 粗体:起强调作用;
- 🎈/🤖️标记:用🎈标记的知识或者论述表示与控制器的代码实现直接相关。🤖️仅会以注释的形式出现在第三章中控制器代码中,用于索引到前两章的知识点;
- 🌧️标记:对于没有官方文档支撑或者我们自己不够确定的论述会使用🌧️标记。
另外,本书中图示中出现的文字和代码中的注释都为英文。
与同类书籍的比较8
- 《Programming Kubernetes》by Michael Hausenblas, Stefan Schimanski, 2019
- 《Kubernetes Programming with Go: Programming Kubernetes Clients and Operators Using Go and the Kubernetes API》by Philippe Martin, 2023
这两本书中关于自定义控制器的部分仍然都是基于kubebuilder
框架,而我们将不会借助任何第三方框架教读者实现一个自定义控制器。
除此以外,上述两本书涵盖了许多与实现控制器本身无关的内容, 而对于本书来说,我们所引入的预备知识会尽量保持简洁,并不会面面俱到——这些内容恰好能够用于理解和实现最后编写的控制器。
总之,我们只专注于做一件事——教会读者仅依赖apimachinery
和client-go
库实现一个精简的自定义控制器。
局限
本书只聚焦于控制器本身的实现,如何使用CRD来扩展Kubernetes API(以及背后的原理)并不是本书要讨论的内容。 使用CRD来扩展Kubernetes API属于阅读本书需要掌握的预备知识。
其次,为了尽可能地追求控制器的简洁,导致了实现的控制器:
- 没有考虑CRD多版本情况;
- 没有defaulting/validating webhook;
另外,不同于kubebuilder等成熟框架,我们只专注于控制器本身逻辑的实现,本书并不提供配套的部署文件(包括role
、rolebindings
等)。
扩展阅读
下面列举了本书中所有非Kubernetes官方文档的引用:
- Kubernetes请求的生命周期
- 📖 Programming Kubernetes by Michael Hausenblas, Stefan Schimanski, Ch. 2, Ch. 4。
- Life of a Kubernetes API Request by Daniel Smith(a KubeCon talk)
- Kubernetes资源版本转化机制
- 声明式系统与命令式系统
- 📄 Imperative vs Declarative by Andrew Chen, Dominik Tornow, medium
- HTTP语境下的资源
- 📄 Identifying resources on the Web, mdn web docs
- 📖 RESTful Web Services by Leonard Richardson, Sam Ruby, Ch. 4.
- Kubernetes术语
- 📄 Difference between Kubernetes Objects and Resources, by Jordan Liggitt, stackoverflow
关于气球🎈
我们要实现一个简单的"气球🎈控制器🤖️",Kubernetes可以用它控制"气球🎈资源"(CRD)的释放。
+ 🎈 =- 你可以在这里 找到基于其他语言的控制器框架。↩
- 其实官方也提供了一个没有使用构建框架来实现的自定义控制器样例sample-controller。这个样例虽然相对来说比完全基于框架的控制器简单,但是它仍然依赖于kubebuilder的子项目controller-runtime。↩
- 我们甚至不借助Kubernetes的
client-gen
工具来生成Kubernetes API客户端的代码。↩ - 你应该知道书籍《The Go Programming Language》的1-10,12章所要表述的知识;你也应该知道Go modules的概念。↩
- 你应该知道书籍《Kubernetes in Action, edition 1》中前两部分(PART1,PART2)所要传达的知识;你需要了解Kubernetes集群的组成及架构;你也有使用kubectl工具管理Kubernetes集群的经验。↩
- 你应该知道什么是Kubernetes Custom Resources 以及如何使用CustomResourceDefinition来扩展Kubernetes API 。↩
- 你应该至少能理解这个使用
client-go
库的例子。↩ - 截止到目前,我们只找到两本包含实现自定义控制器内容的书籍。↩