前言
本文主要会介绍笔者在学习Kubernetes DaemonSet Controller的实现原理时所总结的知识点,其中会涉及到DaemonSet Controller的实现原理、控制循环以及版本控制
等方面的相关内容。
笔者也会将自己的理解在文中进行阐述,这也算是在和大家交流心得的一个过程。若文中有错误的理解和概念,请大家及时纠正;吸纳大家的建议,对于我来说也是很重要的学习过程之一。
(目录)
1.相关概念
DaemonSet所创建的Pod对象会有以下几种特性:
-
Pod运行在Kubernetes集群里的
每一个节点(Node)上
-
每个节点上只有一个Pod对象
-
当有新的节点加入 Kubernetes 集群后,该
Pod会自动地在新节点上被创建
出来;而当旧节点被删除后,它上面的Pod也相应地会被自动回收掉
。
2.调度Pod
在Kubernetes v1.11 之前,由于调度器尚不完善,因此DaemonSet是由DaemonSet Controller自行调度的。实现方式为直接设置Pod的spec.nodename字段,这样就可以跳过调度器来直接调度相关Pod对象了。
在Kubernetes v1.11后
,DaemonSet则不再直接配置Pod对象的相关属性,而是通过设定nodeAffinity和tolerations来让相关的调度器来协助调度Pod
。
3.实现原理
3.1 保证Node上只运行一个Pod
DaemonSet Controller首先从API Server中获取所有的Node列表
,然后遍历所有的Node并检查每一个Node上是不是运行了一个携带了指定label的Pod对象
。
这里会出现以下几种情况:
-
没有查找到
相关Pod对象 则此时需要在这个Node上创建一个带有指定label的Pod。 -
查找到相关Pod对象
但不只一个
此时需要把多余的Pod对象从Node上删除掉,保证该Node上只运行一个此类Pod对象。 -
查找到相关Pod对象
且只有一个
则说明这个Node是正常的,无需任何操作。
Tips: DaemonSet实际上是利用了Kubernetes的label selector来实现上述功能。
3.2 保证Node上永远会被调度Pod
DaemonSet Controller会在创建Pod时自动在Pod对象里加上一个nodeAffinity定义。在nodeAffinity定义中会指定Pod所“亲近”的Node name。即DaemonSet Controller使用节点亲和性来保证为每一个Node上都分配了一个DaemonSet Pod
。
同时,DaemonSet Controller还会给Pod自动加上一系列的Tolerations,这些Tolerations定义了Pod能够容忍指定Node上的一些Taint。而这些Taint往往都是Node在发生一些异常情况时才会被添加上的污点。给Pod增加能够“容忍”这些“污点”就是要保证即使Node发生了异常,Kubernetes也能够不断的尝试往异常Node上调度和运行DaemonSet Pod,直到Pod成功在Node(Node恢复正常状态)上创建和运行。即DaemonSet Controller使用污点机制来保证每个Node上始终都会被调度一个DaemonSet Pod
。
Tips: DaemonSet Controller在向Kubernetes发起请求之前直接会去修改根据模板所创建的Pod对象,
即DaemonSet是直接操作Pod对象的
。
3.3 控制循环
DaemonSet的控制循环逻辑主体思路为:
-
检查每个Node 遍历所有Node,然后根据Node上是否有被管理Pod的情况来决定是否要创建或者删除一个Pod。
-
(可选)为Pod配置节点亲和性 在创建每个Pod的时候,DaemonSet Controller会自动给Pod加上一个nodeAffinity,从而保证这个 Pod只会在指定节点上启动。
-
(可选)为Pod配置污点容忍 在创建每个Pod的时候,DaemonSet Controller会自动给Pod加上一个Toleration,从而忽略Node的相关“污点”。
-
(可选)删除对于Pod 如果发现一个Node上运行了多个DaemonSet Pod,则删除多余的Pod。
4.版本控制
DaemonSet使用ControllerRevision对象来实现DaemonSet的版本管理控制
。
Tips: 更多关于ControllerRevision对象的知识可以参考笔者的另一篇文章。
每对现有的DaemonSet对象做一次PATCH操作(等价于执行一次 kubectl apply -f “旧的 DaemonSet 对象”),Kubernetes就会为其创建一个ControllerRevision对象并把修改前的DaemonSet对象整体定义记录到其中。