Add conditions to PDB status

This commit is contained in:
Morten Torkildsen
2021-03-03 19:40:47 -08:00
parent 466e730259
commit 1e2a7f381f
11 changed files with 424 additions and 29 deletions

View File

@@ -49,6 +49,7 @@ import (
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/workqueue"
pdbhelper "k8s.io/component-helpers/apps/poddisruptionbudget"
"k8s.io/klog/v2"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/controller"
@@ -63,7 +64,9 @@ import (
// If the controller is running on a different node it is important that the two nodes have synced
// clock (via ntp for example). Otherwise PodDisruptionBudget controller may not provide enough
// protection against unwanted pod disruptions.
const DeletionTimeout = 2 * 60 * time.Second
const (
DeletionTimeout = 2 * 60 * time.Second
)
type updater func(*policy.PodDisruptionBudget) error
@@ -579,7 +582,7 @@ func (dc *DisruptionController) sync(key string) error {
}
if err != nil {
klog.Errorf("Failed to sync pdb %s/%s: %v", pdb.Namespace, pdb.Name, err)
return dc.failSafe(pdb)
return dc.failSafe(pdb, err)
}
return nil
@@ -774,9 +777,21 @@ func (dc *DisruptionController) buildDisruptedPodMap(pods []*v1.Pod, pdb *policy
// implement the "fail open" part of the design since if we manage to update
// this field correctly, we will prevent the /evict handler from approving an
// eviction when it may be unsafe to do so.
func (dc *DisruptionController) failSafe(pdb *policy.PodDisruptionBudget) error {
func (dc *DisruptionController) failSafe(pdb *policy.PodDisruptionBudget, err error) error {
newPdb := pdb.DeepCopy()
newPdb.Status.DisruptionsAllowed = 0
if newPdb.Status.Conditions == nil {
newPdb.Status.Conditions = make([]metav1.Condition, 0)
}
apimeta.SetStatusCondition(&newPdb.Status.Conditions, metav1.Condition{
Type: policy.DisruptionAllowedCondition,
Status: metav1.ConditionFalse,
Reason: policy.SyncFailedReason,
Message: err.Error(),
ObservedGeneration: newPdb.Status.ObservedGeneration,
})
return dc.getUpdater()(newPdb)
}
@@ -797,7 +812,8 @@ func (dc *DisruptionController) updatePdbStatus(pdb *policy.PodDisruptionBudget,
pdb.Status.ExpectedPods == expectedCount &&
pdb.Status.DisruptionsAllowed == disruptionsAllowed &&
apiequality.Semantic.DeepEqual(pdb.Status.DisruptedPods, disruptedPods) &&
pdb.Status.ObservedGeneration == pdb.Generation {
pdb.Status.ObservedGeneration == pdb.Generation &&
pdbhelper.ConditionsAreUpToDate(pdb) {
return nil
}
@@ -811,6 +827,8 @@ func (dc *DisruptionController) updatePdbStatus(pdb *policy.PodDisruptionBudget,
ObservedGeneration: pdb.Generation,
}
pdbhelper.UpdateDisruptionAllowedCondition(newPdb)
return dc.getUpdater()(newPdb)
}

View File

@@ -32,6 +32,7 @@ import (
policy "k8s.io/api/policy/v1beta1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors"
apimeta "k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
@@ -73,6 +74,8 @@ func (ps *pdbStates) Get(key string) policy.PodDisruptionBudget {
func (ps *pdbStates) VerifyPdbStatus(t *testing.T, key string, disruptionsAllowed, currentHealthy, desiredHealthy, expectedPods int32,
disruptedPodMap map[string]metav1.Time) {
actualPDB := ps.Get(key)
actualConditions := actualPDB.Status.Conditions
actualPDB.Status.Conditions = nil
expectedStatus := policy.PodDisruptionBudgetStatus{
DisruptionsAllowed: disruptionsAllowed,
CurrentHealthy: currentHealthy,
@@ -86,6 +89,22 @@ func (ps *pdbStates) VerifyPdbStatus(t *testing.T, key string, disruptionsAllowe
debug.PrintStack()
t.Fatalf("PDB %q status mismatch. Expected %+v but got %+v.", key, expectedStatus, actualStatus)
}
cond := apimeta.FindStatusCondition(actualConditions, policy.DisruptionAllowedCondition)
if cond == nil {
t.Fatalf("Expected condition %q, but didn't find it", policy.DisruptionAllowedCondition)
}
if disruptionsAllowed > 0 {
if cond.Status != metav1.ConditionTrue {
t.Fatalf("Expected condition %q to have status %q, but was %q",
policy.DisruptionAllowedCondition, metav1.ConditionTrue, cond.Status)
}
} else {
if cond.Status != metav1.ConditionFalse {
t.Fatalf("Expected condition %q to have status %q, but was %q",
policy.DisruptionAllowedCondition, metav1.ConditionFalse, cond.Status)
}
}
}
func (ps *pdbStates) VerifyDisruptionAllowed(t *testing.T, key string, disruptionsAllowed int32) {