mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-04 09:49:50 +00:00
Return a status cause for disruption budget that contains more details
Also uses the standard error constructor for TooManyRequests and clarifies *why* a disruption is rejected.
This commit is contained in:
parent
74f6669b49
commit
1b8f24c9a8
@ -101,24 +101,9 @@ func (r *EvictionREST) Create(ctx genericapirequest.Context, obj runtime.Object,
|
||||
|
||||
// If it was false already, or if it becomes false during the course of our retries,
|
||||
// raise an error marked as a 429.
|
||||
ok, err := r.checkAndDecrement(pod.Namespace, pod.Name, pdb)
|
||||
if err != nil {
|
||||
if err := r.checkAndDecrement(pod.Namespace, pod.Name, pdb); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
rtStatus = &metav1.Status{
|
||||
Status: metav1.StatusFailure,
|
||||
// TODO(mml): Include some more details about why the eviction is disallowed.
|
||||
// Ideally any such text is generated by the DisruptionController (offline).
|
||||
Message: "Cannot evict pod as it would violate the pod's disruption budget.",
|
||||
Code: 429,
|
||||
// TODO(mml): Add a Retry-After header. Once there are time-based
|
||||
// budgets, we can sometimes compute a sensible suggested value. But
|
||||
// even without that, we can give a suggestion (10 minutes?) that
|
||||
// prevents well-behaved clients from hammering us.
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@ -146,19 +131,28 @@ func (r *EvictionREST) Create(ctx genericapirequest.Context, obj runtime.Object,
|
||||
}
|
||||
|
||||
// checkAndDecrement checks if the provided PodDisruptionBudget allows any disruption.
|
||||
func (r *EvictionREST) checkAndDecrement(namespace string, podName string, pdb policy.PodDisruptionBudget) (ok bool, err error) {
|
||||
func (r *EvictionREST) checkAndDecrement(namespace string, podName string, pdb policy.PodDisruptionBudget) error {
|
||||
if pdb.Status.ObservedGeneration < pdb.Generation {
|
||||
return false, nil
|
||||
// TODO(mml): Add a Retry-After header. Once there are time-based
|
||||
// budgets, we can sometimes compute a sensible suggested value. But
|
||||
// even without that, we can give a suggestion (10 minutes?) that
|
||||
// prevents well-behaved clients from hammering us.
|
||||
err := errors.NewTooManyRequests("Cannot evict pod as it would violate the pod's disruption budget.", 0)
|
||||
err.ErrStatus.Details.Causes = append(err.ErrStatus.Details.Causes, metav1.StatusCause{Type: "DisruptionBudget", Message: fmt.Sprintf("The disruption budget %s is still being processed by the server.", pdb.Name)})
|
||||
return err
|
||||
}
|
||||
if pdb.Status.PodDisruptionsAllowed < 0 {
|
||||
return false, errors.NewForbidden(policy.Resource("poddisruptionbudget"), pdb.Name, fmt.Errorf("pdb disruptions allowed is negative"))
|
||||
return errors.NewForbidden(policy.Resource("poddisruptionbudget"), pdb.Name, fmt.Errorf("pdb disruptions allowed is negative"))
|
||||
}
|
||||
if len(pdb.Status.DisruptedPods) > MaxDisruptedPodSize {
|
||||
return false, errors.NewForbidden(policy.Resource("poddisruptionbudget"), pdb.Name, fmt.Errorf("DisrputedPods map too big - too many evictions not confirmed by PDB controller"))
|
||||
return errors.NewForbidden(policy.Resource("poddisruptionbudget"), pdb.Name, fmt.Errorf("DisruptedPods map too big - too many evictions not confirmed by PDB controller"))
|
||||
}
|
||||
if pdb.Status.PodDisruptionsAllowed == 0 {
|
||||
return false, nil
|
||||
err := errors.NewTooManyRequests("Cannot evict pod as it would violate the pod's disruption budget.", 0)
|
||||
err.ErrStatus.Details.Causes = append(err.ErrStatus.Details.Causes, metav1.StatusCause{Type: "DisruptionBudget", Message: fmt.Sprintf("The disruption budget %s needs %d healthy pods and has %d currently", pdb.Name, pdb.Status.DesiredHealthy, pdb.Status.CurrentHealthy)})
|
||||
return err
|
||||
}
|
||||
|
||||
pdb.Status.PodDisruptionsAllowed--
|
||||
if pdb.Status.DisruptedPods == nil {
|
||||
pdb.Status.DisruptedPods = make(map[string]metav1.Time)
|
||||
@ -169,10 +163,10 @@ func (r *EvictionREST) checkAndDecrement(namespace string, podName string, pdb p
|
||||
// be deleted at all and remove it from DisruptedPod map.
|
||||
pdb.Status.DisruptedPods[podName] = metav1.Time{Time: time.Now()}
|
||||
if _, err := r.podDisruptionBudgetClient.PodDisruptionBudgets(namespace).UpdateStatus(&pdb); err != nil {
|
||||
return false, err
|
||||
return err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// getPodDisruptionBudgets returns any PDBs that match the pod or err if there's an error.
|
||||
|
Loading…
Reference in New Issue
Block a user