apiserver 提供了对各类资源对象,如 Pod、Service、Deployment、CRD 等的增删改查,以及 Watch 的 API 接口,是整个集群的操作入口。

kube-apiserver 是 Kubernetes 最重要的核心组件之一,主要提供以下的功能

  • 提供集群管理的 REST API 接口,包括认证授权、数据校验以及集群状态变更等
  • 提供其他模块之间的数据交互和通信的枢纽(其他模块通过 API Server 查询或修改数据,只有 API Server 才直接操作 etcd)

kube-apiserver工作原理图

API 层

主要以REST方式提供各种API接口,除了有Kubenetes资源对象的CRUD和Watch等主要API,还有健康检查,UI,日志,性能指标等运维监控相关API。

访问控制层

当客户端访问API接口时,访问控制层负责对用户进行身份鉴权,验明用户身份,核准用户对Kubernetes资源对象的访问权限,然后根据配置的各种资源访问许可逻辑即Admission Control,判断是否允许访问。

 

认证

开启 TLS 时,所有的请求都需要首先认证。Kubernetes 支持多种认证机制,并支持同时开启多个认证插件(只要有一个认证通过即可)。如果认证成功,则用户的 username 会传入授权模块做进一步授权验证;而对于认证失败的请求则返回 HTTP 401。

Kubernetes 不直接管理用户

虽然 Kubernetes 认证和授权用到了 username,但 Kubernetes 并不直接管理用户,不能创建 user 对象,也不存储 username更多认证模块的

授权

认证之后的请求就到了授权模块。跟认证类似,Kubernetes 也支持多种授权机制,并支持同时开启多个授权插件(只要有一个验证通过即可)。如果授权成功,则用户的请求会发送到准入控制模块做进一步的请求验证;而对于授权失败的请求则返回 HTTP 403

准入控制

准入控制(Admission Control)用来对请求做进一步的验证或添加默认参数。不同于授权和认证只关心请求的用户和操作,准入控制还处理请求的内容,并且仅对创建、更新、删除或连接(如代理)等有效,而对读操作无效。准入控制也支持同时开启多个插件,它们依次调用,只有全部插件都通过的请求才可以放过进入系统

注册表层

Kubernetes把所有资源对象都保存在注册表(Registry)中,针对注册表中的各种资源对象都定义的:资源对象的类型,如何创建资源对象,如果转换资源的不同版本,以及如何将资源编码和解码为JSON或ProtoBuf格式进行存储。

etcd层

用于持久化存储Kubenetes资源对象的kv数据库,etcd的watch API接口对于API Server来说至关重要,因为通过这个接口,API Server创新性地设计了List-Watch这种高性能的资源对象实时同步机制,使得Kubernetes可以管理超大规模的集群,及时响应和快速处理集群中的各种事件。

访问控制

Kubernetes API 的每个请求都会经过多阶段的访问控制之后才会被接受,这包括认证、授权以及准入控制(Admission Control)等。

List Watch机制(API Server如何通知Node资源变更)

Pod调度过程中的List-Watch机制原理如下

首先,借助etcd的Watch API接口,API Server可以监听在etcd上发生的数据库操作事件,比如Pod创建事件,更新事件,删除事件等,在这些事件发生后,etcd会通知API Server,图中API Server与etcd之间的交互箭头表明了这个过程:当一个ReplicaSet对象被创建并保存etcd后,etcd会发送一个Create事件给API Server即箭头3,类似还有6,7,10,11。

然后,为了让Kubenetes中的其他组件在不访问底层etcd数据库的情况下,也能及时获取资源对象的变化事件,API Server模仿etcd的Watch API接口提供了自己的Watch接口,这样一来,这些组件就能近乎实时地获取它们感兴趣的资源对象的相关事件通知了。图中controller-manager,scheduler,kubelet等组件与API Server之间的0号箭头表明了这个过程。

最后,Kubenetes List-Watch用于实现数据同步代码逻辑。客户端首先调用API Server的List接口获取相关资源的全量数据并将其缓存到内存,然后启动对应资源对象的Watch协程,在接收到Watch事件后,再根据事件的类型(比如新增,删除或修改)对内存中的全量资源对象列表做出相应的同步修改,从实现上来说,这是一种全量结合增量的,高性能,近乎实时的数据同步方式。

集群功能模块之间通信

从Kubernetes结构图可以看出,Kubernetes API Server作为集群的核心,负责集群各功能模块之间的通信,集群内的各个功能模块通过API Server将信息存入etcd,当需要获取和操作这些数据时,则通过API Server提供的REST接口来实现(GET,LIST或WATCH),从而实现各个模块之间的信息交互。

 

常见的一个交互场景是kubelet进程与API Server的交互,每个Node上的kubelet每隔一个时间间隔就会调用一次API Server的REST接口报告自身状态,API Server在接收到这些信息后,会将节点状态信息更新到etcd中,此外,kubelet也通过API Server的Watch接口监听Pod信息,如果监听到新的Pod副本被调度绑定到该节点,则执行Pod对应的容器创建和启动逻辑。

Controller Manager也是通过API Server的Watch接口实时监控Node的信息,并做相应处理。

另外,Scheduler也是通过API Server的Watch接口监听到新建Pod副本的信息后,会检索所有符合该Pod要求的Node列表,开始执行调度逻辑,在调度成功后将Pod绑定到目标节点上,关于Scheduler我会另外写一篇文章专门介绍!

为了缓解集群各模块对API Server的访问压力,各功能模块都采用缓存机制来缓存数据,各功能模块通过List-watch机制定时从API Server获取指定的资源对象信息,然后把这些信息保存在本地缓存中,功能模块在某些情况下不直接访问API Server,而是通过访问缓存数据来间接访问API Server。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐