Skip to content

Commit 8d2a2ff

Browse files
committed
Handle eviction of pods in deleted namespace
If a pod is already marked deleted, and the eviction api returns an unauthorized response, ignore that error since the pod is marked for deletion already. If the pod is not already marked deleted, retry.
1 parent 93f62da commit 8d2a2ff

File tree

1 file changed

+26
-5
lines changed
  • staging/src/k8s.io/kubectl/pkg/drain

1 file changed

+26
-5
lines changed

staging/src/k8s.io/kubectl/pkg/drain/drain.go

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ func (d *Helper) evictPods(pods []corev1.Pod, policyGroupVersion string, getPodF
254254
defer cancel()
255255
for _, pod := range pods {
256256
go func(pod corev1.Pod, returnCh chan error) {
257+
refreshPod := false
257258
for {
258259
switch d.DryRunStrategy {
259260
case cmdutil.DryRunServer:
@@ -268,20 +269,40 @@ func (d *Helper) evictPods(pods []corev1.Pod, policyGroupVersion string, getPodF
268269
return
269270
default:
270271
}
271-
err := d.EvictPod(pod, policyGroupVersion)
272+
273+
// Create a temporary pod so we don't mutate the pod in the loop.
274+
activePod := pod
275+
if refreshPod {
276+
freshPod, err := getPodFn(pod.Namespace, pod.Name)
277+
// We ignore errors and let eviction sort it out with
278+
// the original pod.
279+
if err == nil {
280+
activePod = *freshPod
281+
}
282+
refreshPod = false
283+
}
284+
285+
err := d.EvictPod(activePod, policyGroupVersion)
272286
if err == nil {
273287
break
274288
} else if apierrors.IsNotFound(err) {
275289
returnCh <- nil
276290
return
277291
} else if apierrors.IsTooManyRequests(err) {
278-
fmt.Fprintf(d.ErrOut, "error when evicting pods/%q -n %q (will retry after 5s): %v\n", pod.Name, pod.Namespace, err)
292+
fmt.Fprintf(d.ErrOut, "error when evicting pods/%q -n %q (will retry after 5s): %v\n", activePod.Name, activePod.Namespace, err)
279293
time.Sleep(5 * time.Second)
280-
} else if apierrors.IsForbidden(err) {
281-
// an eviction request in a deleting namespace will throw a forbidden error
294+
} else if !activePod.ObjectMeta.DeletionTimestamp.IsZero() && apierrors.IsForbidden(err) && apierrors.HasStatusCause(err, corev1.NamespaceTerminatingCause) {
295+
// an eviction request in a deleting namespace will throw a forbidden error,
296+
// if the pod is already marked deleted, we can ignore this error, an eviction
297+
// request will never succeed, but we will waitForDelete for this pod.
282298
break
299+
} else if apierrors.IsForbidden(err) && apierrors.HasStatusCause(err, corev1.NamespaceTerminatingCause) {
300+
// an eviction request in a deleting namespace will throw a forbidden error,
301+
// if the pod is not marked deleted, we retry until it is.
302+
fmt.Fprintf(d.ErrOut, "error when evicting pod %q (will retry after 5s): %v\n", activePod.Name, err)
303+
time.Sleep(5 * time.Second)
283304
} else {
284-
returnCh <- fmt.Errorf("error when evicting pods/%q -n %q: %v", pod.Name, pod.Namespace, err)
305+
returnCh <- fmt.Errorf("error when evicting pods/%q -n %q: %v", activePod.Name, activePod.Namespace, err)
285306
return
286307
}
287308
}

0 commit comments

Comments
 (0)