controller sets observedGeneration on pod conditions

This commit is contained in:
Natasha Sarkar 2025-03-07 17:04:22 +00:00
parent b82260f003
commit af9ac325b1
4 changed files with 31 additions and 10 deletions

View File

@ -428,3 +428,21 @@ func GetPodObservedGenerationIfEnabled(pod *v1.Pod) int64 {
}
return 0
}
// We will emit condition.observedGeneration if the feature is enabled OR if condition.observedGeneration is already set.
// This protects against an infinite loop of kubelet trying to clear the value after the FG is turned off, and
// the API server preserving existing values when an incoming update tries to clear it.
func GetPodObservedGenerationIfEnabledOnCondition(pod *v1.Pod, conditionType v1.PodConditionType) int64 {
if pod == nil {
return 0
}
if utilfeature.DefaultFeatureGate.Enabled(features.PodObservedGenerationTracking) {
return pod.Generation
}
for _, condition := range pod.Status.Conditions {
if condition.Type == conditionType && condition.ObservedGeneration != 0 {
return pod.Generation
}
}
return 0
}

View File

@ -787,8 +787,9 @@ func (dc *DisruptionController) syncStalePodDisruption(ctx context.Context, key
newPod := pod.DeepCopy()
updated := apipod.UpdatePodCondition(&newPod.Status, &v1.PodCondition{
Type: v1.DisruptionTarget,
Status: v1.ConditionFalse,
Type: v1.DisruptionTarget,
ObservedGeneration: apipod.GetPodObservedGenerationIfEnabledOnCondition(newPod, v1.DisruptionTarget),
Status: v1.ConditionFalse,
})
if !updated {
return nil

View File

@ -246,10 +246,11 @@ func (gcc *PodGCController) gcOrphaned(ctx context.Context, pods []*v1.Pod, node
}
logger.V(2).Info("Found orphaned Pod assigned to the Node, deleting", "pod", klog.KObj(pod), "node", klog.KRef("", pod.Spec.NodeName))
condition := &v1.PodCondition{
Type: v1.DisruptionTarget,
Status: v1.ConditionTrue,
Reason: "DeletionByPodGC",
Message: "PodGC: node no longer exists",
Type: v1.DisruptionTarget,
ObservedGeneration: apipod.GetPodObservedGenerationIfEnabledOnCondition(pod, v1.DisruptionTarget),
Status: v1.ConditionTrue,
Reason: "DeletionByPodGC",
Message: "PodGC: node no longer exists",
}
if err := gcc.markFailedAndDeletePodWithCondition(ctx, pod, condition); err != nil {
utilruntime.HandleError(err)

View File

@ -133,10 +133,11 @@ func addConditionAndDeletePod(ctx context.Context, c clientset.Interface, name,
}
newStatus := pod.Status.DeepCopy()
updated := apipod.UpdatePodCondition(newStatus, &v1.PodCondition{
Type: v1.DisruptionTarget,
Status: v1.ConditionTrue,
Reason: "DeletionByTaintManager",
Message: "Taint manager: deleting due to NoExecute taint",
Type: v1.DisruptionTarget,
ObservedGeneration: apipod.GetPodObservedGenerationIfEnabledOnCondition(pod, v1.DisruptionTarget),
Status: v1.ConditionTrue,
Reason: "DeletionByTaintManager",
Message: "Taint manager: deleting due to NoExecute taint",
})
if updated {
if _, _, _, err := utilpod.PatchPodStatus(ctx, c, pod.Namespace, pod.Name, pod.UID, pod.Status, *newStatus); err != nil {