1 概述

1.1 版本

版本信息如下:
a、kubernetes版本:v1.30.11

1.2 一句话概述

被驱逐的状态显示Evicted的 Pod的DeletionTimestamp字段始终为空,因此pod对象永远走不进kubelet向kube-apiserver发送删除Pod请求的代码段。

2 简化代码分析

2.1 kubelet的eviction manager的evictPod( )

kubelet驱逐一个具体Pod的代码入口:

func (m *managerImpl) evictPod(pod *v1.Pod, gracePeriodOverride int64, evictMsg string, annotations map[string]string, condition *v1.PodCondition) bool {
	/*
		其他代码
	*/
	
	// killPodFunc函数只是去删除pod内所有容器、更新pod状态
	// 并不会去更新pod的metadata(DeletionTimestamp字段在这里)
	err := m.killPodFunc(pod, true, &gracePeriodOverride, func(status *v1.PodStatus) {
		status.Phase = v1.PodFailed
		status.Reason = Reason
		status.Message = evictMsg
		if condition != nil {
			podutil.UpdatePodCondition(status, condition)
		}
	})
	/*
		其他代码
	*/
	return true
}

killPodFunc( )函数只是去删除pod内所有容器、通过status manager组件去更新pod的status字段,并不会去更新pod的metadata(DeletionTimestamp字段在这里),因此被驱逐的Pod的DeletionTimestamp字段是一直是空

另外一方面,kubelet在源码中,只有两处会使用kube-apiserver client去执行删除Pod的请求,一处是关于mirror pod(在本文不关心此情景),另一处是status manager的syncPod( )。


2.2 kubelet的status manager的syncPod( )

kubelet的status manager的syncPod( )的代码如下,主要看该函数的末尾逻辑,进入不了if语句:

// syncPod syncs the given status with the API server. The caller must not hold the status lock.
func (m *manager) syncPod(uid types.UID, status versionedPodStatus) {
    /*
        其他代码
    */

    // canBeDeleted()一直返回false,因此进入不了if语句
    if m.canBeDeleted(pod, status.status, status.podIsFinished) {
        deleteOptions := metav1.DeleteOptions{
            GracePeriodSeconds: new(int64),
            Preconditions: metav1.NewUIDPreconditions(string(pod.UID)),
        }
        
        // 调用client请求kube-apiserver彻底删除Pod,请求中指定grace-period=0
        err = m.kubeClient.CoreV1().Pods(pod.Namespace).Delete(context.TODO(), pod.Name, deleteOptions)
        
        /*
        	其他代码
        */
    }
}

查看canBeDeleted( )的代码,由于pod.DeletionTimestamp == nil,因此canBeDeleted( )返回一直是false。

func (m *manager) canBeDeleted(pod *v1.Pod, status v1.PodStatus, podIsFinished bool) bool {
    if pod.DeletionTimestamp == nil || kubetypes.IsMirrorPod(pod) {
        return false
    }
    
     /*
        	其他代码
    */
    return false
}

综合起来看,对于Evicted状态的Pod,kubelet的status manager的syncPod( )里是没机会向kube-apiserver发送带grace-period=0的删除Pod的请求,所以Pod就一直存在于集群中。

3 附录

pod的删除概述流程分析,请参考我的另外一个篇文章:

https://blog.csdn.net/nangonghen/article/details/109305635
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐