继续上文未完的内容
3、控制器模式
在说Kubernetes的控制器模式之前,我们先看看软件架构中十分常见的MVC模式,即Model(模型)、View(视图)、Controller(控制器)。
* 模型(Model)
用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。“ Model ”有对数据直接访问的权力,例如对数据库的访问。“Model”不依赖“View”和“Controller”,也就是说, Model 不关心它会被如何显示或是如何被操作。但是 Model 中数据的变化一般会通过一种刷新机制被公布。为了实现这种机制,那些用于监视此 Model 的 View 必须事先在此 Model 上注册,从而,View 可以了解在数据 Model 上发生的改变。(比如:观察者模式(软件设计模式))
* 视图(View)
能够实现数据有目的的显示(理论上,这不是必需的)。在 View 中一般没有程序上的逻辑。为了实现 View 上的刷新功能,View 需要访问它监视的数据模型(Model),因此应该事先在被它监视的数据那里注册。
* 控制器(Controller)
起到不同层面间的组织作用,用于控制应用程序的流程。它处理事件并作出响应。“事件”包括用户的行为和数据 Model 上的改变。
MVC 模式强调职责分离,即视图和数据模型的分离,并利用控制器来作为这两者的逻辑控制的中介,使之具有逻辑复用、松散耦合等优点。
数据模型(Model),它描述了“应用程序是什么”,用于封装和保存应用程序的数据,同时定义操控和处理该数据的逻辑和运算。而且,Model通常是可以复用的。
一个良好的MVC应用程序应该将所有重要的数据都封装到Model中,而应用程序在将持久化的数据(文件、数据库)加载到内存中时,也应该保存在Model中。
因为Model本身就代表着业务的特定数据对象,而在k8s里面,典型的Model就是Pod。
视图(View),它是展现给用户的界面,这个不用多说。这个在k8s的应用不多,例如kubectl的信息输出或者Dashbord等,都可以算是一种View的应用。
控制器(Controller),它充当View和Model的媒介,将模型和视图绑定在一起,包括处理用户的配置输入,以此修改Model。反过来,View需要知道Model中数据的变化,也是通过Controller来完成。除此之外,Controller还可以为应用程序协调任务,管理其它对象的生命周期。在k8s里面,典型的Controller就是Deployment。
在上文中我们提到了k8s拥有很多API对象,而其中一部分是属于控制器类型的特殊对象,我们可以进入k8s的代码目录:kubernetes/pkg/controller/*,查看所有控制机类型的API对象,包含:deployment\job\namespace\replicaset\cronjob\serviceaccount\volume 等等。
由于k8s的架构体系中,View不算是其核心的功能模块,我们这里重点关注Controller和Model的关系,代入k8s对象的话,我们以典型的Deployment和Pod的关系,作为主要的研究对象。
我们回头看看文章连载前面的 Deployment 的yaml配置文件样例,可以划分为两大部分进行分析,配置文件的上半部分是属于控制器,下半部分是数据模型:
其实要深究起来,Deployment不是直接控制Pod,而是通过一个叫ReplicaSet的对象对Pod进行编排控制,所在在Pod的matadata里面会显示其 owerReference是ReplicaSet。
也就是说在控制器对象的范围内,也会进行功能的分层,因为不同的控制机之间,存在着可以复用的功能逻辑,比如对Pod的副本数控制。
那么这时候可以抽象出一层例如像ReplicaSet的对象,进行对Pod的副本控制,除了Deployment以外,也存在其他的控制器对象可以利用ReplicaSet进行对Model的控制。
基于这样的分层思想,我们在生产环境场景的所遇到的需求,可以将其控制逻辑都在控制器这一层进行实现。
比如无状态的Deployment和有状态的StatefuleSet,或者每个Node只有一个DeamonSet,尽管各自实现的功能各不相同,但是它们都是可以共用同一套Pod对象的逻辑,而差异的部分都封装在控制器层。