Kubernetes和数据库相似之处是因为它是声明式应用程序管理的基础知识
在这篇文章中,阿里巴巴云的员工工程师、Kubernetes的维护者张磊先生提到了Kubernetes与数据库相似之处的想法。
最近,Kubernetes社区对于“Kubernetes是一个新型数据库”的主张引起了关注。准确地说,这个主张并不是指Kubernetes作为一个数据库来使用,而是指Kubernetes本身能像数据库一样发挥功能。

一开始,可能会觉得将Kubernetes与数据库进行比较有些奇怪。毕竟,Kubernetes的工作原理,如控制器模式和声明式API,似乎与“数据库”这一概念没有直接关系。然而,在这里,我们揭示了可以追溯到Kubernetes最基本理论的本质。
在Kubernetes中宣言式应用程序管理的基础知识
当涉及到Kubernetes的讨论时,常常会提到“声明式应用程序管理”的概念。这个概念不仅是区分Kubernetes与其他基础设施项目的设计特征,也是Kubernetes的独特功能之一。那么,在Kubernetes中,什么是声明式应用程序管理呢?
宣言式应用程序管理不仅仅是“声明式API”。
根据Kubernetes的核心工作原理,kubelet负责执行容器、kube-proxy负责执行iptables规则、kube-scheduler负责调度Pod、Deployment负责管理ReplicaSet等,大多数Kubernetes的功能都遵循了我们之前强调的控制器模式。换句话说,当用户在YAML文件中声明期望的状态时,Kubernetes的各个组件会将整个集群的状态接近用户所声明的期望状态,并最终实现相同状态。因此,实际状态逐渐接近期望状态的过程被称为”Reconciliation(协调)”。这一原则也适用于Kubernetes Operators和自定义控制器。
通过声明性的描述,控制器可以调整两种状态的方法是最直观地体现声明性应用程序管理的方式。值得注意的是,这个过程有两个含义。
希望达到的宣言状态是指该描述必须是用户所期望的最终状态。如果在该描述中使用了中间状态,或者希望动态地调整这一理想状态,那么这种声明性语义将无法精确执行。
基于和解的状态逼近:为了使系统的实际状态与期望的状态保持一致,进行了调整过程。具体而言,调解过程通过持续进行“检查-差异-执行”的循环,始终能够处理系统的实际状态与期望状态之间的差异。换句话说,仅仅依靠声明性描述是不够的。因为在提交描述时,系统已经实现了期望状态。然而,一小时后并不一定如此。许多人将声明式应用管理和声明式API混淆,这是因为他们没有正确理解和解的必要性。
你是否好奇这个声明式应用程序管理系统为Kubernetes带来了什么好处?
宣言型应用程序管理的本质就是将基础设施作为数据进行处理。
基于原始程序的应用管理系统的理论基础是被称为“基础设施即数据(IaD)”的概念。根据这个概念,基础设施管理不应该与特定的编程语言或配置方法绑定,而应该依赖于能够完全表达用户期望系统状态的纯净格式的可读系统数据。
注意:基础设施即数据也被称为配置即数据。
该优点在于针对基础设施的任何操作最终都等同于对数据进行CURD(创建、更新、检索和删除)操作。更重要的是,关于如何“创建、更新、检索、删除”数据的方法与基础设施本身无关。因此,与基础设施进行交互不会受限于编程语言、远程调用协议、软件开发工具包(SDK)等。只要能生成相应格式的“数据”,就可以对基础设施进行任意操作。
关于Kubernetes,如果想要在Kubernetes上进行操作,不需要使用Kubernetes的RESTful API或SDK,只需发送YAML文件并对该文件进行CURD操作。需要注意的是,YAML文件的内容应与IaD系统或Kubernetes的数据相对应。
Kubernetes从成立之初就将所有功能定义为”API对象”,即作为数据片段进行定义。Kubernetes用户可以通过对这些数据进行CURD操作,无需受到特定编程语言或SDK的限制,可以自由地实现他们想要的功能。更重要的是,与独立的命令型API或SDK相比,基于YAML的声明性数据可以更轻松地对底层实现进行保护,从而便于与现有的基础设施功能进行连接和集成。这也是Kubernetes生态系统迅速繁荣的秘密武器。通过声明性API和控制器模式,整个社区都积极参与编写适用于Kubernetes的插件,并集成各种功能。此外,这些插件和功能非常通用和可移植。这些优势是其他项目如Mesos和OpenStack所无法获得的。可以说,声明性API和控制器模式是Kubernetes实现”平台中的平台”目标的核心竞争力。
那么,在IaD设计中,所谓的数据就是指Kubernetes中声明式API对象,Kubernetes的控制循环确保系统能够始终与由该数据描述的状态保持一致。从这个角度来看,Kubernetes本质上是将系统配置值表示为数据,并通过控制器的操作来维护配置值与数据的一致性的调整系统。
你对于“保持与系统设置值的一致性”这个理论有没有听过?
如果你是从工程师背景出身的人,可能会在一门叫做控制理论的课程中学习过Kubernetes的基础知识。

学习了Kubernetes的要点后,或许可以更容易地理解Kubernetes的运作方式。
例如,使用Kubernetes编写许多YAML文件是因为Kubernetes需要一种将数据发送到控制系统的方法。在这个过程中,YAML只是用来编写格式化数据的载体。
现在,你可能会想知道,为了让Kubernetes能够轻松分析和处理这种数据,是否有特定的“格式”存在于数据中。这种格式在Kubernetes中被称为API对象模式。经常编写自定义控制器的人可能已经深入了解了这个模式。CRD是用于定义此模式的特殊API对象。
YAML与数据库比较
IaD认为Kubernetes不像传统的分布式系统那样操作,而更像一个数据库。这也是Kubernetes学习曲线陡峭的根本原因之一。
从这个角度来看,Kubernetes公开的API对象是具有预定义模式的表格。我们编写YAML文件来对这些表的数据进行CURD操作。与SQL类似,YAML是用来操作数据库内数据的工具和载体。Kubernetes与传统数据库的唯一区别在于,Kubernetes不持久化获取的数据,而是利用数据驱动控制器进行操作,逐步调整系统状态以匹配数据所声明的最终状态。现在,让我们回到之前提到的”控制理论”。
在Kubernetes中,整个系统都是以”数据”为基础。因此,对于Kubernetes工程师来说,编写和执行YAML文件几乎成为了日常工作的唯一事务。然而,在本文中学习了IaD之后,你可以自称为”数据库工程师”,这比”YAML工程师”更为适当。
Kubernetes的”视图层”
当以“数据库”为视角重新审视Kubernetes的设计时,我们能更深入地理解背后的许多原创理念。例如,下列几个方面:
-
- データモデル:APIオブジェクトとKubernetesのCRD(Custom Resource Definition)の仕組み
-
- データの傍受、検証、修正の仕組み:Kubernetesのアドミッションフック
-
- データ駆動型の実行0のメカニズム:Kubernetesのコントローラとオペレータ
- データ変更の監視とインデックスのメカニズム:Kubernetesのインフォーマー
随着Kubernetes基础设施日益复杂化,第三方插件和功能的增加,Kubernetes社区开始意识到数据表在规模和复杂性上都急剧增加,这些数据表被实际集成到了Kubernetes内部。因此,Kubernetes社区一直在讨论如何设计Kubernetes的”数据视图”。
CREATE VIEW <Native Kubernetes object> AS <View-layer object of Kubernetes>;
在基于Kubernetes API资源构建的”视图层”的优点类似于数据库的”视图”。例如,下面是一些例子。
1)数据格式和表示的简化和修改
Kubernetes的视图层可以向开发者和操作员提供简化和抽象化的应用层API对象,而不是基础设施层的原始API对象。用户可以自由定义视图层对象,而不受基础Kubernetes对象模式的限制。
2)简化复杂数据操作(简化SQL)
抽象化的视图层对象需要更简化的用户界面,并且需要定义和管理Kubernetes中复杂的API资源拓扑结构。这样可以减轻在管理Kubernetes应用程序时的复杂性和负担。
3) 基于数据表的保护
由于开发人员和运营人员可以直接操作视图层的对象,因此Kubernetes的基础对象得到保护。这样一来,Kubernetes的基础对象可以在用户察觉不到的情况下进行修改和升级。
4)重复使用数据操作(重复使用SQL)
视图层对象与基础架构完全分离,因此通过视图层对象声明的应用程序和运营能力可以在整个Kubernetes集群中使用,与Kubernetes集群支持的能力无关。
5)对于视图的标准表操作支持
Kubernetes的视图对象必须是标准的Kubernetes对象,以便将API对象的所有操作和原始配对应用于视图对象。这样一来,可以避免给Kubernetes API模型的用户带来额外的心理负担。
尽管Kubernetes没有本地支持视图层的概念,但许多社区成员普遍认为视图层是常识。例如,Pinterest为了描述和定义Pinterest应用程序,开发了PinterestService CRD作为Kubernetes的一部分。这个CRD实际上就是视图层对象。然而,这种做法对大多数企业而言仍然太基础了。数据视图不仅仅是数据的抽象化和转换。要在实际生产环境中广泛使用视图层,必须解决以下重要问题。
1、您如何定义和管理视图层对象与基础Kubernetes对象之间的映射关系?请注意,这不仅仅是简单的一对一映射。一个视图层对象可能对应多个Kubernetes对象。
2、”运维能力”如何建模和抽象化?在实际应用中,通常使用简单的部署(Deployment)或者K8s操作器(Operator)。例如,一个容器化的应用程序和相应的扩展策略通常是以程序和与之对应的运维能力的组合形式存在。这些运维能力在应用程序中是如何定义的?是否可以将所有这些能力都定义为注解?
3、如何管理运维能力和程序之间的关联关系?在Kubernetes中,关联关系如何转化为实际的执行关系?
4、如何通过视图层对象来定义类似阿里云RDS实例这样的标准云资源?
上述问题是 Kubernetes 没有实现原生的“视图层”的原因之一,这也成为了像 OAM(Open Application Model)等开源项目中的一个重要关注点。需要注意的是,仅仅通过 OAM 的“规范”无法解决所有这些问题。为了确保用户能够真正享受到 Kubernetes 的“数据视图”带来的优势和便利,需要在实现层使用标准视图层的依赖库。目前,在社区中为 Kubernetes 视图层提供相当强大依赖库的是 OAM Kubernetes runtime 项目。
概述
基于IaD的数据库式Kubernetes设计,一方面支持了这个社区的繁荣和发展。然而,IaD也导致了无数个“独立的”控制器和运算器的出现,以及由这些控制器组装而成的复杂的Kubernetes集群。在生产环境中,具有如此复杂性的Kubernetes集群与开发者和运营者愿意接受的云原生应用管理平台相去甚远。
过去5年来,Kubernetes的成功归因于使用声明性API逐步标准化和统一基础设施功能(如网络、存储和容器等)。随着OAM等Kubernetes应用层技术的普及,标准应用层生态系统正在形成。同时,团队也越来越多地尝试通过更易用的数据视图层向终端用户公开API,并提供给基础架构工程师更强大的模块化水平连接的平台功能。
在另一方面,缺乏数据库类的Kubernetes的其他领域无疑将成为未来社区关注的领域。例如,迅速成熟的OPA(开放策略代理)项目可以被视为“数据拦截、验证和修正机制”的演化结果。此外,阿里巴巴在“1万节点”集群上进行的控制链路性能优化的理论依据和实践与数据库性能优化类似。
请务必在评论中提供对IaD的意见和反馈。
本博客是从英文版翻译而来的。您可以通过点击这里查看原文。我们使用了部分机器翻译。如果有任何错误的翻译,请您不吝指正,感激不尽。
阿里巴巴云拥有两个数据中心,在全球拥有超过60个可用区,是2019年亚太地区排名第一的云基础设施提供商(根据Gartner数据)。欲了解更多阿里巴巴云的详细信息,请点击此处访问阿里巴巴云日本官方页面。