From be2bb399648d68868212e9c5507ac3dcca1124b2 Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Fri, 21 Oct 2016 11:23:22 +0200 Subject: [PATCH 1/2] Cache node conditions in scheduler NodeInfo --- .../algorithm/predicates/predicates.go | 29 +++--------- .../pkg/scheduler/schedulercache/node_info.go | 45 ++++++++++++++++--- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/plugin/pkg/scheduler/algorithm/predicates/predicates.go b/plugin/pkg/scheduler/algorithm/predicates/predicates.go index 7665bcc5572..a50a51ae9be 100644 --- a/plugin/pkg/scheduler/algorithm/predicates/predicates.go +++ b/plugin/pkg/scheduler/algorithm/predicates/predicates.go @@ -1174,11 +1174,6 @@ func isPodBestEffort(pod *v1.Pod) bool { // CheckNodeMemoryPressurePredicate checks if a pod can be scheduled on a node // reporting memory pressure condition. func CheckNodeMemoryPressurePredicate(pod *v1.Pod, meta interface{}, nodeInfo *schedulercache.NodeInfo) (bool, []algorithm.PredicateFailureReason, error) { - node := nodeInfo.Node() - if node == nil { - return false, nil, fmt.Errorf("node not found") - } - var podBestEffort bool if predicateMeta, ok := meta.(*predicateMetadata); ok { podBestEffort = predicateMeta.podBestEffort @@ -1186,36 +1181,24 @@ func CheckNodeMemoryPressurePredicate(pod *v1.Pod, meta interface{}, nodeInfo *s // We couldn't parse metadata - fallback to computing it. podBestEffort = isPodBestEffort(pod) } - // pod is not BestEffort pod if !podBestEffort { return true, nil, nil } - // is node under pressure? - for _, cond := range node.Status.Conditions { - if cond.Type == v1.NodeMemoryPressure && cond.Status == v1.ConditionTrue { - return false, []algorithm.PredicateFailureReason{ErrNodeUnderMemoryPressure}, nil - } + // is node under presure? + if nodeInfo.MemoryPressureCondition() == v1.ConditionTrue { + return false, []algorithm.PredicateFailureReason{ErrNodeUnderMemoryPressure}, nil } - return true, nil, nil } // CheckNodeDiskPressurePredicate checks if a pod can be scheduled on a node // reporting disk pressure condition. func CheckNodeDiskPressurePredicate(pod *v1.Pod, meta interface{}, nodeInfo *schedulercache.NodeInfo) (bool, []algorithm.PredicateFailureReason, error) { - node := nodeInfo.Node() - if node == nil { - return false, nil, fmt.Errorf("node not found") + // is node under presure? + if nodeInfo.DiskPressureCondition() == v1.ConditionTrue { + return false, []algorithm.PredicateFailureReason{ErrNodeUnderDiskPressure}, nil } - - // is node under pressure? - for _, cond := range node.Status.Conditions { - if cond.Type == v1.NodeDiskPressure && cond.Status == v1.ConditionTrue { - return false, []algorithm.PredicateFailureReason{ErrNodeUnderDiskPressure}, nil - } - } - return true, nil, nil } diff --git a/plugin/pkg/scheduler/schedulercache/node_info.go b/plugin/pkg/scheduler/schedulercache/node_info.go index 4a173b6b2ee..4fceb567f21 100644 --- a/plugin/pkg/scheduler/schedulercache/node_info.go +++ b/plugin/pkg/scheduler/schedulercache/node_info.go @@ -49,6 +49,10 @@ type NodeInfo struct { // explicitly as int, to avoid conversions and improve performance. allowedPodNumber int + // Cached conditions of node for faster lookup. + memoryPressureCondition v1.ConditionStatus + diskPressureCondition v1.ConditionStatus + // Whenever NodeInfo changes, generation is bumped. // This is used to avoid cloning it if the object didn't change. generation int64 @@ -122,6 +126,20 @@ func (n *NodeInfo) AllowedPodNumber() int { return n.allowedPodNumber } +func (n *NodeInfo) MemoryPressureCondition() v1.ConditionStatus { + if n == nil { + return v1.ConditionUnknown + } + return n.memoryPressureCondition +} + +func (n *NodeInfo) DiskPressureCondition() v1.ConditionStatus { + if n == nil { + return v1.ConditionUnknown + } + return n.diskPressureCondition +} + // RequestedResource returns aggregated resource request of pods on this node. func (n *NodeInfo) RequestedResource() Resource { if n == nil { @@ -148,12 +166,14 @@ func (n *NodeInfo) AllocatableResource() Resource { func (n *NodeInfo) Clone() *NodeInfo { clone := &NodeInfo{ - node: n.node, - requestedResource: &(*n.requestedResource), - nonzeroRequest: &(*n.nonzeroRequest), - allocatableResource: &(*n.allocatableResource), - allowedPodNumber: n.allowedPodNumber, - generation: n.generation, + node: n.node, + requestedResource: &(*n.requestedResource), + nonzeroRequest: &(*n.nonzeroRequest), + allocatableResource: &(*n.allocatableResource), + allowedPodNumber: n.allowedPodNumber, + memoryPressureCondition: n.memoryPressureCondition, + diskPressureCondition: n.diskPressureCondition, + generation: n.generation, } if len(n.pods) > 0 { clone.pods = append([]*v1.Pod(nil), n.pods...) @@ -306,6 +326,17 @@ func (n *NodeInfo) SetNode(node *v1.Node) error { } } } + for i := range node.Status.Conditions { + cond := &node.Status.Conditions[i] + switch cond.Type { + case v1.NodeMemoryPressure: + n.memoryPressureCondition = cond.Status + case v1.NodeDiskPressure: + n.diskPressureCondition = cond.Status + default: + // We ignore other conditions. + } + } n.generation++ return nil } @@ -319,6 +350,8 @@ func (n *NodeInfo) RemoveNode(node *v1.Node) error { n.node = nil n.allocatableResource = &Resource{} n.allowedPodNumber = 0 + n.memoryPressureCondition = v1.ConditionUnknown + n.diskPressureCondition = v1.ConditionUnknown n.generation++ return nil } From 7387bc05723452ff8dd342c7b20aa409ea5fc5c0 Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Fri, 21 Oct 2016 11:33:09 +0200 Subject: [PATCH 2/2] Cache node taints in scheduler NodeInfo --- .../algorithm/predicates/predicates.go | 7 +------ .../pkg/scheduler/schedulercache/node_info.go | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/plugin/pkg/scheduler/algorithm/predicates/predicates.go b/plugin/pkg/scheduler/algorithm/predicates/predicates.go index a50a51ae9be..ee102d8d966 100644 --- a/plugin/pkg/scheduler/algorithm/predicates/predicates.go +++ b/plugin/pkg/scheduler/algorithm/predicates/predicates.go @@ -1119,12 +1119,7 @@ func (c *PodAffinityChecker) satisfiesPodsAffinityAntiAffinity(pod *v1.Pod, node } func PodToleratesNodeTaints(pod *v1.Pod, meta interface{}, nodeInfo *schedulercache.NodeInfo) (bool, []algorithm.PredicateFailureReason, error) { - node := nodeInfo.Node() - if node == nil { - return false, nil, fmt.Errorf("node not found") - } - - taints, err := v1.GetTaintsFromNodeAnnotations(node.Annotations) + taints, err := nodeInfo.Taints() if err != nil { return false, nil, err } diff --git a/plugin/pkg/scheduler/schedulercache/node_info.go b/plugin/pkg/scheduler/schedulercache/node_info.go index 4fceb567f21..a3e816ae715 100644 --- a/plugin/pkg/scheduler/schedulercache/node_info.go +++ b/plugin/pkg/scheduler/schedulercache/node_info.go @@ -49,6 +49,10 @@ type NodeInfo struct { // explicitly as int, to avoid conversions and improve performance. allowedPodNumber int + // Cached tains of the node for faster lookup. + taints []v1.Taint + taintsErr error + // Cached conditions of node for faster lookup. memoryPressureCondition v1.ConditionStatus diskPressureCondition v1.ConditionStatus @@ -126,6 +130,13 @@ func (n *NodeInfo) AllowedPodNumber() int { return n.allowedPodNumber } +func (n *NodeInfo) Taints() ([]v1.Taint, error) { + if n == nil { + return nil, nil + } + return n.taints, n.taintsErr +} + func (n *NodeInfo) MemoryPressureCondition() v1.ConditionStatus { if n == nil { return v1.ConditionUnknown @@ -171,6 +182,7 @@ func (n *NodeInfo) Clone() *NodeInfo { nonzeroRequest: &(*n.nonzeroRequest), allocatableResource: &(*n.allocatableResource), allowedPodNumber: n.allowedPodNumber, + taintsErr: n.taintsErr, memoryPressureCondition: n.memoryPressureCondition, diskPressureCondition: n.diskPressureCondition, generation: n.generation, @@ -181,6 +193,9 @@ func (n *NodeInfo) Clone() *NodeInfo { if len(n.podsWithAffinity) > 0 { clone.podsWithAffinity = append([]*v1.Pod(nil), n.podsWithAffinity...) } + if len(n.taints) > 0 { + clone.taints = append([]v1.Taint(nil), n.taints...) + } return clone } @@ -326,6 +341,7 @@ func (n *NodeInfo) SetNode(node *v1.Node) error { } } } + n.taints, n.taintsErr = v1.GetTaintsFromNodeAnnotations(node.Annotations) for i := range node.Status.Conditions { cond := &node.Status.Conditions[i] switch cond.Type { @@ -350,6 +366,7 @@ func (n *NodeInfo) RemoveNode(node *v1.Node) error { n.node = nil n.allocatableResource = &Resource{} n.allowedPodNumber = 0 + n.taints, n.taintsErr = nil, nil n.memoryPressureCondition = v1.ConditionUnknown n.diskPressureCondition = v1.ConditionUnknown n.generation++