kubernetes中apiserver的设计无疑是复杂的,其自身内部就包含了三种角色的api服务,今天我们一起来臆测下其内部的设计,搞明白aggregator、apiserver、apiExtensionsServer(crd server)的设计精要
1.从web服务到web网关到CRD
apiserver还是蛮复杂的,今天我们只讨论其kube-aggregator/apiserver/apiextensions三者架构上的设计,而不关注诸如请求认证、准入控制、权限等等
1.1 最基础的REST服务
一个最基础的Rest服务通常会包括一个resource资源和一组HTTP请求的方法, 在kubernetes中被称为一个REST,其内部还内嵌了一个Store(可以理解为继承),其提供了针对某个具体资源的所有操作的集合,也就是我们常说的最终执行CRUD的具体操作的实现
1.2 Service
我们有了Rest就可以提供各种k8s中资源的管理,但是如果我要进行扩展呢,如果要支持一些外部的资源k8s中不存在, 最简单的方式肯定就是在外部独立一个服务了,由这个服务自己管理数据存储、变更、控制等等逻辑
1.3 APIAggregator
当通过外部服务来进行集群资源扩展的时候,针对这类资源我们如何集成到当前的apiserver中呢?为此k8s中设计了APIAggregator组件(其实APIAggreator组件还包括代理后端服务等功能),来实现外部服务的集成,这样开发人员不用修改k8s代码,也可以来自定义服务信息
1.4 一个服务的基本功能
一个基础的业务服务通常包含数据模型、控制逻辑、持久化存储、基础功能(认证、监控、日志等等)等等,为了要创建一个服务,我们通常需要如下操作(不包含设计阶段):1)选择合适的框架(完成基础功能) 2)定义数据模型 3)选择数据存储 4)编写业务控制逻辑, 这里面除了业务控制逻辑,其余部分在大多数情况下可能都是通用,比如框架、数据存储这些,那能不能简化下?来看大招CRD
1.5 CustomResourceDefinitions
CRD中文被称为自定义资源类型,其核心在k8s中提供数据模型定义、数据存储、基础功能,这样如果我们要扩展服务就只需要编写一个业务逻辑控制器即可, 我们思考下其场景
通常web请求的处理流程都是反序列化、验证字段、业务逻辑处理、数据存储,而在k8s中业务控制逻辑大多数由controller来进行,那为了支持CRD剩余工作肯定也是在k8s中完成的
在我们完成定义模型之后,k8s的crd模块需要进行对应资源REST的构建、验证、转换、存储等操作这些无疑都是耗费资源的,而且在apiserver这种数据总线上,由此可以发行CRD并不支持大规模的数据存储
1.6 CRD server
CRDServer主要就是负责CRD资源的管理,其会监听CRD资源的变更,并且为其创建对应的REST接口,完成对应的认证、转换、验证、存储等机制
2. ServerChan
ServerChan从设计上更类似一种责任链的模式,简单来说如果我处理不了该请求,我就交给下个人处理,这种操作在k8s中被称为delegate(委托),接下来我们开始了解其关键实现
2.1 服务的角色划分
到目前我们已经有了三个server, 其中APIAggregator负责外部服务的集成和内部请求的转发,apiserver服务k8s汇总内部资源的控制,CRDServer则负责用户自定义资源的处理,然后我们就只需要将三者串联起来,就是我们最终的apiserver
2.2 责任链上的层层委托
当APIAggregator接收到请求之后,如果发现对应的是一个service的请求,则会直接转发到对应的服务上否则则委托给apiserver进行处理,apiserver中根据当前URL来选择对应的REST接口处理,如果未能找到对应的处理,则会交由CRD server处理, CRD server检测是否已经注册对应的CRD资源,如果注册就处理
2.3 APIAggregator上的服务注册
APIAggreagtor中会通过informer 监听后端Service的变化,如果发现有新的服务,就会创建对应的代理转发,从而实现对应的服务注册
2.4 CRD Server中的资源感知
当在集群中创建了对应的CRD资源的时候,会通过内部的controller来感知对应的CRD资源信息,然后为其创建对应的REST处理接口,这样后续接收到对应的资源就可以进行处理了
3. 基础概览图
读k8s代码总是这样迷迷糊糊中又能灵光一现直接柳暗花明,流程真的重要嘛,貌似也不是很重要,了解其上层设计,然后直接关注感兴趣点即可,除非和我一样就是感兴趣,那就只能死磕了,我该去吃饭了,祝你好运
来源:站长平台