k8s驱逐篇(7)-kube-controller-manager驱逐-taintManager源码分析

概述

taintManager的主要功能为:当某个node被打上NoExecute污点后,其上面的pod如果不能容忍该污点,则taintManager将会驱逐这些pod,而新建的pod也需要容忍该污点才能调度到该node上;

通过kcm启动参数--enable-taint-manager来确定是否启动taintManagertrue时启动(启动参数默认值为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对象的NodeNameTolerations不相同)事件时,pod会进入该队列;
(5)nodeUpdateChannelsnodeUpdateChannels即8个nodeUpdateItem类型的channel,有worker负责消费nodeUpdateQueue队列,然后根据node name计算出index,把node放入其中1个nodeUpdateItem类型的channel中;
(6)podUpdateChannelspodUpdateChannels即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时,传入的workFuncdeletePodHandler函数,作用是删除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

NewNodeLifecycleControllerNodeLifecycleController的初始化函数,里面给taintManager注册了pod与node的EventHandlerAddUpdateDelete事件都会调用taintManagerPodUpdatedNodeUpdated方法来做处理;

// pkg/controller/nodelifecycle/node_lifecycle_controller.go
func NewNodeLifecycleController(
    ...
    podInformer.Informer().Ad
K8s驱逐是保障集群资源合理使用和节点健康的重要机制,以下从多个方面介绍相关知识: ### 驱逐相关内容概述 K8s驱逐相关内容主要包含k8s QoS与pod驱逐kubelet节点压力驱逐kube - scheduler抢占调度驱逐kube - controller - manager驱逐等方面。还涉及到相关的源码分析,如kube - scheduler抢占调度源码kube - controller - manager驱逐源码kube - controller - manager TaintManager源码等[^1]。 ### 不同组件的驱逐分析 - **kubelet节点压力驱逐**:当节点资源(如CPU、内存、磁盘等)达到一定压力阈值时,kubelet会根据节点压力情况对Pod进行驱逐操作,以保障节点的稳定运行。 - **kube - scheduler抢占调度驱逐**:当一个高优先级的Pod需要调度到某个节点,但该节点资源不足时,kube - scheduler会尝试驱逐该节点上低优先级的Pod,为高优先级Pod腾出资源。 - **kube - controller - manager驱逐**:在k8s v1.16版本中,NodeController分为了NodeIpamController与NodeLifecycleController,其中NodeLifecycleController驱逐方面发挥作用。例如,它会根据节点的状态和相关规则对Pod进行驱逐操作[^1][^3]。 ### Taint和Toleration与驱逐的关系 Taint有三种Effect: - **PreferNoSchedule**:不容忍该污点的Pod,调度器kube - scheduler会尽量避免把Pod调度到具有该污点的节点上,如果不能避免(如其他节点资源不足等),Pod也能调度到具有该污点的节点上,而已存在于具有该污点的节点上的Pod不会被驱逐- **NoSchedule**:不容忍该污点的Pod一定不会被调度到具有该污点的节点上,而已存在于具有该污点的节点上的Pod不会被驱逐- **NoExecute**:不容忍该污点的Pod一定不会被调度到具有该污点的节点上,同时会将已调度到该节点上但不容忍该污点的Pod驱逐掉[^4]。 ### 驱逐操作示例 在进行master驱逐、删除节点操作时,可以使用以下命令: ```bash kubectl drain k8s - node03 --delete - emptydir - data --force --ignore - daemonsets kubectl delete node k8s - node03 ``` 上述命令先将节点上的Pod驱逐,然后删除该节点[^2]。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值