028.核心组件-API Server
木二 人气:2一 Kubernetes API Server原理
1.1 API Server功能
Kubernetes API Server的核心功能是提供Kubernetes各类资源对象(如Pod、RC、Service等)的增、删、改、查及Watch等HTTP Rest接口,成为集群内各个功能模块之间数据交互和通信的中心枢纽,是整个系统的数据总线和数据中心。同时还有以下一些功能特性。
- 是集群管理的API入口。
- 是资源配额控制的入口。
- 提供了完备的集群安全机制。
1.2 Kubernetes API Server概述
Kubernetes API Server通过一个名为kube-apiserver的进程提供服务,该进程运行在Master上。在默认情况下,kube-apiserver进程在本机的8080端口(对应参数--insecure-port=8080)提供REST服务。同时启动HTTPS安全端口(--secure-port=6443)来启动安全机制,加强RESTAPI访问的安全性。
通常可以通过命令行工具kubectl来与Kubernetes API Server交互,它们之间的接口是RESTful API。也可通过curl直接测试和验证Kubernetes API Server所提供的接口。
insecure-port非安全方式测试:
1 [root@k8smaster01 study]# curl localhost:8080/api #以JSON方式返回 2 [root@k8smaster01 study]# curl localhost:8080/api/v1 #查看Kubernetes API Server支持的资源对象种类 3 [root@k8smaster01 study]# curl localhost:8080/api/v1/pods 4 [root@k8smaster01 study]# curl localhost:8080/api/v1/services #分别查看集群对应资源列表
secure-port=6443安全方式测试:
1 [root@k8smaster01 study]# curl -k --cert /opt/k8s/work/admin.pem --key /opt/k8s/work/admin-key.pem https://172.24.8.71:6443/
1 [root@k8smaster01 study]# curl -k --cert /opt/k8s/work/admin.pem --key /opt/k8s/work/admin-key.pem https://172.24.8.71:6443/api/v1/pods
1 [root@k8smaster01 study]# curl -k --cert /opt/k8s/work/admin.pem --key /opt/k8s/work/admin-key.pem https://172.24.8.71:6443/api/v1/services
1.3 API Server架构解析
API Server的架构从上到下可以分为以下几层。
- API层:主要以REST方式提供各种API接口,除了有Kubernetes资源对象的CRUD和Watch等主要API,还有健康检查、UI、日志、性能指标等运维监控相关的API。
注意:Kubernetes从1.11版本开始废弃Heapster监控组件,转而使用Metrics Server提供Metrics API接口,进一步完善了自身的监控能力。
- 访问控制层:当客户端访问API接口时,访问控制层负责对用户身份鉴权,验明用户身份,核准用户对Kubernetes资源对象的访问权限,然后根据配置的各种资源访问许可逻辑(AdmissionControl),判断是否允许访问。
- 注册表层:Kubernetes把所有资源对象都保存在注册表(Registry)中,针对注册表中的各种资源对象都定义了:资源对象的类型、如何创建资源对象、如何转换资源的不同版本,以及如何将资源编码和解码为JSON或ProtoBuf格式进行存储。
- etcd数据库:用于持久化存储Kubernetes资源对象的KV数据库。etcd的watch API接口对于API Server来说至关重要,因为通过这个接口,API Server创新性地设计了List-Watch这种高性能的资源对象实时同步机制,使Kubernetes可以管理超大规模的集群,及时响应和快速处理集群中的各种事件。
本质上看,API Server与常见的MIS或ERP系统中的DAO模块类似,可以将主要处理逻辑视作对数据库表的CRUD操作。
如下以一个完整的Pod调度过程为例,对API Server的List-Watch机制进行说明。
Pod调度过程中的List-Watch机制:
首先,借助etcd提供的Watch API接口,API Server可以监听(Watch)在etcd上发生的数据操作事件,比如Pod创建事件、更新事件、删除事件等,在这些事件发生后,etcd会及时通知API Server。
如上图所示API Server与etcd之间的交互:当一个ReplicaSet对象被创建并被保存到etcd中后,etcd会立即发送一个对应的Create事件给API Server,与其类似的6、7、10、11箭头都是针对Pod的创建、更新事件的。
然后,为了让Kubernetes中的其他组件在不访问底层etcd数据库的情况下,也能及时获取资源对象的变化事件,API Server模仿etcd的Watch API接口提供了自己的Watch接口,从而,其他组件就能近乎实时地获取希望获取的任意资源对象的相关事件通知。
如上图所示controller-manager、scheduler、kublet等组件与API Server之间的3个标记有List-Watch的虚框表明了此过程。
提示:其他组件在监听希望获取的资源事件的时候,可以增加过滤条件,如上图List-Watch3为例,node1节点上的kubelet进程只希望获取自己节点上的Pod事件。
最后,Kubernetes List-Watch用于实现数据同步的代码逻辑。客户端首先调用API Server的List接口获取相关资源对象的全量数据并将其缓存到内存中,然后启动对应资源对象的Watch协程,在接收到Watch事件后,再根据事件的类型(比如新增、修改或删除)对内存中的全量资源对象列表做出相应的同步修改。
从实现上来看,这是一种全量结合增量的、高性能的、近乎实时的数据同步方式。
二 Kubernetes Proxy API
2.1 Proxy API介绍
Kubernetes API Server最主要的REST接口是资源对象的增、删、改、查接口,同时还提供了一类很特殊的REST接口:Kubernetes Proxy API接口。
这类接口的作用是代理REST请求,即Kubernetes API Server把收到的REST请求转发到某个Node上的kubelet守护进程的REST端口,由该kubelet进程负责响应。
Kubernetes Proxy API里关于Node的REST接口路径为/api/v1/proxy/nodes/{name},其中{name}为节点的名称或IP地址,包括以下几个具体接口:
/api/v1/proxy/nodes/{name}/pods/ #列出指定节点内所有Pod的信息
/api/v1/proxy/nodes/{name}/stats/ #列出指定节点内物理资源的统计信息
/api/v1/proxy/nodes/{name}/spec/ #列出指定节点的概要信息
三 集群模块之间的通信
3.1 通信概述
如下图所示,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对应的容器创建和启动逻辑;如果监听到Pod对象被删除,则删除本节点上相应的Pod容器;如果监听到修改Pod的信息,kubelet就会相应地修改本节点的Pod容器。
另一个交互场景是kube-controller-manager进程与API Server的交互。kube-controller-manager中的Node Controller模块通过API Server提供的Watch接口实时监控Node的信息,并做相应处理。
还有一个比较重要的交互场景是kube-scheduler与API Server的交互。Scheduler通过API Server的Watch接口监听到新建Pod副本的信息后,会检索所有符合该Pod要求的Node列表,开始执行Pod调度逻辑,在调度成功后将Pod绑定到目标节点上。
为了缓解集群各模块对API Server的访问压力,各功能模块都采用缓存机制来缓存数据。
各功能模块定时从API Server获取指定的资源对象信息(通过List-Watch方法),然后将这些信息保存到本地缓存中,功能模块在某些情况下不直接访问API Server,而是通过访问缓存数据来间接访问API Server。
加载全部内容