控制器原理简介

Pod这个容器对象实际上是对容器的进一步抽象和封装。而控制器就是控制这些Pod,以让它们达到用户设定的期望状态。

我们以Deployment控制器为例简要说明。首先定义一个Deployment的YAML文件,如下:

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: nginx-deployment
  5. spec:
  6. selector:
  7. matchLabels:
  8. app: nginx
  9. replicas: 2
  10. template:
  11. metadata:
  12. labels:
  13. app: nginx
  14. spec:
  15. containers:
  16. - name: nginx
  17. image: nginx:1.7.9
  18. ports:
  19. - 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)。其实现方法简述为一下伪代码:

  1. for {
  2. 实际状态 := 获取集群中对象 X 的实际状态(Actual State
  3. 期望状态 := 获取集群中对象 X 的期望状态(Desired State
  4. if 实际状态 == 期望状态{
  5. 什么都不做
  6. } else {
  7. 执行编排动作,将实际状态调整为期望状态
  8. }
  9. }

简要说明:
(1)、实际状态就是Kubernetes集群中实际运行的状态,这些状态可以通过比如kubelet通过汇报的容器状态和节点状态,或者其他监控系统中保存的应用数据,或者控制器主动收集的一些集群信息等;
(2)、期望状态就是我们在模板中定义的状态,比如上面Deployment模板中定义的selector和replicas字段的数值,这些数值都是存储在Etcd中;
(3)、如果实际状态和期望状态相同,那么Controller Manager就不会做任何操作。反之,Controller Manager就会去执行一些编排操作,让实际状态成为期望状态;

这整个操作被称为调谐(Reconcile),这个调谐的过程被称为调谐循环(Reconcile Loop)或者同步循环(Sync Loop)。

控制器的设计原理

像Deployment这类控制器的设计原理就是用一种对象管理另一种对象的设计方法。其中,这个控制器本身负责管理被管理者的期望状态,而被控制字段主要来源于一个模板(template),而这个模板就是Pod的API对象的标准定义,所以这个模板也称为PodTemplate。

3、控制器 - 图1
类似上面的Deployment对象,它由两部分组成,其中上半部分是控制器对象,主要用来定义期望状态等信息,下半部分是被控制对象定义,也就是Pod的定义。