Merge pull request #28874 from kevin-wangzefeng/fix-interpod-antiaffinity

Automatic merge from submit-queue

check PodAntiAffinity even when pod has no AntiAffinity constraints

Hard inter-pod anti-affinity is designed to be symmetric, in other word, the algorithm should check if AntiAffinity constraints from both the pod to be scheduled and pods already running are satisfied during scheduling.

Current implementation skipped the checking when pod has no AntiAffinity constraints, ignored the anti-affinity constraints of existing pods , which is not correct. This PR is to fix it.
This commit is contained in:
k8s-merge-robot 2016-07-12 22:33:57 -07:00 committed by GitHub
commit ec47f5c926
2 changed files with 60 additions and 8 deletions

View File

@ -925,7 +925,7 @@ func (checker *PodAffinityChecker) NodeMatchesHardPodAffinity(pod *api.Pod, allP
// 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 {
var podAntiAffinityTerms []api.PodAffinityTerm
if len(podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution) != 0 {
if podAntiAffinity != nil && len(podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution) != 0 {
podAntiAffinityTerms = podAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution
}
// 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.
// hard inter-pod affinity is not symmetric, check only when affinity.PodAffinity is not nil.
if affinity.PodAffinity != nil {
if !checker.NodeMatchesHardPodAffinity(pod, allPods, node, affinity.PodAffinity) {
return false
}
}
// check if the current node match the inter-pod anti-affinity scheduling rules.
if affinity.PodAntiAffinity != nil {
if !checker.NodeMatchesHardPodAntiAffinity(pod, allPods, node, affinity.PodAntiAffinity) {
return false
}
}
return true
// hard inter-pod anti-affinity is symmetric, check both when affinity.PodAntiAffinity is nil and not nil.
return checker.NodeMatchesHardPodAntiAffinity(pod, allPods, node, affinity.PodAntiAffinity)
}
func PodToleratesNodeTaints(pod *api.Pod, meta interface{}, nodeInfo *schedulercache.NodeInfo) (bool, error) {

View File

@ -2254,6 +2254,62 @@ func TestInterPodAffinity(t *testing.T) {
fits: false,
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 {
node := test.node