02-1-kubernetes模型设计
1. 通用对象设计原则
kubernetes 对所有对象进行了抽象,其设计原则如下:
- kubernetes将业务模型化,所有对象的操作都是通过API的形式发布出来,并且所有的API都是声明式的
- 所有对象之间是可以互相组合,而不是简单的封装
- 控制器的操作是幂等的,所有的操作都是朝着用户期望的状态逼近
- API对象的状态不能依赖于网络连接状态,因为分布式系统下网络可能会抖动
- 避免操作机制依赖于全局状态
2. 模型设计
2.1. TypeMeta
TypeMeta定义了资源类型,有以下几个字段:
- Kind:定义对象的具体类型,如Deploymen,Job,Pod等
- Group:资源对象组,即对资源对象进行分类,方便管理
- Version:API 版本,随着版本的迭代,资源对象的版本会从v1aplpha1到v1beta1再到v1
2.2. Metadata
Metadata定义具体资源对象的实例,在k8s中,资源对象根据作用域分为Namespace级别和Cluster级别,对于Namespace级别对象,可以通过Namespace进行隔离。
- Namespace 定义了资源对象所属名称空间,是一种逻辑隔离。
- Name 定义了资源对象的具体名称
- SelfLink 说明了当前资源对象的访问路径,kuberenets会自动生成
- Label 定义了当前对象的一些自定义属性,通过label selector 进行筛选,是得对象之间的关联关系变得更加解耦,如RC通过Label通过Label管理一组Pod, SVC 通过label将流量转发到一组Pod上
- Annotation 用于扩展label的功能,常用于Prometheus监控指标采集
- Finalizer 用于避免资源对象泄露,删除资源时会检查该字段是否为空,如果为空则立刻删除,否则等待其它程序将该字段置为空。因此无法删除Namespace时,需要将该字段置为空
- ResourceVersion 资源版本管理,避免多进程操作资源时发生冲突,当资源处理器(通常为controller)处理资源后,如果需要更新资源清单,则对该字段进行+1操作后发送给apiserver,只有集群中该对象的版本低于控制器发来的版本时,apiserver 才会接受更新。
- Spec 用于期望状态
- Status 当前资源状态
3. 控制器模式
api server 用于保存和查看资源对象的状态,这些资源对象的处理逻辑时由控制器实现的,控制器调用两个核心接口:Informer() 和 Lister() 接口。前者用于声明需要关注的事件类型和对应处理函数,后者用于查看资源列表。
控制器启动后,Informer会监听关注的对象变化事件,一旦关注的对象出现了创建、更新、删除等事件,这些事件会由核心组件API Server推送给控制器,控制器会将对象保存在本地缓存中,并将对象的主键发送给消息队列中。
控制器中的worker线程会从消息队列中获取主键,并从缓存中读取完整的状态,进行相关处理,并将最终的状态回写至API Server
从广义上来说,controller-manager,scheduler,kubelet 都是控制器,因为它们的处理逻辑和控制器类似,都是监听API资源变化,然后处理对象,回写状态到APIServer