控制器原理简介
Pod这个容器对象实际上是对容器的进一步抽象和封装。而控制器就是控制这些Pod,以让它们达到用户设定的期望状态。
我们以Deployment控制器为例简要说明。首先定义一个Deployment的YAML文件,如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
这个Deployment的YAML文件的功能就是确保labels为app:nginx的Pod永远运行2个副本,即.spec.selector.metchLabels和.spec.replicas定义的字段内容,这里定义的就是用户的期望状态。这也意味着,如果实际的运行状态小于期望状态,那么Kubernetes就会通过Controller Manager来增加Pod数量以达到我们的期望的状态。反之,如果Pod实际运行个数大于我们期望的个数,那么Kubernetes就会通过Controller Manager删除旧的Pod以让其数量符合我们期望的状态。
Deployment控制器只是所有控制器中的其中一种,还有其他的控制器比如:DaemonSet,ReplicaSet,Job,StatefulSet等。这些所有的控制器都会遵循Kubernetes通用的编排模式,即为控制循环(control loop)。其实现方法简述为一下伪代码:
for {
实际状态 := 获取集群中对象 X 的实际状态(Actual State)
期望状态 := 获取集群中对象 X 的期望状态(Desired State)
if 实际状态 == 期望状态{
什么都不做
} else {
执行编排动作,将实际状态调整为期望状态
}
}
简要说明:
(1)、实际状态就是Kubernetes集群中实际运行的状态,这些状态可以通过比如kubelet通过汇报的容器状态和节点状态,或者其他监控系统中保存的应用数据,或者控制器主动收集的一些集群信息等;
(2)、期望状态就是我们在模板中定义的状态,比如上面Deployment模板中定义的selector和replicas字段的数值,这些数值都是存储在Etcd中;
(3)、如果实际状态和期望状态相同,那么Controller Manager就不会做任何操作。反之,Controller Manager就会去执行一些编排操作,让实际状态成为期望状态;
这整个操作被称为调谐(Reconcile),这个调谐的过程被称为调谐循环(Reconcile Loop)或者同步循环(Sync Loop)。
控制器的设计原理
像Deployment这类控制器的设计原理就是用一种对象管理另一种对象的设计方法。其中,这个控制器本身负责管理被管理者的期望状态,而被控制字段主要来源于一个模板(template),而这个模板就是Pod的API对象的标准定义,所以这个模板也称为PodTemplate。
类似上面的Deployment对象,它由两部分组成,其中上半部分是控制器对象,主要用来定义期望状态等信息,下半部分是被控制对象定义,也就是Pod的定义。