目录

kubernetes处理node的命令详解

cordon、drain、delete node区别

cordon

drain 驱逐节点

delete 节点

kubectl delete node 详解

正常情况无node绑定关系

有绑定关系

总结


kubernetes处理node的命令详解

cordon、drain、delete node区别

主要目的:导致node处于不可调度状态,新创建的pod容器不会调度在node上。

cordon

  1. 将node置为SchedulingDisabled不可调度状态,后续的新创建pod容器时scheduler调度不会考虑该node
  2. 旧的pod容器不会正常受影响,仍可以对外提供正常服务。(特殊情况:pod容器如果跟node绑定的话,容器下次更新就不会回到原宿主机,该情况如何处理呢?可能设置成不可调度状态就不太合适。调度器 预调度策略)
  3. 恢复调度  kubectl uncordon node

drain 驱逐节点

  1. 设置该node为不可调度状态 cordon
  2. 驱逐node节点上pod,使其在其他节点上创建。gracefully terminate all pods
  3. 恢复调度 kubectl uncordon node

delete 节点

  1. delete node后 kubernetes集群管控端获取不到node信息。master节点删除该node,失去对其控制,master不可对其恢复
  2. 驱逐node上的pod容器。(如何驱赶呢?参考 https://blog.csdn.net/li_101357/article/details/89606269 ,主要是podGCcontroller来做这件事情)  疑问是:master删除node了,GC怎么删除呢?强制删除
  3. 恢复调度,需要进入node节点,重启kubelet即可

kubectl delete node 详解

正常情况无node绑定关系

kubectl delete node之后

日志显示delete node之后GC pod的过程

通过statefulapp controller直接自动拉起,并在其他的node上创建完毕。这种情况使用大多数,不关系pod容器IP是什么,只需要能够正常运行起来提供服务即可。

有绑定关系

1. 正常创建时,在scheduler模块发现该node被删,预调度策略匹配不上,导致容器pending状态。源码中sts创建pod:

2. (定制) 创建pod前,需要做一些其他工作(添加taint或者toleration),获取该node信息失败,导致都没有发出创建请求。

// processNextWorkItem dequeues items, processes them, and marks them done. It enforces that the syncHandler is never
// invoked concurrently with the same key.
func (ssc *StatefulSetController) processNextWorkItem() bool {
	key, quit := ssc.queue.Get()
	if quit {
		return false
	}
	defer ssc.queue.Done(key)
	if err := ssc.sync(key.(string)); err != nil {
        // 错误日志打印地方
		utilruntime.HandleError(fmt.Errorf("Error syncing StatefulSet %v, requeuing: %v", key.(string), err))
        // 重新入限速队列
		ssc.queue.AddRateLimited(key)
	} else {
		ssc.queue.Forget(key)
	}
	return true
}

对象键重新入限速队列。

// 队列初始化
queue:           workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "statefulset")

// 默认限速队列。  指数级增长的限速器 和 漏桶限速器,每次取两者限速器的最大值
func DefaultControllerRateLimiter() RateLimiter {
	return NewMaxOfRateLimiter(
		NewItemExponentialFailureRateLimiter(5*time.Millisecond, 1000*time.Second),
		// 10 qps, 100 bucket size.  This is only for retry speed and its only the overall factor (not per item)
		&BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
	)
}

所以对象键入队列之后,如果没有正常的时间更新发生,系统等待sync的时间会越来越长,导致最大是1000s。

就解释了,当你添加删除的node到集群中时,可能等待的时间最长是1000s,主要取决于上次什么时候开始进行同步的。

总结

分析完之后,也就明白了运维同学delete node之后自己的一系列疑惑。还是要多分析,多看源码,才能理解掌握的更到位!

Logo

开源、云原生的融合云平台

更多推荐