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
ac4a082b
Commit
ac4a082b
authored
Aug 22, 2018
by
Ahmad Diaa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
use topologyPairsMaps for inter pod affinity/anti-affinity maps
parent
e41d9f15
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
141 additions
and
152 deletions
+141
-152
metadata.go
pkg/scheduler/algorithm/predicates/metadata.go
+68
-90
metadata_test.go
pkg/scheduler/algorithm/predicates/metadata_test.go
+60
-42
predicates.go
pkg/scheduler/algorithm/predicates/predicates.go
+13
-20
No files found.
pkg/scheduler/algorithm/predicates/metadata.go
View file @
ac4a082b
...
...
@@ -71,15 +71,15 @@ type predicateMetadata struct {
podPorts
[]
*
v1
.
ContainerPort
topologyPairsAntiAffinityPodsMap
*
topologyPairsMaps
// A map of
node name to a list of Pods on the node
that can potentially match
// the affinity rules of the "pod".
nodeNameToMatchingAffinityPods
map
[
string
][]
*
v1
.
Pod
// A map of
node name to a list of Pods on the node
that can potentially match
// the anti-affinity rules of the "pod".
nodeNameToMatchingAntiAffinityPods
map
[
string
][]
*
v1
.
Pod
serviceAffinityInUse
bool
serviceAffinityMatchingPodList
[]
*
v1
.
Pod
serviceAffinityMatchingPodServices
[]
*
v1
.
Service
// A map of
topology pairs to a list of Pods
that can potentially match
// the affinity rules of the "pod"
and its inverse
.
topologyPairsPotentialAffinityPods
*
topologyPairsMaps
// A map of
topology pairs to a list of Pods
that can potentially match
// the anti-affinity rules of the "pod"
and its inverse
.
topologyPairsPotentialAntiAffinityPods
*
topologyPairsMaps
serviceAffinityInUse
bool
serviceAffinityMatchingPodList
[]
*
v1
.
Pod
serviceAffinityMatchingPodServices
[]
*
v1
.
Service
// ignoredExtendedResources is a set of extended resource names that will
// be ignored in the PodFitsResources predicate.
//
...
...
@@ -134,19 +134,19 @@ func (pfactory *PredicateMetadataFactory) GetMetadata(pod *v1.Pod, nodeNameToInf
if
err
!=
nil
{
return
nil
}
affinityPods
,
antiAffinityPod
s
,
err
:=
getPodsMatchingAffinity
(
pod
,
nodeNameToInfoMap
)
topologyPairsAffinityPodsMaps
,
topologyPairsAntiAffinityPodsMap
s
,
err
:=
getPodsMatchingAffinity
(
pod
,
nodeNameToInfoMap
)
if
err
!=
nil
{
glog
.
Errorf
(
"[predicate meta data generation] error finding pods that match affinity terms: %v"
,
err
)
return
nil
}
predicateMetadata
:=
&
predicateMetadata
{
pod
:
pod
,
podBestEffort
:
isPodBestEffort
(
pod
),
podRequest
:
GetResourceRequest
(
pod
),
podPorts
:
schedutil
.
GetContainerPorts
(
pod
),
nodeNameToMatchingAffinityPods
:
affinityPod
s
,
nodeNameToMatchingAntiAffinityPods
:
antiAffinityPod
s
,
topologyPairsAntiAffinityPodsMap
:
topologyPairsMaps
,
pod
:
pod
,
podBestEffort
:
isPodBestEffort
(
pod
),
podRequest
:
GetResourceRequest
(
pod
),
podPorts
:
schedutil
.
GetContainerPorts
(
pod
),
topologyPairsPotentialAffinityPods
:
topologyPairsAffinityPodsMap
s
,
topologyPairsPotentialAntiAffinityPods
:
topologyPairsAntiAffinityPodsMap
s
,
topologyPairsAntiAffinityPodsMap
:
topologyPairsMaps
,
}
for
predicateName
,
precomputeFunc
:=
range
predicateMetadataProducers
{
glog
.
V
(
10
)
.
Infof
(
"Precompute: %v"
,
predicateName
)
...
...
@@ -200,33 +200,9 @@ func (meta *predicateMetadata) RemovePod(deletedPod *v1.Pod) error {
return
fmt
.
Errorf
(
"deletedPod and meta.pod must not be the same"
)
}
meta
.
topologyPairsAntiAffinityPodsMap
.
removePod
(
deletedPod
)
// Delete pod from the matching affinity or anti-affinity pods if exists.
affinity
:=
meta
.
pod
.
Spec
.
Affinity
podNodeName
:=
deletedPod
.
Spec
.
NodeName
if
affinity
!=
nil
&&
len
(
podNodeName
)
>
0
{
if
affinity
.
PodAffinity
!=
nil
{
for
i
,
p
:=
range
meta
.
nodeNameToMatchingAffinityPods
[
podNodeName
]
{
if
p
==
deletedPod
{
s
:=
meta
.
nodeNameToMatchingAffinityPods
[
podNodeName
]
s
[
i
]
=
s
[
len
(
s
)
-
1
]
s
=
s
[
:
len
(
s
)
-
1
]
meta
.
nodeNameToMatchingAffinityPods
[
podNodeName
]
=
s
break
}
}
}
if
affinity
.
PodAntiAffinity
!=
nil
{
for
i
,
p
:=
range
meta
.
nodeNameToMatchingAntiAffinityPods
[
podNodeName
]
{
if
p
==
deletedPod
{
s
:=
meta
.
nodeNameToMatchingAntiAffinityPods
[
podNodeName
]
s
[
i
]
=
s
[
len
(
s
)
-
1
]
s
=
s
[
:
len
(
s
)
-
1
]
meta
.
nodeNameToMatchingAntiAffinityPods
[
podNodeName
]
=
s
break
}
}
}
}
// Delete pod from the matching affinity or anti-affinity topology pairs maps.
meta
.
topologyPairsPotentialAffinityPods
.
removePod
(
deletedPod
)
meta
.
topologyPairsPotentialAntiAffinityPods
.
removePod
(
deletedPod
)
// All pods in the serviceAffinityMatchingPodList are in the same namespace.
// So, if the namespace of the first one is not the same as the namespace of the
// deletedPod, we don't need to check the list, as deletedPod isn't in the list.
...
...
@@ -267,29 +243,24 @@ func (meta *predicateMetadata) AddPod(addedPod *v1.Pod, nodeInfo *schedulercache
affinity
:=
meta
.
pod
.
Spec
.
Affinity
podNodeName
:=
addedPod
.
Spec
.
NodeName
if
affinity
!=
nil
&&
len
(
podNodeName
)
>
0
{
podNode
:=
nodeInfo
.
Node
()
affinityTerms
:=
GetPodAffinityTerms
(
affinity
.
PodAffinity
)
antiAffinityTerms
:=
GetPodAntiAffinityTerms
(
affinity
.
PodAntiAffinity
)
if
targetPodMatchesAffinityOfPod
(
meta
.
pod
,
addedPod
)
{
found
:=
false
for
_
,
p
:=
range
meta
.
nodeNameToMatchingAffinityPods
[
podNodeName
]
{
if
p
==
addedPod
{
found
=
true
break
for
_
,
term
:=
range
affinityTerms
{
if
topologyValue
,
ok
:=
podNode
.
Labels
[
term
.
TopologyKey
];
ok
{
pair
:=
topologyPair
{
key
:
term
.
TopologyKey
,
value
:
topologyValue
}
meta
.
topologyPairsPotentialAffinityPods
.
addTopologyPair
(
pair
,
addedPod
)
}
}
if
!
found
{
meta
.
nodeNameToMatchingAffinityPods
[
podNodeName
]
=
append
(
meta
.
nodeNameToMatchingAffinityPods
[
podNodeName
],
addedPod
)
}
}
if
targetPodMatchesAntiAffinityOfPod
(
meta
.
pod
,
addedPod
)
{
found
:=
false
for
_
,
p
:=
range
meta
.
nodeNameToMatchingAntiAffinityPods
[
podNodeName
]
{
if
p
==
addedPod
{
found
=
true
break
for
_
,
term
:=
range
antiAffinityTerms
{
if
topologyValue
,
ok
:=
podNode
.
Labels
[
term
.
TopologyKey
];
ok
{
pair
:=
topologyPair
{
key
:
term
.
TopologyKey
,
value
:
topologyValue
}
meta
.
topologyPairsPotentialAntiAffinityPods
.
addTopologyPair
(
pair
,
addedPod
)
}
}
if
!
found
{
meta
.
nodeNameToMatchingAntiAffinityPods
[
podNodeName
]
=
append
(
meta
.
nodeNameToMatchingAntiAffinityPods
[
podNodeName
],
addedPod
)
}
}
}
// If addedPod is in the same namespace as the meta.pod, update the list
...
...
@@ -308,22 +279,17 @@ func (meta *predicateMetadata) AddPod(addedPod *v1.Pod, nodeInfo *schedulercache
// its maps and slices, but it does not copy the contents of pointer values.
func
(
meta
*
predicateMetadata
)
ShallowCopy
()
algorithm
.
PredicateMetadata
{
newPredMeta
:=
&
predicateMetadata
{
pod
:
meta
.
pod
,
podBestEffort
:
meta
.
podBestEffort
,
podRequest
:
meta
.
podRequest
,
serviceAffinityInUse
:
meta
.
serviceAffinityInUse
,
ignoredExtendedResources
:
meta
.
ignoredExtendedResources
,
topologyPairsAntiAffinityPodsMap
:
meta
.
topologyPairsAntiAffinityPodsMap
,
pod
:
meta
.
pod
,
podBestEffort
:
meta
.
podBestEffort
,
podRequest
:
meta
.
podRequest
,
serviceAffinityInUse
:
meta
.
serviceAffinityInUse
,
ignoredExtendedResources
:
meta
.
ignoredExtendedResources
,
}
newPredMeta
.
podPorts
=
append
([]
*
v1
.
ContainerPort
(
nil
),
meta
.
podPorts
...
)
newPredMeta
.
nodeNameToMatchingAffinityPods
=
make
(
map
[
string
][]
*
v1
.
Pod
)
for
k
,
v
:=
range
meta
.
nodeNameToMatchingAffinityPods
{
newPredMeta
.
nodeNameToMatchingAffinityPods
[
k
]
=
append
([]
*
v1
.
Pod
(
nil
),
v
...
)
}
newPredMeta
.
nodeNameToMatchingAntiAffinityPods
=
make
(
map
[
string
][]
*
v1
.
Pod
)
for
k
,
v
:=
range
meta
.
nodeNameToMatchingAntiAffinityPods
{
newPredMeta
.
nodeNameToMatchingAntiAffinityPods
[
k
]
=
append
([]
*
v1
.
Pod
(
nil
),
v
...
)
}
newPredMeta
.
topologyPairsPotentialAffinityPods
=
newTopologyPairsMaps
()
newPredMeta
.
topologyPairsPotentialAffinityPods
.
appendMaps
(
meta
.
topologyPairsPotentialAffinityPods
)
newPredMeta
.
topologyPairsPotentialAntiAffinityPods
=
newTopologyPairsMaps
()
newPredMeta
.
topologyPairsPotentialAntiAffinityPods
.
appendMaps
(
meta
.
topologyPairsPotentialAntiAffinityPods
)
newPredMeta
.
topologyPairsAntiAffinityPodsMap
=
newTopologyPairsMaps
()
newPredMeta
.
topologyPairsAntiAffinityPodsMap
.
appendMaps
(
meta
.
topologyPairsAntiAffinityPodsMap
)
newPredMeta
.
serviceAffinityMatchingPodServices
=
append
([]
*
v1
.
Service
(
nil
),
...
...
@@ -373,12 +339,12 @@ func podMatchesAffinityTermProperties(pod *v1.Pod, properties []*affinityTermPro
// It ignores topology. It returns a set of Pods that are checked later by the affinity
// predicate. With this set of pods available, the affinity predicate does not
// need to check all the pods in the cluster.
func
getPodsMatchingAffinity
(
pod
*
v1
.
Pod
,
nodeInfoMap
map
[
string
]
*
schedulercache
.
NodeInfo
)
(
affinityPods
map
[
string
][]
*
v1
.
Pod
,
antiAffinityPods
map
[
string
][]
*
v1
.
Pod
,
err
error
)
{
func
getPodsMatchingAffinity
(
pod
*
v1
.
Pod
,
nodeInfoMap
map
[
string
]
*
schedulercache
.
NodeInfo
)
(
topologyPairsAffinityPodsMaps
*
topologyPairsMaps
,
topologyPairsAntiAffinityPodsMaps
*
topologyPairsMaps
,
err
error
)
{
allNodeNames
:=
make
([]
string
,
0
,
len
(
nodeInfoMap
))
affinity
:=
pod
.
Spec
.
Affinity
if
affinity
==
nil
||
(
affinity
.
PodAffinity
==
nil
&&
affinity
.
PodAntiAffinity
==
nil
)
{
return
n
il
,
nil
,
nil
return
n
ewTopologyPairsMaps
(),
newTopologyPairsMaps
()
,
nil
}
for
name
:=
range
nodeInfoMap
{
...
...
@@ -387,16 +353,16 @@ func getPodsMatchingAffinity(pod *v1.Pod, nodeInfoMap map[string]*schedulercache
var
lock
sync
.
Mutex
var
firstError
error
affinityPods
=
make
(
map
[
string
][]
*
v1
.
Pod
)
antiAffinityPods
=
make
(
map
[
string
][]
*
v1
.
Pod
)
appendResult
:=
func
(
nodeName
string
,
affPods
,
antiAffPods
[]
*
v1
.
Pod
)
{
topologyPairsAffinityPodsMaps
=
newTopologyPairsMaps
(
)
topologyPairsAntiAffinityPodsMaps
=
newTopologyPairsMaps
(
)
appendResult
:=
func
(
nodeName
string
,
nodeTopologyPairsAffinityPodsMaps
,
nodeTopologyPairsAntiAffinityPodsMaps
*
topologyPairsMaps
)
{
lock
.
Lock
()
defer
lock
.
Unlock
()
if
len
(
aff
Pods
)
>
0
{
affinityPods
[
nodeName
]
=
affPods
if
len
(
nodeTopologyPairsAffinityPodsMaps
.
topologyPairTo
Pods
)
>
0
{
topologyPairsAffinityPodsMaps
.
appendMaps
(
nodeTopologyPairsAffinityPodsMaps
)
}
if
len
(
antiAff
Pods
)
>
0
{
antiAffinityPods
[
nodeName
]
=
antiAffPods
if
len
(
nodeTopologyPairsAntiAffinityPodsMaps
.
topologyPairTo
Pods
)
>
0
{
topologyPairsAntiAffinityPodsMaps
.
appendMaps
(
nodeTopologyPairsAntiAffinityPodsMaps
)
}
}
...
...
@@ -417,6 +383,8 @@ func getPodsMatchingAffinity(pod *v1.Pod, nodeInfoMap map[string]*schedulercache
return
nil
,
nil
,
err
}
affinityTerms
:=
GetPodAffinityTerms
(
affinity
.
PodAffinity
)
antiAffinityTerms
:=
GetPodAntiAffinityTerms
(
affinity
.
PodAntiAffinity
)
processNode
:=
func
(
i
int
)
{
nodeInfo
:=
nodeInfoMap
[
allNodeNames
[
i
]]
node
:=
nodeInfo
.
Node
()
...
...
@@ -424,24 +392,34 @@ func getPodsMatchingAffinity(pod *v1.Pod, nodeInfoMap map[string]*schedulercache
catchError
(
fmt
.
Errorf
(
"nodeInfo.Node is nil"
))
return
}
affPods
:=
make
([]
*
v1
.
Pod
,
0
,
len
(
nodeInfo
.
Pods
())
)
antiAffPods
:=
make
([]
*
v1
.
Pod
,
0
,
len
(
nodeInfo
.
Pods
())
)
nodeTopologyPairsAffinityPodsMaps
:=
newTopologyPairsMaps
(
)
nodeTopologyPairsAntiAffinityPodsMaps
:=
newTopologyPairsMaps
(
)
for
_
,
existingPod
:=
range
nodeInfo
.
Pods
()
{
// Check affinity properties.
if
podMatchesAffinityTermProperties
(
existingPod
,
affinityProperties
)
{
affPods
=
append
(
affPods
,
existingPod
)
for
_
,
term
:=
range
affinityTerms
{
if
topologyValue
,
ok
:=
node
.
Labels
[
term
.
TopologyKey
];
ok
{
pair
:=
topologyPair
{
key
:
term
.
TopologyKey
,
value
:
topologyValue
}
nodeTopologyPairsAffinityPodsMaps
.
addTopologyPair
(
pair
,
existingPod
)
}
}
}
// Check anti-affinity properties.
if
podMatchesAffinityTermProperties
(
existingPod
,
antiAffinityProperties
)
{
antiAffPods
=
append
(
antiAffPods
,
existingPod
)
for
_
,
term
:=
range
antiAffinityTerms
{
if
topologyValue
,
ok
:=
node
.
Labels
[
term
.
TopologyKey
];
ok
{
pair
:=
topologyPair
{
key
:
term
.
TopologyKey
,
value
:
topologyValue
}
nodeTopologyPairsAntiAffinityPodsMaps
.
addTopologyPair
(
pair
,
existingPod
)
}
}
}
}
if
len
(
antiAffPods
)
>
0
||
len
(
aff
Pods
)
>
0
{
appendResult
(
node
.
Name
,
affPods
,
antiAffPod
s
)
if
len
(
nodeTopologyPairsAffinityPodsMaps
.
topologyPairToPods
)
>
0
||
len
(
nodeTopologyPairsAntiAffinityPodsMaps
.
topologyPairTo
Pods
)
>
0
{
appendResult
(
node
.
Name
,
nodeTopologyPairsAffinityPodsMaps
,
nodeTopologyPairsAntiAffinityPodsMap
s
)
}
}
workqueue
.
Parallelize
(
16
,
len
(
allNodeNames
),
processNode
)
return
affinityPods
,
antiAffinityPod
s
,
firstError
return
topologyPairsAffinityPodsMaps
,
topologyPairsAntiAffinityPodsMap
s
,
firstError
}
// podMatchesAffinity returns true if "targetPod" matches any affinity rule of
...
...
pkg/scheduler/algorithm/predicates/metadata_test.go
View file @
ac4a082b
...
...
@@ -52,13 +52,6 @@ func (s sortableServices) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
var
_
=
sort
.
Interface
(
&
sortableServices
{})
func
sortNodePodMap
(
np
map
[
string
][]
*
v1
.
Pod
)
{
for
_
,
pl
:=
range
np
{
sortablePods
:=
sortablePods
(
pl
)
sort
.
Sort
(
sortablePods
)
}
}
// predicateMetadataEquivalent returns true if the two metadata are equivalent.
// Note: this function does not compare podRequest.
func
predicateMetadataEquivalent
(
meta1
,
meta2
*
predicateMetadata
)
error
{
...
...
@@ -77,15 +70,11 @@ func predicateMetadataEquivalent(meta1, meta2 *predicateMetadata) error {
for
!
reflect
.
DeepEqual
(
meta1
.
podPorts
,
meta2
.
podPorts
)
{
return
fmt
.
Errorf
(
"podPorts are not equal"
)
}
sortNodePodMap
(
meta1
.
nodeNameToMatchingAffinityPods
)
sortNodePodMap
(
meta2
.
nodeNameToMatchingAffinityPods
)
if
!
reflect
.
DeepEqual
(
meta1
.
nodeNameToMatchingAffinityPods
,
meta2
.
nodeNameToMatchingAffinityPods
)
{
return
fmt
.
Errorf
(
"nodeNameToMatchingAffinityPods are not euqal"
)
if
!
reflect
.
DeepEqual
(
meta1
.
topologyPairsPotentialAffinityPods
,
meta2
.
topologyPairsPotentialAffinityPods
)
{
return
fmt
.
Errorf
(
"topologyPairsPotentialAffinityPods are not equal"
)
}
sortNodePodMap
(
meta1
.
nodeNameToMatchingAntiAffinityPods
)
sortNodePodMap
(
meta2
.
nodeNameToMatchingAntiAffinityPods
)
if
!
reflect
.
DeepEqual
(
meta1
.
nodeNameToMatchingAntiAffinityPods
,
meta2
.
nodeNameToMatchingAntiAffinityPods
)
{
return
fmt
.
Errorf
(
"nodeNameToMatchingAntiAffinityPods are not euqal"
)
if
!
reflect
.
DeepEqual
(
meta1
.
topologyPairsPotentialAntiAffinityPods
,
meta2
.
topologyPairsPotentialAntiAffinityPods
)
{
return
fmt
.
Errorf
(
"topologyPairsPotentialAntiAffinityPods are not equal"
)
}
if
!
reflect
.
DeepEqual
(
meta1
.
topologyPairsAntiAffinityPodsMap
.
podToTopologyPairs
,
meta2
.
topologyPairsAntiAffinityPodsMap
.
podToTopologyPairs
)
{
...
...
@@ -454,42 +443,71 @@ func TestPredicateMetadata_ShallowCopy(t *testing.T) {
},
},
},
nodeNameToMatchingAffinityPods
:
map
[
string
][]
*
v1
.
Pod
{
"nodeA"
:
{
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p1"
,
Labels
:
selector1
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeA"
},
topologyPairsPotentialAffinityPods
:
&
topologyPairsMaps
{
topologyPairToPods
:
map
[
topologyPair
]
podSet
{
{
key
:
"name"
,
value
:
"nodeA"
}
:
{
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p1"
,
Labels
:
selector1
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeA"
},
}
:
struct
{}{},
},
{
key
:
"name"
,
value
:
"nodeC"
}
:
{
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p2"
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeC"
,
},
}
:
struct
{}{},
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p6"
,
Labels
:
selector1
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeC"
},
}
:
struct
{}{},
},
},
"nodeC"
:
{
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p2"
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeC"
,
},
podToTopologyPairs
:
map
[
string
]
topologyPairSet
{
"p1_"
:
{
topologyPair
{
key
:
"name"
,
value
:
"nodeA"
}
:
struct
{}{},
},
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p6"
,
Labels
:
selector1
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeC"
},
"p2_"
:
{
topologyPair
{
key
:
"name"
,
value
:
"nodeC"
}
:
struct
{}{},
},
"p6_"
:
{
topologyPair
{
key
:
"name"
,
value
:
"nodeC"
}
:
struct
{}{},
},
},
},
nodeNameToMatchingAntiAffinityPods
:
map
[
string
][]
*
v1
.
Pod
{
"nodeN"
:
{
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p1"
,
Labels
:
selector1
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeN"
},
},
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p2"
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeM"
,
},
topologyPairsPotentialAntiAffinityPods
:
&
topologyPairsMaps
{
topologyPairToPods
:
map
[
topologyPair
]
podSet
{
{
key
:
"name"
,
value
:
"nodeN"
}
:
{
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p1"
,
Labels
:
selector1
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeN"
},
}
:
struct
{}{},
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p2"
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeM"
,
},
}
:
struct
{}{},
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p3"
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeM"
,
},
}
:
struct
{}{},
},
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p3"
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeM"
,
},
{
key
:
"name"
,
value
:
"nodeM"
}
:
{
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p6"
,
Labels
:
selector1
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeM"
}
,
}
:
struct
{}{}
,
},
},
"nodeM"
:
{
&
v1
.
Pod
{
ObjectMeta
:
metav1
.
ObjectMeta
{
Name
:
"p6"
,
Labels
:
selector1
},
Spec
:
v1
.
PodSpec
{
NodeName
:
"nodeM"
},
podToTopologyPairs
:
map
[
string
]
topologyPairSet
{
"p1_"
:
{
topologyPair
{
key
:
"name"
,
value
:
"nodeN"
}
:
struct
{}{},
},
"p2_"
:
{
topologyPair
{
key
:
"name"
,
value
:
"nodeN"
}
:
struct
{}{},
},
"p3_"
:
{
topologyPair
{
key
:
"name"
,
value
:
"nodeN"
}
:
struct
{}{},
},
"p6_"
:
{
topologyPair
{
key
:
"name"
,
value
:
"nodeM"
}
:
struct
{}{},
},
},
},
...
...
pkg/scheduler/algorithm/predicates/predicates.go
View file @
ac4a082b
...
...
@@ -1395,23 +1395,16 @@ func (c *PodAffinityChecker) satisfiesExistingPodsAntiAffinity(pod *v1.Pod, meta
// anyPodsMatchingTopologyTerms checks whether any of the nodes given via
// "targetPods" matches topology of all the "terms" for the give "pod" and "nodeInfo".
func
(
c
*
PodAffinityChecker
)
anyPodsMatchingTopologyTerms
(
pod
*
v1
.
Pod
,
targetPods
map
[
string
][]
*
v1
.
Pod
,
nodeInfo
*
schedulercache
.
NodeInfo
,
terms
[]
v1
.
PodAffinityTerm
)
(
bool
,
error
)
{
for
nodeName
,
targetPods
:=
range
targetPods
{
targetPodNodeInfo
,
err
:=
c
.
info
.
GetNodeInfo
(
nodeName
)
if
err
!=
nil
{
return
false
,
err
}
if
len
(
targetPods
)
>
0
{
allTermsMatched
:=
true
for
_
,
term
:=
range
terms
{
if
!
priorityutil
.
NodesHaveSameTopologyKey
(
nodeInfo
.
Node
(),
targetPodNodeInfo
,
term
.
TopologyKey
)
{
allTermsMatched
=
false
break
}
}
if
allTermsMatched
{
// We have 1 or more pods on the target node that have already matched namespace and selector
// and all of the terms topologies matched the target node. So, there is at least 1 matching pod on the node.
func
(
c
*
PodAffinityChecker
)
anyPodsMatchingTopologyTerms
(
pod
*
v1
.
Pod
,
targetPods
*
topologyPairsMaps
,
nodeInfo
*
schedulercache
.
NodeInfo
,
terms
[]
v1
.
PodAffinityTerm
)
(
bool
,
error
)
{
podNameToMatchingTermsCount
:=
make
(
map
[
string
]
int
)
node
:=
nodeInfo
.
Node
()
podTermsCount
:=
len
(
terms
)
for
_
,
term
:=
range
terms
{
pair
:=
topologyPair
{
key
:
term
.
TopologyKey
,
value
:
node
.
Labels
[
term
.
TopologyKey
]}
for
existingPod
:=
range
targetPods
.
topologyPairToPods
[
pair
]
{
existingPodFullName
:=
schedutil
.
GetPodFullName
(
existingPod
)
podNameToMatchingTermsCount
[
existingPodFullName
]
=
podNameToMatchingTermsCount
[
existingPodFullName
]
+
1
if
podNameToMatchingTermsCount
[
existingPodFullName
]
==
podTermsCount
{
return
true
,
nil
}
}
...
...
@@ -1429,7 +1422,7 @@ func (c *PodAffinityChecker) satisfiesPodsAffinityAntiAffinity(pod *v1.Pod,
}
if
predicateMeta
,
ok
:=
meta
.
(
*
predicateMetadata
);
ok
{
// Check all affinity terms.
matchingPods
:=
predicateMeta
.
nodeNameToMatching
AffinityPods
matchingPods
:=
predicateMeta
.
topologyPairsPotential
AffinityPods
if
affinityTerms
:=
GetPodAffinityTerms
(
affinity
.
PodAffinity
);
len
(
affinityTerms
)
>
0
{
matchExists
,
err
:=
c
.
anyPodsMatchingTopologyTerms
(
pod
,
matchingPods
,
nodeInfo
,
affinityTerms
)
if
err
!=
nil
{
...
...
@@ -1442,7 +1435,7 @@ func (c *PodAffinityChecker) satisfiesPodsAffinityAntiAffinity(pod *v1.Pod,
// to not leave such pods in pending state forever, we check that if no other pod
// in the cluster matches the namespace and selector of this pod and the pod matches
// its own terms, then we allow the pod to pass the affinity check.
if
!
(
len
(
matchingPods
)
==
0
&&
targetPodMatchesAffinityOfPod
(
pod
,
pod
))
{
if
!
(
len
(
matchingPods
.
topologyPairToPods
)
==
0
&&
targetPodMatchesAffinityOfPod
(
pod
,
pod
))
{
glog
.
V
(
10
)
.
Infof
(
"Cannot schedule pod %+v onto node %v, because of PodAffinity"
,
podName
(
pod
),
node
.
Name
)
return
ErrPodAffinityRulesNotMatch
,
nil
...
...
@@ -1451,7 +1444,7 @@ func (c *PodAffinityChecker) satisfiesPodsAffinityAntiAffinity(pod *v1.Pod,
}
// Check all anti-affinity terms.
matchingPods
=
predicateMeta
.
nodeNameToMatching
AntiAffinityPods
matchingPods
=
predicateMeta
.
topologyPairsPotential
AntiAffinityPods
if
antiAffinityTerms
:=
GetPodAntiAffinityTerms
(
affinity
.
PodAntiAffinity
);
len
(
antiAffinityTerms
)
>
0
{
matchExists
,
err
:=
c
.
anyPodsMatchingTopologyTerms
(
pod
,
matchingPods
,
nodeInfo
,
antiAffinityTerms
)
if
err
!=
nil
||
matchExists
{
...
...
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