Merge pull request #4026 from marwanad/cherry-pick-fits-any-1.18
Cherry pick #3429 onto 1.18 - Use FitsAnyNode in binpacking
This commit is contained in:
commit
0dd845c9eb
|
|
@ -63,7 +63,7 @@ func (estimator *BinpackingNodeEstimator) Estimate(
|
||||||
podInfos := calculatePodScore(pods, nodeTemplate)
|
podInfos := calculatePodScore(pods, nodeTemplate)
|
||||||
sort.Slice(podInfos, func(i, j int) bool { return podInfos[i].score > podInfos[j].score })
|
sort.Slice(podInfos, func(i, j int) bool { return podInfos[i].score > podInfos[j].score })
|
||||||
|
|
||||||
newNodeNames := make([]string, 0)
|
newNodeNames := make(map[string]bool)
|
||||||
|
|
||||||
if err := estimator.clusterSnapshot.Fork(); err != nil {
|
if err := estimator.clusterSnapshot.Fork(); err != nil {
|
||||||
klog.Errorf("Error while calling ClusterSnapshot.Fork; %v", err)
|
klog.Errorf("Error while calling ClusterSnapshot.Fork; %v", err)
|
||||||
|
|
@ -80,16 +80,18 @@ func (estimator *BinpackingNodeEstimator) Estimate(
|
||||||
|
|
||||||
for _, podInfo := range podInfos {
|
for _, podInfo := range podInfos {
|
||||||
found := false
|
found := false
|
||||||
for _, nodeName := range newNodeNames {
|
|
||||||
if err := estimator.predicateChecker.CheckPredicates(estimator.clusterSnapshot, podInfo.pod, nodeName); err == nil {
|
nodeName, err := estimator.predicateChecker.FitsAnyNodeMatching(estimator.clusterSnapshot, podInfo.pod, func(nodeInfo *schedulernodeinfo.NodeInfo) bool {
|
||||||
|
return newNodeNames[nodeInfo.Node().Name]
|
||||||
|
})
|
||||||
|
if err == nil {
|
||||||
found = true
|
found = true
|
||||||
if err := estimator.clusterSnapshot.AddPod(podInfo.pod, nodeName); err != nil {
|
if err := estimator.clusterSnapshot.AddPod(podInfo.pod, nodeName); err != nil {
|
||||||
klog.Errorf("Error adding pod %v.%v to node %v in ClusterSnapshot; %v", podInfo.pod.Namespace, podInfo.pod.Name, nodeName, err)
|
klog.Errorf("Error adding pod %v.%v to node %v in ClusterSnapshot; %v", podInfo.pod.Namespace, podInfo.pod.Name, nodeName, err)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
// Add new node
|
// Add new node
|
||||||
newNodeName, err := estimator.addNewNodeToSnapshot(nodeTemplate, newNodeNameTimestamp, newNodeNameIndex)
|
newNodeName, err := estimator.addNewNodeToSnapshot(nodeTemplate, newNodeNameTimestamp, newNodeNameIndex)
|
||||||
|
|
@ -103,7 +105,7 @@ func (estimator *BinpackingNodeEstimator) Estimate(
|
||||||
klog.Errorf("Error adding pod %v.%v to node %v in ClusterSnapshot; %v", podInfo.pod.Namespace, podInfo.pod.Name, newNodeName, err)
|
klog.Errorf("Error adding pod %v.%v to node %v in ClusterSnapshot; %v", podInfo.pod.Namespace, podInfo.pod.Name, newNodeName, err)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
newNodeNames = append(newNodeNames, newNodeName)
|
newNodeNames[newNodeName] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return len(newNodeNames)
|
return len(newNodeNames)
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,12 @@ package simulator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
apiv1 "k8s.io/api/core/v1"
|
apiv1 "k8s.io/api/core/v1"
|
||||||
|
schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PredicateChecker checks whether all required predicates pass for given Pod and Node.
|
// PredicateChecker checks whether all required predicates pass for given Pod and Node.
|
||||||
type PredicateChecker interface {
|
type PredicateChecker interface {
|
||||||
FitsAnyNode(clusterSnapshot ClusterSnapshot, pod *apiv1.Pod) (string, error)
|
FitsAnyNode(clusterSnapshot ClusterSnapshot, pod *apiv1.Pod) (string, error)
|
||||||
|
FitsAnyNodeMatching(clusterSnapshot ClusterSnapshot, pod *apiv1.Pod, nodeMatches func(*schedulernodeinfo.NodeInfo) bool) (string, error)
|
||||||
CheckPredicates(clusterSnapshot ClusterSnapshot, pod *apiv1.Pod, nodeName string) *PredicateError
|
CheckPredicates(clusterSnapshot ClusterSnapshot, pod *apiv1.Pod, nodeName string) *PredicateError
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,13 @@ func NewSchedulerBasedPredicateChecker(kubeClient kube_client.Interface, stop <-
|
||||||
|
|
||||||
// FitsAnyNode checks if the given pod can be placed on any of the given nodes.
|
// FitsAnyNode checks if the given pod can be placed on any of the given nodes.
|
||||||
func (p *SchedulerBasedPredicateChecker) FitsAnyNode(clusterSnapshot ClusterSnapshot, pod *apiv1.Pod) (string, error) {
|
func (p *SchedulerBasedPredicateChecker) FitsAnyNode(clusterSnapshot ClusterSnapshot, pod *apiv1.Pod) (string, error) {
|
||||||
|
return p.FitsAnyNodeMatching(clusterSnapshot, pod, func(*scheduler_nodeinfo.NodeInfo) bool {
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// FitsAnyNodeMatching checks if the given pod can be placed on any of the given nodes matching the provided function.
|
||||||
|
func (p *SchedulerBasedPredicateChecker) FitsAnyNodeMatching(clusterSnapshot ClusterSnapshot, pod *apiv1.Pod, nodeMatches func(*scheduler_nodeinfo.NodeInfo) bool) (string, error) {
|
||||||
if clusterSnapshot == nil {
|
if clusterSnapshot == nil {
|
||||||
return "", fmt.Errorf("ClusterSnapshot not provided")
|
return "", fmt.Errorf("ClusterSnapshot not provided")
|
||||||
}
|
}
|
||||||
|
|
@ -113,6 +120,10 @@ func (p *SchedulerBasedPredicateChecker) FitsAnyNode(clusterSnapshot ClusterSnap
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, nodeInfo := range nodeInfosList {
|
for _, nodeInfo := range nodeInfosList {
|
||||||
|
if !nodeMatches(nodeInfo) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// Be sure that the node is schedulable.
|
// Be sure that the node is schedulable.
|
||||||
if nodeInfo.Node().Spec.Unschedulable {
|
if nodeInfo.Node().Spec.Unschedulable {
|
||||||
continue
|
continue
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue