Code change:
func TestCheckGracefulDelete(t *testing.T) { defaultGracePeriod := int64(30) tcs := []struct { <del> in          *api.Pod gracePeriod int64 </del> <ins> name              string pod               *api.Pod deleteGracePeriod *int64 gracePeriod       int64 </ins> }{ { <del> in: &api.Pod{ </del> <ins> name: "in pending phase with has node name", pod: &api.Pod{ </ins> Spec:   api.PodSpec{NodeName: "something"}, Status: api.PodStatus{Phase: api.PodPending}, }, <del> gracePeriod: defaultGracePeriod, </del> <ins> deleteGracePeriod: &defaultGracePeriod, gracePeriod:       defaultGracePeriod, </ins> }, { <del> in: &api.Pod{ </del> <ins> name: "in failed phase with has node name", pod: &api.Pod{ </ins> Spec:   api.PodSpec{NodeName: "something"}, Status: api.PodStatus{Phase: api.PodFailed}, }, <del> gracePeriod: 0, </del> <ins> deleteGracePeriod: &defaultGracePeriod, gracePeriod:       0, </ins> }, { <del> in: &api.Pod{ </del> <ins> name: "in failed phase", pod: &api.Pod{ </ins> Spec:   api.PodSpec{}, Status: api.PodStatus{Phase: api.PodPending}, }, <del> gracePeriod: 0, </del> <ins> deleteGracePeriod: &defaultGracePeriod, gracePeriod:       0, </ins> }, { <del> in: &api.Pod{ </del> <ins> name: "in succeeded phase", pod: &api.Pod{ </ins> Spec:   api.PodSpec{}, Status: api.PodStatus{Phase: api.PodSucceeded}, }, <del> gracePeriod: 0, </del> <ins> deleteGracePeriod: &defaultGracePeriod, gracePeriod:       0, </ins> }, { <del> in: &api.Pod{ </del> <ins> name: "no phase", pod: &api.Pod{ </ins> Spec:   api.PodSpec{}, Status: api.PodStatus{}, }, <del> gracePeriod: 0, </del> <ins> deleteGracePeriod: &defaultGracePeriod, gracePeriod:       0, }, { name: "has negative grace period", pod: &api.Pod{ Spec: api.PodSpec{ NodeName:                      "something", TerminationGracePeriodSeconds: utilpointer.Int64(-1), }, Status: api.PodStatus{}, }, gracePeriod: 1, </ins> }, } for _, tc := range tcs { <del> out := &metav1.DeleteOptions{GracePeriodSeconds: &defaultGracePeriod} Strategy.CheckGracefulDelete(genericapirequest.NewContext(), tc.in, out) if out.GracePeriodSeconds == nil { t.Errorf("out grace period was nil but supposed to be %v", tc.gracePeriod) } if *(out.GracePeriodSeconds) != tc.gracePeriod { t.Errorf("out grace period was %v but was expected to be %v", *out, tc.gracePeriod) } </del> <ins> t.Run(tc.name, func(t *testing.T) { out := &metav1.DeleteOptions{} if tc.deleteGracePeriod != nil { out.GracePeriodSeconds = utilpointer.Int64(*tc.deleteGracePeriod) } Strategy.CheckGracefulDelete(genericapirequest.NewContext(), tc.pod, out) if out.GracePeriodSeconds == nil { t.Errorf("out grace period was nil but supposed to be %v", tc.gracePeriod) } if *(out.GracePeriodSeconds) != tc.gracePeriod { t.Errorf("out grace period was %v but was expected to be %v", *out, tc.gracePeriod) } }) </ins> } }

Related discussion:
text: <!-- Please use this template while reporting a bug and provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. Thanks! If the matter is security related, please disclose it privately via --What happened: Some k8s client tried to evict a pod by setting negative value for deletionGracePeriodSeconds. But all eventual delete calls (and force-delete calls) made by kubelet, pod-garbage-collector, etc were not able to delete that pod, because apiserver doesnt allow deletionGracePeriodSeconds to be increased once it is set. So force-delete (which set it to 0) doesn't take effect when it's already negative. Not even kubectl is able to call delete with negative grace-period. But curl with an even more negative grace-period value worked. What you expected to happen: force-delete works. How to reproduce it (as minimally and precisely as possible): Anything else we need to know?: I think the issue is in the code below As the comment suggest, in phase 1, the was set to a negative value (meaning was in the past), and in phase 2, has to be set even lower, otherwise, it will be considered as pending graceful deletion and not performing the immediate delete. I think there're two possible fixes. not allowing setting in the past ( should be non-negative). In that case, we could convert to 0 if negative. that could be set in the past. In that case, in phase 2, we treat negative value of the same as 0, and allow immediate delete. Thoughts? Environment: Kubernetes version (use ): Cloud provider or hardware configuration: OS (e.g: ): Kernel (e.g. ): Install tools: Network plugin and version (if this is a network-related bug): Others:
/sig api-machinery
The label(s) cannot be applied, because the repository doesn't have them <detailsIn response to : /sig api-machinery Instructions for interacting with me using PR comments are available . If you have questions or suggestions related to my behavior, please file an issue against the repository. </details
/assign
/cc /triage accepted
No component in the system should ever treat the timestamp of DeletionTimestamp as authoritative.