// Schedule tries to schedule the given pod to one of the nodes in the node list.
// If it succeeds, it will return the name of the node.
// If it fails, it will return a FitError error with reasons.
翻译过来就是Schedule方法 尝试从给出的节点列表中选择一个调度这个pod
如果成功,会返回节点的名称
如果失败,会返回错误
来分析一下 这个方法的返回值
这个ScheduleResult结构体他的字段定义的很清晰一看就知道干啥的
(result ScheduleResult, err error)type ScheduleResult struct {
// Name of the scheduler suggest host
SuggestedHost string 结果节点
// Number of nodes scheduler evaluated on one pod scheduled
EvaluatedNodes int 参与计算的节点数
// Number of feasible nodes on one pod scheduled
FeasibleNodes int 合适的节点数
}
再分析一下这个方法的 参数
(ctx context.Context, extenders []framework.Extender, fwk framework.Framework, state *framework.CycleState, pod *v1.Pod)
// Run "prefilter" plugins.
s := fwk.RunPreFilterPlugins(ctx, state, pod)
allNodes, err := g.nodeInfoSnapshot.NodeInfos().List()if err !=nil{returnnil, diagnosis, err
}
遍历执行的代码如下
func(f *frameworkImpl)RunPreFilterPlugins(ctx context.Context, state *framework.CycleState, pod *v1.Pod)(status *framework.Status){
startTime := time.Now()deferfunc(){
metrics.FrameworkExtensionPointDuration.WithLabelValues(preFilter, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime))}()for_, pl :=range f.preFilterPlugins {
status = f.runPreFilterPlugin(ctx, pl, state, pod)if!status.IsSuccess(){
status.SetFailedPlugin(pl.Name())if status.IsUnschedulable(){return status
}return framework.AsStatus(fmt.Errorf("running PreFilter plugin %q: %w", pl.Name(), status.AsError())).WithFailedPlugin(pl.Name())}}returnnil}
核心就是执行 各个 PreFilterPlugin的 PreFilter方法
type PreFilterPlugin interface{
Plugin
// PreFilter is called at the beginning of the scheduling cycle. All PreFilter// plugins must return success or the pod will be rejected.PreFilter(ctx context.Context, state *CycleState, p *v1.Pod)*Status
// PreFilterExtensions returns a PreFilterExtensions interface if the plugin implements one,// or nil if it does not. A Pre-filter plugin can provide extensions to incrementally// modify its pre-processed info. The framework guarantees that the extensions// AddPod/RemovePod will only be called after PreFilter, possibly on a cloned// CycleState, and may call those functions more than once before calling// Filter again on a specific node.PreFilterExtensions() PreFilterExtensions
}
// computePodResourceRequest returns a framework.Resource that covers the largest// width in each resource dimension. Because init-containers run sequentially, we collect// the max in each dimension iteratively. In contrast, we sum the resource vectors for// regular containers since they run simultaneously.//// If Pod Overhead is specified and the feature gate is set, the resources defined for Overhead// are added to the calculated Resource request sum//// Example://// Pod:// InitContainers// IC1:// CPU: 2// Memory: 1G// IC2:// CPU: 2// Memory: 3G// Containers// C1:// CPU: 2// Memory: 1G// C2:// CPU: 1// Memory: 1G//// Result: CPU: 3, Memory: 3G
// Filter invoked at the filter extension point.// Checks if a node has sufficient resources, such as cpu, memory, gpu, opaque int resources etc to run a pod.// It returns a list of insufficient resources, if empty, then the node has all the resources requested by the pod.func(f *Fit)Filter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo)*framework.Status {
s, err :=getPreFilterState(cycleState)if err !=nil{return framework.AsStatus(err)}
insufficientResources :=fitsRequest(s, nodeInfo, f.ignoredResources, f.ignoredResourceGroups)iflen(insufficientResources)!=0{// We will keep all failure reasons.
failureReasons :=make([]string,0,len(insufficientResources))for_, r :=range insufficientResources {
failureReasons =append(failureReasons, r.Reason)}return framework.NewStatus(framework.Unschedulable, failureReasons...)}returnnil}