mirror of
https://github.com/kubernetes/kubernetes.git
synced 2026-02-18 18:28:18 -05:00
Merge pull request #135325 from brejman/issue-134393
Fix queue hint for inter-pod anti-affinity
This commit is contained in:
commit
285eb9fdba
3 changed files with 86 additions and 8 deletions
|
|
@ -220,15 +220,27 @@ func (pl *InterPodAffinity) isSchedulableAfterPodChange(logger klog.Logger, pod
|
|||
return fwk.QueueSkip, nil
|
||||
}
|
||||
|
||||
// Pod is deleted. Return Queue when the deleted pod matching the target pod's anti-affinity.
|
||||
if !podMatchesAllAffinityTerms(antiTerms, originalPod) {
|
||||
logger.V(5).Info("a scheduled pod was deleted but it doesn't match the target pod's anti-affinity",
|
||||
"pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod))
|
||||
return fwk.QueueSkip, nil
|
||||
// Pod is deleted. Return Queue when the deleted pod matches the target pod's anti-affinity or vice versa.
|
||||
|
||||
if podMatchesAllAffinityTerms(antiTerms, originalPod) {
|
||||
logger.V(5).Info("a scheduled pod was deleted and it matches the target pod's anti-affinity. The pod may be schedulable now",
|
||||
"pod", klog.KObj(pod), "originalPod", klog.KObj(originalPod))
|
||||
return fwk.Queue, nil
|
||||
}
|
||||
logger.V(5).Info("a scheduled pod was deleted and it matches the target pod's anti-affinity. The pod may be schedulable now",
|
||||
"pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod))
|
||||
return fwk.Queue, nil
|
||||
|
||||
originalPodAntiTerms, err := fwk.GetAffinityTerms(originalPod, fwk.GetPodAntiAffinityTerms(originalPod.Spec.Affinity))
|
||||
if err != nil {
|
||||
return fwk.Queue, err
|
||||
}
|
||||
if podMatchesAllAffinityTerms(originalPodAntiTerms, pod) {
|
||||
logger.V(5).Info("a scheduled pod was deleted and the target pod matches the deleted pod's anti-affinity. The pod may be schedulable now",
|
||||
"pod", klog.KObj(pod), "originalPod", klog.KObj(originalPod))
|
||||
return fwk.Queue, nil
|
||||
}
|
||||
|
||||
logger.V(5).Info("a scheduled pod was deleted but it doesn't match the target pod's anti-affinity, nor vice versa",
|
||||
"pod", klog.KObj(pod), "originalPod", klog.KObj(originalPod))
|
||||
return fwk.QueueSkip, nil
|
||||
}
|
||||
|
||||
func (pl *InterPodAffinity) isSchedulableAfterNodeChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (fwk.QueueingHint, error) {
|
||||
|
|
|
|||
|
|
@ -129,6 +129,24 @@ func Test_isSchedulableAfterPodChange(t *testing.T) {
|
|||
oldPod: st.MakePod().Node("fake-node").Label("service", "securityscan").Obj(),
|
||||
expectedHint: fwk.Queue,
|
||||
},
|
||||
{
|
||||
name: "delete a pod with anti-affinity that matches pending pod",
|
||||
pod: st.MakePod().Name("p").Label("service", "securityscan").Obj(),
|
||||
oldPod: st.MakePod().Node("fake-node").PodAntiAffinityIn("service", "region", []string{"securityscan", "value2"}, st.PodAntiAffinityWithRequiredReq).Obj(),
|
||||
expectedHint: fwk.Queue,
|
||||
},
|
||||
{
|
||||
name: "delete a pod with anti-affinity that doesn't match pending pod",
|
||||
pod: st.MakePod().Name("p").Label("service", "foo").Obj(),
|
||||
oldPod: st.MakePod().Node("fake-node").PodAntiAffinityIn("service", "region", []string{"securityscan", "value2"}, st.PodAntiAffinityWithRequiredReq).Obj(),
|
||||
expectedHint: fwk.QueueSkip,
|
||||
},
|
||||
{
|
||||
name: "delete a pod which doesn't match pending pod's anti-affinity and has anti-affinity that doesn't match pending pod",
|
||||
pod: st.MakePod().Name("p").PodAntiAffinityIn("service", "region", []string{"securityscan", "value2"}, st.PodAntiAffinityWithRequiredReq).Label("service", "foo").Obj(),
|
||||
oldPod: st.MakePod().Node("fake-node").PodAntiAffinityIn("service", "region", []string{"securityscan", "value2"}, st.PodAntiAffinityWithRequiredReq).Label("service", "foo").Obj(),
|
||||
expectedHint: fwk.QueueSkip,
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -682,6 +682,54 @@ var CoreResourceEnqueueTestCases = []*CoreResourceEnqueueTestCase{
|
|||
WantRequeuedPods: sets.New("pod2"),
|
||||
EnableSchedulingQueueHint: sets.New(true),
|
||||
},
|
||||
{
|
||||
Name: "Pod rejected by the InterPodAffinity plugin is requeued when deleting the existing pod that matches the target podAntiAffinity",
|
||||
EnablePlugins: []string{names.InterPodAffinity},
|
||||
InitialNodes: []*v1.Node{st.MakeNode().Name("fake-node").Label("node", "fake-node").Obj()},
|
||||
InitialPods: []*v1.Pod{
|
||||
st.MakePod().Name("pod1").Label("anti1", "anti1").Container("image").Node("fake-node").Obj(),
|
||||
st.MakePod().Name("pod2").Label("anti2", "anti2").Container("image").Node("fake-node").Obj(),
|
||||
},
|
||||
Pods: []*v1.Pod{
|
||||
// - Pod3 and pod4 will be rejected by the PodAffinity plugin.
|
||||
st.MakePod().Name("pod3").Label("anti1", "anti1").PodAntiAffinityExists("anti1", "node", st.PodAntiAffinityWithRequiredReq).Container("image").Obj(),
|
||||
st.MakePod().Name("pod4").Label("anti2", "anti2").PodAntiAffinityExists("anti2", "node", st.PodAntiAffinityWithRequiredReq).Container("image").Obj(),
|
||||
},
|
||||
|
||||
TriggerFn: func(testCtx *testutils.TestContext) (map[fwk.ClusterEvent]uint64, error) {
|
||||
// Delete pod1 which will make pod3 schedulable because pod3's antiAffinity won't match pod1 anymore.
|
||||
if err := testCtx.ClientSet.CoreV1().Pods(testCtx.NS.Name).Delete(testCtx.Ctx, "pod1", metav1.DeleteOptions{GracePeriodSeconds: new(int64)}); err != nil {
|
||||
return nil, fmt.Errorf("failed to delete pod1: %w", err)
|
||||
}
|
||||
return map[fwk.ClusterEvent]uint64{{Resource: assignedPod, ActionType: fwk.Delete}: 1}, nil
|
||||
},
|
||||
WantRequeuedPods: sets.New("pod3"),
|
||||
EnableSchedulingQueueHint: sets.New(true),
|
||||
},
|
||||
{
|
||||
Name: "Pod rejected by the InterPodAffinity plugin is requeued when deleting the existing pod with podAntiAffinity that matches the target pod",
|
||||
EnablePlugins: []string{names.InterPodAffinity},
|
||||
InitialNodes: []*v1.Node{st.MakeNode().Name("fake-node").Label("node", "fake-node").Obj()},
|
||||
InitialPods: []*v1.Pod{
|
||||
st.MakePod().Name("pod1").PodAntiAffinityExists("anti1", "node", st.PodAntiAffinityWithRequiredReq).Container("image").Node("fake-node").Obj(),
|
||||
st.MakePod().Name("pod2").PodAntiAffinityExists("anti2", "node", st.PodAntiAffinityWithRequiredReq).Container("image").Node("fake-node").Obj(),
|
||||
},
|
||||
Pods: []*v1.Pod{
|
||||
// - Pod3 and pod4 will be rejected by the PodAffinity plugin.
|
||||
st.MakePod().Name("pod3").Label("anti1", "anti1").Container("image").Obj(),
|
||||
st.MakePod().Name("pod4").Label("anti2", "anti2").Container("image").Obj(),
|
||||
},
|
||||
|
||||
TriggerFn: func(testCtx *testutils.TestContext) (map[fwk.ClusterEvent]uint64, error) {
|
||||
// Delete pod1 which will make pod3 schedulable because pod1's antiAffinity won't match pod3 anymore.
|
||||
if err := testCtx.ClientSet.CoreV1().Pods(testCtx.NS.Name).Delete(testCtx.Ctx, "pod1", metav1.DeleteOptions{GracePeriodSeconds: new(int64)}); err != nil {
|
||||
return nil, fmt.Errorf("failed to delete pod1: %w", err)
|
||||
}
|
||||
return map[fwk.ClusterEvent]uint64{{Resource: assignedPod, ActionType: fwk.Delete}: 1}, nil
|
||||
},
|
||||
WantRequeuedPods: sets.New("pod3"),
|
||||
EnableSchedulingQueueHint: sets.New(true),
|
||||
},
|
||||
{
|
||||
Name: "Pod rejected by the PodAffinity plugin is requeued when updating the existed pod's label to make it match the pod's podAffinity",
|
||||
EnablePlugins: []string{names.InterPodAffinity},
|
||||
|
|
|
|||
Loading…
Reference in a new issue