深入分析Kubernetes Critical Pod(三)

阅读全文请点击

本文介绍了Kubelet在Predicate Admit准入检查时对CriticalPod的资源抢占的原理,以及Priority Admission Controller对CriticalPod的PriorityClassName特殊处理。

深入分析Kubernetes Critical Pod系列:
深入分析Kubernetes Critical Pod(一)
深入分析Kubernetes Critical Pod(二)
深入分析Kubernetes Critical Pod(三)
深入分析Kubernetes Critical Pod(四)

Kubelet Predicate Admit时对Critical的资源抢占处理

kubelet 在Predicate Admit流程中,会对Pods进行各种Predicate准入检查,包括GeneralPredicates检查本节点是否有足够的cpu,mem,gpu资源。如果GeneralPredicates准入检测失败,对于nonCriticalPod则直接Admit失败,但如果是CriticalPod则会触发kubelet preemption进行资源抢占,按照一定规则杀死一些Pods释放资源,抢占成功,则Admit成功。

流程的源头应该从kubelet初始化的流程开始。

pkg/kubelet/kubelet.go:315

// NewMainKubelet instantiates a new Kubelet object along with all the required internal modules.
// No initialization of Kubelet and its modules should happen here.
func NewMainKubelet(...) (*Kubelet, error) {
    ...
   criticalPodAdmissionHandler := preemption.NewCriticalPodAdmissionHandler(klet.GetActivePods, killPodNow(klet.podWorkers, kubeDeps.Recorder), kubeDeps.Recorder)
    klet.admitHandlers.AddPodAdmitHandler(lifecycle.NewPredicateAdmitHandler(klet.getNodeAnyWay, criticalPodAdmissionHandler, klet.containerManager.UpdatePluginResources))
    // apply functional Option's
    for _, opt := range kubeDeps.Options {
        opt(klet)
    }

    ...
    return klet, nil
}

在NewMainKubelet对kubelet进行初始化时,通过AddPodAdmitHandler注册了criticalPodAdmissionHandler,CriticalPod的Admit的特殊之处就体现在criticalPodAdmissionHandler。

然后,我们进入kubelet的predicateAdmitHandler流程中,看看GeneralPredicates失败后的处理逻辑。

pkg/kubelet/lifecycle/predicate.go:58

func (w *predicateAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult {
    ...

    fit, reasons, err := predicates.GeneralPredicates(podWithoutMissingExtendedResources, nil, nodeInfo)
    if err != nil {
        message := fmt.Sprintf("GeneralPredicates failed due to %v, which is unexpected.", err)
        glog.Warningf("Failed to admit pod %v - %s", format.Pod(pod), message)
        return PodAdmitResult{
            Admit:   fit,
            Reason:  "UnexpectedAdmissionError",
            Message: message,
        }
    }
    if !fit {
        fit, reasons, err = w.admissionFailureHandler.HandleAdmissionFailure(pod, reasons)
        if err != nil {
            message := fmt.Sprintf("Unexpected error while attempting to recover from admission failure: %v", err)
            glog.Warningf("Failed to admit pod %v - %s", format.Pod(pod), message)
            return PodAdmitResult{
                Admit:   fit,
                Reason:  "UnexpectedAdmissionError",
                Message: message,
            }
        }
    }
    ...
    return PodAdmitResult{
        Admit: true,
    }
}
posted @ 2018-07-02 15:00  16619913174  阅读(1175)  评论(0编辑  收藏  举报