Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
ecba5049
Commit
ecba5049
authored
Dec 14, 2017
by
Yassine TIJANI
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implementing predicates ordering
parent
17117051
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
83 additions
and
29 deletions
+83
-29
predicates.go
plugin/pkg/scheduler/algorithm/predicates/predicates.go
+42
-3
generic_scheduler.go
plugin/pkg/scheduler/core/generic_scheduler.go
+28
-25
generic_scheduler_test.go
plugin/pkg/scheduler/core/generic_scheduler_test.go
+10
-1
scheduler_test.go
plugin/pkg/scheduler/scheduler_test.go
+3
-0
No files found.
plugin/pkg/scheduler/algorithm/predicates/predicates.go
View file @
ecba5049
...
@@ -49,9 +49,25 @@ import (
...
@@ -49,9 +49,25 @@ import (
)
)
const
(
const
(
MatchInterPodAffinity
=
"MatchInterPodAffinity"
MatchInterPodAffinity
=
"MatchInterPodAffinity"
CheckVolumeBinding
=
"CheckVolumeBinding"
CheckVolumeBinding
=
"CheckVolumeBinding"
CheckNodeConditionPred
=
"CheckNodeCondition"
GeneralPred
=
"GeneralPredicates"
HostNamePred
=
"HostName"
PodFitsHostPortsPred
=
"PodFitsHostPorts"
MatchNodeSelectorPred
=
"MatchNodeSelector"
PodFitsResourcesPred
=
"PodFitsResources"
NoDiskConflictPred
=
"NoDiskConflict"
PodToleratesNodeTaintsPred
=
"PodToleratesNodeTaints"
PodToleratesNodeNoExecuteTaintsPred
=
"PodToleratesNodeNoExecuteTaints"
CheckNodeLabelPresencePred
=
"CheckNodeLabelPresence"
checkServiceAffinityPred
=
"checkServiceAffinity"
MaxEBSVolumeCountPred
=
"MaxEBSVolumeCount"
MaxGCEPDVolumeCountPred
=
"MaxGCEPDVolumeCount"
MaxAzureDiskVolumeCountPred
=
"MaxAzureDiskVolumeCount"
NoVolumeZoneConflictPred
=
"NoVolumeZoneConflict"
CheckNodeMemoryPressurePred
=
"CheckNodeMemoryPressure"
CheckNodeDiskPressure
=
"CheckNodeDiskPressure"
// DefaultMaxGCEPDVolumes defines the maximum number of PD Volumes for GCE
// DefaultMaxGCEPDVolumes defines the maximum number of PD Volumes for GCE
// GCE instances can have up to 16 PD volumes attached.
// GCE instances can have up to 16 PD volumes attached.
DefaultMaxGCEPDVolumes
=
16
DefaultMaxGCEPDVolumes
=
16
...
@@ -79,6 +95,21 @@ const (
...
@@ -79,6 +95,21 @@ const (
// For example:
// For example:
// https://github.com/kubernetes/kubernetes/blob/36a218e/plugin/pkg/scheduler/factory/factory.go#L422
// https://github.com/kubernetes/kubernetes/blob/36a218e/plugin/pkg/scheduler/factory/factory.go#L422
// IMPORTANT: this list contains the ordering of the predicates, if you develop a new predicates
// it is mandatory to add its name on this list.
// otherwise it won't be processed, see generic_scheduler#podFitsOnNode()
// the order is based on the restrictiveness & complexity of predicates
// design doc: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/scheduling/predicates-ordering.md
var
(
predicatesOrdering
=
[]
string
{
CheckNodeConditionPred
,
GeneralPred
,
HostNamePred
,
PodFitsHostPortsPred
,
MatchNodeSelectorPred
,
PodFitsResourcesPred
,
NoDiskConflictPred
,
PodToleratesNodeTaintsPred
,
PodToleratesNodeNoExecuteTaintsPred
,
CheckNodeLabelPresencePred
,
checkServiceAffinityPred
,
MaxEBSVolumeCountPred
,
MaxGCEPDVolumeCountPred
,
MaxAzureDiskVolumeCountPred
,
CheckVolumeBinding
,
NoVolumeZoneConflictPred
,
CheckNodeMemoryPressurePred
,
CheckNodeDiskPressure
,
MatchInterPodAffinity
}
)
// NodeInfo: Other types for predicate functions...
// NodeInfo: Other types for predicate functions...
type
NodeInfo
interface
{
type
NodeInfo
interface
{
GetNodeInfo
(
nodeID
string
)
(
*
v1
.
Node
,
error
)
GetNodeInfo
(
nodeID
string
)
(
*
v1
.
Node
,
error
)
...
@@ -93,6 +124,14 @@ type CachedPersistentVolumeInfo struct {
...
@@ -93,6 +124,14 @@ type CachedPersistentVolumeInfo struct {
corelisters
.
PersistentVolumeLister
corelisters
.
PersistentVolumeLister
}
}
func
GetPredicatesOrdering
()
[]
string
{
return
predicatesOrdering
}
func
SetPredicatesOrdering
(
names
[]
string
)
{
predicatesOrdering
=
names
}
func
(
c
*
CachedPersistentVolumeInfo
)
GetPersistentVolumeInfo
(
pvID
string
)
(
*
v1
.
PersistentVolume
,
error
)
{
func
(
c
*
CachedPersistentVolumeInfo
)
GetPersistentVolumeInfo
(
pvID
string
)
(
*
v1
.
PersistentVolume
,
error
)
{
return
c
.
Get
(
pvID
)
return
c
.
Get
(
pvID
)
}
}
...
...
plugin/pkg/scheduler/core/generic_scheduler.go
View file @
ecba5049
...
@@ -444,34 +444,37 @@ func podFitsOnNode(
...
@@ -444,34 +444,37 @@ func podFitsOnNode(
// TODO(bsalamat): consider using eCache and adding proper eCache invalidations
// TODO(bsalamat): consider using eCache and adding proper eCache invalidations
// when pods are nominated or their nominations change.
// when pods are nominated or their nominations change.
eCacheAvailable
=
eCacheAvailable
&&
!
podsAdded
eCacheAvailable
=
eCacheAvailable
&&
!
podsAdded
for
predicateKey
,
predicate
:=
range
predicateFuncs
{
for
_
,
predicateKey
:=
range
predicates
.
GetPredicatesOrdering
()
{
if
eCacheAvailable
{
//TODO (yastij) : compute average predicate restrictiveness to export it as promethus metric
// PredicateWithECache will return its cached predicate results.
if
predicate
,
exist
:=
predicateFuncs
[
predicateKey
];
exist
{
fit
,
reasons
,
invalid
=
ecache
.
PredicateWithECache
(
pod
.
GetName
(),
info
.
Node
()
.
GetName
(),
predicateKey
,
equivalenceHash
)
}
// TODO(bsalamat): When one predicate fails and fit is false, why do we continue
// checking other predicates?
if
!
eCacheAvailable
||
invalid
{
// we need to execute predicate functions since equivalence cache does not work
fit
,
reasons
,
err
=
predicate
(
pod
,
metaToUse
,
nodeInfoToUse
)
if
err
!=
nil
{
return
false
,
[]
algorithm
.
PredicateFailureReason
{},
err
}
if
eCacheAvailable
{
if
eCacheAvailable
{
// Store data to update eCache after this loop.
// PredicateWithECache will return its cached predicate results.
if
res
,
exists
:=
predicateResults
[
predicateKey
];
exists
{
fit
,
reasons
,
invalid
=
ecache
.
PredicateWithECache
(
pod
.
GetName
(),
info
.
Node
()
.
GetName
(),
predicateKey
,
equivalenceHash
)
res
.
Fit
=
res
.
Fit
&&
fit
}
res
.
FailReasons
=
append
(
res
.
FailReasons
,
reasons
...
)
predicateResults
[
predicateKey
]
=
res
// TODO(bsalamat): When one predicate fails and fit is false, why do we continue
}
else
{
// checking other predicates?
predicateResults
[
predicateKey
]
=
HostPredicate
{
Fit
:
fit
,
FailReasons
:
reasons
}
if
!
eCacheAvailable
||
invalid
{
// we need to execute predicate functions since equivalence cache does not work
fit
,
reasons
,
err
=
predicate
(
pod
,
metaToUse
,
nodeInfoToUse
)
if
err
!=
nil
{
return
false
,
[]
algorithm
.
PredicateFailureReason
{},
err
}
if
eCacheAvailable
{
// Store data to update eCache after this loop.
if
res
,
exists
:=
predicateResults
[
predicateKey
];
exists
{
res
.
Fit
=
res
.
Fit
&&
fit
res
.
FailReasons
=
append
(
res
.
FailReasons
,
reasons
...
)
predicateResults
[
predicateKey
]
=
res
}
else
{
predicateResults
[
predicateKey
]
=
HostPredicate
{
Fit
:
fit
,
FailReasons
:
reasons
}
}
}
}
}
}
}
if
!
fit
{
if
!
fit
{
// eCache is available and valid, and predicates result is unfit, record the fail reasons
// eCache is available and valid, and predicates result is unfit, record the fail reasons
failedPredicates
=
append
(
failedPredicates
,
reasons
...
)
failedPredicates
=
append
(
failedPredicates
,
reasons
...
)
}
}
}
}
}
}
}
...
...
plugin/pkg/scheduler/core/generic_scheduler_test.go
View file @
ecba5049
...
@@ -42,6 +42,10 @@ import (
...
@@ -42,6 +42,10 @@ import (
schedulertesting
"k8s.io/kubernetes/plugin/pkg/scheduler/testing"
schedulertesting
"k8s.io/kubernetes/plugin/pkg/scheduler/testing"
)
)
var
(
order
=
[]
string
{
"false"
,
"true"
,
"matches"
,
"nopods"
,
predicates
.
MatchInterPodAffinity
}
)
func
falsePredicate
(
pod
*
v1
.
Pod
,
meta
algorithm
.
PredicateMetadata
,
nodeInfo
*
schedulercache
.
NodeInfo
)
(
bool
,
[]
algorithm
.
PredicateFailureReason
,
error
)
{
func
falsePredicate
(
pod
*
v1
.
Pod
,
meta
algorithm
.
PredicateMetadata
,
nodeInfo
*
schedulercache
.
NodeInfo
)
(
bool
,
[]
algorithm
.
PredicateFailureReason
,
error
)
{
return
false
,
[]
algorithm
.
PredicateFailureReason
{
algorithmpredicates
.
ErrFakePredicate
},
nil
return
false
,
[]
algorithm
.
PredicateFailureReason
{
algorithmpredicates
.
ErrFakePredicate
},
nil
}
}
...
@@ -181,6 +185,7 @@ func TestSelectHost(t *testing.T) {
...
@@ -181,6 +185,7 @@ func TestSelectHost(t *testing.T) {
}
}
func
TestGenericScheduler
(
t
*
testing
.
T
)
{
func
TestGenericScheduler
(
t
*
testing
.
T
)
{
predicates
.
SetPredicatesOrdering
(
order
)
tests
:=
[]
struct
{
tests
:=
[]
struct
{
name
string
name
string
predicates
map
[
string
]
algorithm
.
FitPredicate
predicates
map
[
string
]
algorithm
.
FitPredicate
...
@@ -401,6 +406,7 @@ func TestGenericScheduler(t *testing.T) {
...
@@ -401,6 +406,7 @@ func TestGenericScheduler(t *testing.T) {
}
}
func
TestFindFitAllError
(
t
*
testing
.
T
)
{
func
TestFindFitAllError
(
t
*
testing
.
T
)
{
predicates
.
SetPredicatesOrdering
(
order
)
nodes
:=
[]
string
{
"3"
,
"2"
,
"1"
}
nodes
:=
[]
string
{
"3"
,
"2"
,
"1"
}
predicates
:=
map
[
string
]
algorithm
.
FitPredicate
{
"true"
:
truePredicate
,
"false"
:
falsePredicate
}
predicates
:=
map
[
string
]
algorithm
.
FitPredicate
{
"true"
:
truePredicate
,
"false"
:
falsePredicate
}
nodeNameToInfo
:=
map
[
string
]
*
schedulercache
.
NodeInfo
{
nodeNameToInfo
:=
map
[
string
]
*
schedulercache
.
NodeInfo
{
...
@@ -430,8 +436,9 @@ func TestFindFitAllError(t *testing.T) {
...
@@ -430,8 +436,9 @@ func TestFindFitAllError(t *testing.T) {
}
}
func
TestFindFitSomeError
(
t
*
testing
.
T
)
{
func
TestFindFitSomeError
(
t
*
testing
.
T
)
{
predicates
.
SetPredicatesOrdering
(
order
)
nodes
:=
[]
string
{
"3"
,
"2"
,
"1"
}
nodes
:=
[]
string
{
"3"
,
"2"
,
"1"
}
predicates
:=
map
[
string
]
algorithm
.
FitPredicate
{
"true"
:
truePredicate
,
"match"
:
matchesPredicate
}
predicates
:=
map
[
string
]
algorithm
.
FitPredicate
{
"true"
:
truePredicate
,
"match
es
"
:
matchesPredicate
}
pod
:=
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"1"
}}
pod
:=
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"1"
}}
nodeNameToInfo
:=
map
[
string
]
*
schedulercache
.
NodeInfo
{
nodeNameToInfo
:=
map
[
string
]
*
schedulercache
.
NodeInfo
{
"3"
:
schedulercache
.
NewNodeInfo
(),
"3"
:
schedulercache
.
NewNodeInfo
(),
...
@@ -741,6 +748,7 @@ var negPriority, lowPriority, midPriority, highPriority, veryHighPriority = int3
...
@@ -741,6 +748,7 @@ var negPriority, lowPriority, midPriority, highPriority, veryHighPriority = int3
// TestSelectNodesForPreemption tests selectNodesForPreemption. This test assumes
// TestSelectNodesForPreemption tests selectNodesForPreemption. This test assumes
// that podsFitsOnNode works correctly and is tested separately.
// that podsFitsOnNode works correctly and is tested separately.
func
TestSelectNodesForPreemption
(
t
*
testing
.
T
)
{
func
TestSelectNodesForPreemption
(
t
*
testing
.
T
)
{
predicates
.
SetPredicatesOrdering
(
order
)
tests
:=
[]
struct
{
tests
:=
[]
struct
{
name
string
name
string
predicates
map
[
string
]
algorithm
.
FitPredicate
predicates
map
[
string
]
algorithm
.
FitPredicate
...
@@ -879,6 +887,7 @@ func TestSelectNodesForPreemption(t *testing.T) {
...
@@ -879,6 +887,7 @@ func TestSelectNodesForPreemption(t *testing.T) {
// TestPickOneNodeForPreemption tests pickOneNodeForPreemption.
// TestPickOneNodeForPreemption tests pickOneNodeForPreemption.
func
TestPickOneNodeForPreemption
(
t
*
testing
.
T
)
{
func
TestPickOneNodeForPreemption
(
t
*
testing
.
T
)
{
predicates
.
SetPredicatesOrdering
(
order
)
tests
:=
[]
struct
{
tests
:=
[]
struct
{
name
string
name
string
predicates
map
[
string
]
algorithm
.
FitPredicate
predicates
map
[
string
]
algorithm
.
FitPredicate
...
...
plugin/pkg/scheduler/scheduler_test.go
View file @
ecba5049
...
@@ -43,6 +43,8 @@ import (
...
@@ -43,6 +43,8 @@ import (
"k8s.io/kubernetes/plugin/pkg/scheduler/volumebinder"
"k8s.io/kubernetes/plugin/pkg/scheduler/volumebinder"
)
)
var
order
=
[]
string
{
"VolumeBindingChecker"
}
type
fakeBinder
struct
{
type
fakeBinder
struct
{
b
func
(
binding
*
v1
.
Binding
)
error
b
func
(
binding
*
v1
.
Binding
)
error
}
}
...
@@ -637,6 +639,7 @@ func makePredicateError(failReason string) error {
...
@@ -637,6 +639,7 @@ func makePredicateError(failReason string) error {
}
}
func
TestSchedulerWithVolumeBinding
(
t
*
testing
.
T
)
{
func
TestSchedulerWithVolumeBinding
(
t
*
testing
.
T
)
{
predicates
.
SetPredicatesOrdering
(
order
)
findErr
:=
fmt
.
Errorf
(
"find err"
)
findErr
:=
fmt
.
Errorf
(
"find err"
)
assumeErr
:=
fmt
.
Errorf
(
"assume err"
)
assumeErr
:=
fmt
.
Errorf
(
"assume err"
)
bindErr
:=
fmt
.
Errorf
(
"bind err"
)
bindErr
:=
fmt
.
Errorf
(
"bind err"
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment