update inter-pod affinity predicates, check PodAntiAffinity even when pod has no AntiAffinity constraints
This commit is contained in:
@@ -925,7 +925,7 @@ func (checker *PodAffinityChecker) NodeMatchesHardPodAffinity(pod *api.Pod, allP
|
|||||||
// break any existing pods' anti-affinity rules, then return true.
|
// break any existing pods' anti-affinity rules, then return true.
|
||||||
func (checker *PodAffinityChecker) NodeMatchesHardPodAntiAffinity(pod *api.Pod, allPods []*api.Pod, node *api.Node, podAntiAffinity *api.PodAntiAffinity) bool {
|
func (checker *PodAffinityChecker) NodeMatchesHardPodAntiAffinity(pod *api.Pod, allPods []*api.Pod, node *api.Node, podAntiAffinity *api.PodAntiAffinity) bool {
|
||||||
var podAntiAffinityTerms []api.PodAffinityTerm
|
var podAntiAffinityTerms []api.PodAffinityTerm
|
||||||
if len(podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution) != 0 {
|
if podAntiAffinity != nil && len(podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution) != 0 {
|
||||||
podAntiAffinityTerms = podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution
|
podAntiAffinityTerms = podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution
|
||||||
}
|
}
|
||||||
// TODO: Uncomment this block when implement RequiredDuringSchedulingRequiredDuringExecution.
|
// TODO: Uncomment this block when implement RequiredDuringSchedulingRequiredDuringExecution.
|
||||||
@@ -999,19 +999,15 @@ func (checker *PodAffinityChecker) NodeMatchPodAffinityAntiAffinity(pod *api.Pod
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if the current node match the inter-pod affinity scheduling rules.
|
// check if the current node match the inter-pod affinity scheduling rules.
|
||||||
|
// hard inter-pod affinity is not symmetric, check only when affinity.PodAffinity is not nil.
|
||||||
if affinity.PodAffinity != nil {
|
if affinity.PodAffinity != nil {
|
||||||
if !checker.NodeMatchesHardPodAffinity(pod, allPods, node, affinity.PodAffinity) {
|
if !checker.NodeMatchesHardPodAffinity(pod, allPods, node, affinity.PodAffinity) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the current node match the inter-pod anti-affinity scheduling rules.
|
// hard inter-pod anti-affinity is symmetric, check both when affinity.PodAntiAffinity is nil and not nil.
|
||||||
if affinity.PodAntiAffinity != nil {
|
return checker.NodeMatchesHardPodAntiAffinity(pod, allPods, node, affinity.PodAntiAffinity)
|
||||||
if !checker.NodeMatchesHardPodAntiAffinity(pod, allPods, node, affinity.PodAntiAffinity) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func PodToleratesNodeTaints(pod *api.Pod, meta interface{}, nodeInfo *schedulercache.NodeInfo) (bool, error) {
|
func PodToleratesNodeTaints(pod *api.Pod, meta interface{}, nodeInfo *schedulercache.NodeInfo) (bool, error) {
|
||||||
|
@@ -2254,6 +2254,62 @@ func TestInterPodAffinity(t *testing.T) {
|
|||||||
fits: false,
|
fits: false,
|
||||||
test: "pod matches its own Label in PodAffinity and that matches the existing pod Labels",
|
test: "pod matches its own Label in PodAffinity and that matches the existing pod Labels",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
pod: &api.Pod{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Labels: podLabel,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pods: []*api.Pod{{Spec: api.PodSpec{NodeName: "machine1"},
|
||||||
|
ObjectMeta: api.ObjectMeta{Labels: podLabel,
|
||||||
|
Annotations: map[string]string{
|
||||||
|
api.AffinityAnnotationKey: `
|
||||||
|
{"PodAntiAffinity": {
|
||||||
|
"requiredDuringSchedulingIgnoredDuringExecution": [{
|
||||||
|
"labelSelector": {
|
||||||
|
"matchExpressions": [{
|
||||||
|
"key": "service",
|
||||||
|
"operator": "In",
|
||||||
|
"values": ["securityscan", "value2"]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"topologyKey": "zone"
|
||||||
|
}]
|
||||||
|
}}`,
|
||||||
|
}},
|
||||||
|
}},
|
||||||
|
node: &node1,
|
||||||
|
fits: false,
|
||||||
|
test: "verify that PodAntiAffinity from existing pod is respected when pod has no AntiAffinity constraints. doesn't satisfy PodAntiAffinity symmetry with the existing pod",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pod: &api.Pod{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Labels: podLabel,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pods: []*api.Pod{{Spec: api.PodSpec{NodeName: "machine1"},
|
||||||
|
ObjectMeta: api.ObjectMeta{Labels: podLabel,
|
||||||
|
Annotations: map[string]string{
|
||||||
|
api.AffinityAnnotationKey: `
|
||||||
|
{"PodAntiAffinity": {
|
||||||
|
"requiredDuringSchedulingIgnoredDuringExecution": [{
|
||||||
|
"labelSelector": {
|
||||||
|
"matchExpressions": [{
|
||||||
|
"key": "service",
|
||||||
|
"operator": "NotIn",
|
||||||
|
"values": ["securityscan", "value2"]
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"topologyKey": "zone"
|
||||||
|
}]
|
||||||
|
}}`,
|
||||||
|
}},
|
||||||
|
}},
|
||||||
|
node: &node1,
|
||||||
|
fits: true,
|
||||||
|
test: "verify that PodAntiAffinity from existing pod is respected when pod has no AntiAffinity constraints. satisfy PodAntiAffinity symmetry with the existing pod",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
node := test.node
|
node := test.node
|
||||||
|
Reference in New Issue
Block a user