概述
taintManager的主要功能为:当某个node被打上NoExecute污点后,其上面的pod如果不能容忍该污点,则taintManager将会驱逐这些pod,而新建的pod也需要容忍该污点才能调度到该node上;
通过kcm启动参数--enable-taint-manager来确定是否启动taintManager,true时启动(启动参数默认值为true);
kcm启动参数--feature-gates=TaintBasedEvictions=xxx,默认值true,配合--enable-taint-manager共同作用,两者均为true,才会开启污点驱逐;
kcm污点驱逐
当node出现NoExecute污点时,判断node上的pod是否能容忍node的污点,不能容忍的pod,会被立即删除,能容忍所有污点的pod,则等待所有污点的容忍时间里最小值后,pod被删除;
源码分析
1.结构体分析
1.1 NoExecuteTaintManager结构体分析
NoExecuteTaintManager结构体为taintManager的主要结构体,其主要属性有:
(1)taintEvictionQueue:不能容忍node上NoExecute的污点的pod,会被加入到该队列中,然后pod会被删除;
(2)taintedNodes:记录了每个node的taint;
(3)nodeUpdateQueue:当node对象发生add、delete、update(新旧node对象的taint不相同)事件时,node会进入该队列;
(4)podUpdateQueue:当pod对象发生add、delete、update(新旧pod对象的NodeName或Tolerations不相同)事件时,pod会进入该队列;
(5)nodeUpdateChannels:nodeUpdateChannels即8个nodeUpdateItem类型的channel,有worker负责消费nodeUpdateQueue队列,然后根据node name计算出index,把node放入其中1个nodeUpdateItem类型的channel中;
(6)podUpdateChannels:podUpdateChannels即8个podUpdateItem类型的channel,有worker负责消费podUpdateQueue队列,然后根据pod的node name计算出index,把pod放入其中1个podUpdateItem类型的channel中;
// pkg/controller/nodelifecycle/scheduler/taint_manager.go
type NoExecuteTaintManager struct {
client clientset.Interface
recorder record.EventRecorder
getPod GetPodFunc
getNode GetNodeFunc
getPodsAssignedToNode GetPodsByNodeNameFunc
taintEvictionQueue *TimedWorkerQueue
// keeps a map from nodeName to all noExecute taints on that Node
taintedNodesLock sync.Mutex
taintedNodes map[string][]v1.Taint
nodeUpdateChannels []chan nodeUpdateItem
podUpdateChannels []chan podUpdateItem
nodeUpdateQueue workqueue.Interface
podUpdateQueue workqueue.Interface
}
1.2 taintEvictionQueue分析
taintEvictionQueue属性是一个TimedWorkerQueue类型的队列,调用tc.taintEvictionQueue.AddWork,会将pod添加到该队列中,会添加一个定时器,然后到期之后会自动执行workFunc,初始化taintEvictionQueue时,传入的workFunc是deletePodHandler函数,作用是删除pod;
所以进入taintEvictionQueue中的pod,会在设置好的时间,被删除;
1.3 pod.Spec.Tolerations分析
pod.Spec.Tolerations配置的是pod的污点容忍信息;
// vendor/k8s.io/api/core/v1/types.go
type Toleration struct {
Key string `json:"key,omitempty" protobuf:"bytes,1,opt,name=key"`
Operator TolerationOperator `json:"operator,omitempty" protobuf:"bytes,2,opt,name=operator,casttype=TolerationOperator"`
Value string `json:"value,omitempty" protobuf:"bytes,3,opt,name=value"`
Effect TaintEffect `json:"effect,omitempty" protobuf:"bytes,4,opt,name=effect,casttype=TaintEffect"`
TolerationSeconds *int64 `json:"tolerationSeconds,omitempty" protobuf:"varint,5,opt,name=tolerationSeconds"`
}
Tolerations的属性值解析如下:
(1)Key:匹配node污点的Key;
(2)Operator:表示Tolerations中Key与node污点的Key相同时,其Value与node污点的Value的关系,默认值Equal,代表相等,Exists则代表Tolerations中Key与node污点的Key相同即可,不用比较其Value值;
(3)Value:匹配node污点的Value;
(4)Effect:匹配node污点的Effect;
(5)TolerationSeconds:node污点容忍时间;
配置示例:
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
tolerationSeconds: 3600
上述配置表示如果该pod正在运行,同时一个匹配的污点被添加到其所在的node节点上,那么该pod还将继续在节点上运行3600秒,然后会被驱逐(如果在此之前其匹配的node污点被删除了,则该pod不会被驱逐);
2.初始化分析
2.1 NewNodeLifecycleController
NewNodeLifecycleController为NodeLifecycleController的初始化函数,里面给taintManager注册了pod与node的EventHandler,Add、Update、Delete事件都会调用taintManager的PodUpdated或NodeUpdated方法来做处理;
// pkg/controller/nodelifecycle/node_lifecycle_controller.go
func NewNodeLifecycleController(
...
podInformer.Informer().Ad

最低0.47元/天 解锁文章
1394

被折叠的 条评论
为什么被折叠?



