Skip to content

Commit f96deba

Browse files
authored
Merge pull request kubernetes#93947 from mgugino-upstream-stage/fix-drain-forbidden
Fix drain forbidden
2 parents 8e29d95 + 8d2a2ff commit f96deba

File tree

1 file changed

+27
-3
lines changed
  • staging/src/k8s.io/kubectl/pkg/drain

1 file changed

+27
-3
lines changed

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

Lines changed: 27 additions & 3 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,17 +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)
293+
time.Sleep(5 * time.Second)
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.
298+
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)
279303
time.Sleep(5 * time.Second)
280304
} else {
281-
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)
282306
return
283307
}
284308
}

0 commit comments

Comments
 (0)