Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Make KCP pre-terminate hook more robust #11161

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion controlplane/kubeadm/internal/controllers/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ func (r *KubeadmControlPlaneReconciler) reconcileDelete(ctx context.Context, con
}

// Delete control plane machines in parallel
machinesToDelete := controlPlane.Machines.Filter(collections.Not(collections.HasDeletionTimestamp))
machinesToDelete := controlPlane.Machines
var errs []error
for _, machineToDelete := range machinesToDelete {
log := log.WithValues("Machine", klog.KObj(machineToDelete))
Expand All @@ -584,6 +584,11 @@ func (r *KubeadmControlPlaneReconciler) reconcileDelete(ctx context.Context, con
continue
}

if !machineToDelete.DeletionTimestamp.IsZero() {
// Nothing to do, Machine already has deletionTimestamp set.
continue
}

log.Info("Deleting control plane Machine")
if err := r.Client.Delete(ctx, machineToDelete); err != nil && !apierrors.IsNotFound(err) {
errs = append(errs, errors.Wrapf(err, "failed to delete control plane Machine %s", klog.KObj(machineToDelete)))
Expand All @@ -595,11 +600,19 @@ func (r *KubeadmControlPlaneReconciler) reconcileDelete(ctx context.Context, con
"Failed to delete control plane Machines for cluster %s control plane: %v", klog.KObj(controlPlane.Cluster), err)
return ctrl.Result{}, err
}

log.Info("Waiting for control plane Machines to not exist anymore")

conditions.MarkFalse(controlPlane.KCP, controlplanev1.ResizedCondition, clusterv1.DeletingReason, clusterv1.ConditionSeverityInfo, "")
return ctrl.Result{RequeueAfter: deleteRequeueAfter}, nil
}

func (r *KubeadmControlPlaneReconciler) removePreTerminateHookAnnotationFromMachine(ctx context.Context, machine *clusterv1.Machine) error {
if _, exists := machine.Annotations[controlplanev1.PreTerminateHookCleanupAnnotation]; !exists {
// Nothing to do, the annotation is not set (anymore) on the Machine
return nil
}

log := ctrl.LoggerFrom(ctx)
log.Info("Removing pre-terminate hook from control plane Machine")

Expand Down
2 changes: 2 additions & 0 deletions controlplane/kubeadm/internal/controllers/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2478,6 +2478,8 @@ func TestKubeadmControlPlaneReconciler_reconcileDelete(t *testing.T) {
initObjs = append(initObjs, m)
machines.Insert(m)
}
// One Machine was already deleted before KCP, validate the pre-terminate hook is still removed.
machines.UnsortedList()[2].DeletionTimestamp = &metav1.Time{Time: time.Now()}

fakeClient := newFakeClient(initObjs...)

Expand Down
15 changes: 15 additions & 0 deletions internal/controllers/machine/machine_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package machine
import (
"context"
"fmt"
"strings"
"time"

"github.com/pkg/errors"
Expand Down Expand Up @@ -366,6 +367,13 @@ func (r *Reconciler) reconcileDelete(ctx context.Context, cluster *clusterv1.Clu
// pre-drain.delete lifecycle hook
// Return early without error, will requeue if/when the hook owner removes the annotation.
if annotations.HasWithPrefix(clusterv1.PreDrainDeleteHookAnnotationPrefix, m.ObjectMeta.Annotations) {
var hooks []string
for key := range m.ObjectMeta.Annotations {
if strings.HasPrefix(key, clusterv1.PreDrainDeleteHookAnnotationPrefix) {
hooks = append(hooks, key)
}
}
log.Info("Waiting for pre-drain hooks to succeed", "hooks", strings.Join(hooks, ","))
conditions.MarkFalse(m, clusterv1.PreDrainDeleteHookSucceededCondition, clusterv1.WaitingExternalHookReason, clusterv1.ConditionSeverityInfo, "")
return ctrl.Result{}, nil
}
Expand Down Expand Up @@ -430,6 +438,13 @@ func (r *Reconciler) reconcileDelete(ctx context.Context, cluster *clusterv1.Clu
// pre-term.delete lifecycle hook
// Return early without error, will requeue if/when the hook owner removes the annotation.
if annotations.HasWithPrefix(clusterv1.PreTerminateDeleteHookAnnotationPrefix, m.ObjectMeta.Annotations) {
var hooks []string
for key := range m.ObjectMeta.Annotations {
if strings.HasPrefix(key, clusterv1.PreTerminateDeleteHookAnnotationPrefix) {
hooks = append(hooks, key)
}
}
log.Info("Waiting for pre-terminate hooks to succeed", "hooks", strings.Join(hooks, ","))
conditions.MarkFalse(m, clusterv1.PreTerminateDeleteHookSucceededCondition, clusterv1.WaitingExternalHookReason, clusterv1.ConditionSeverityInfo, "")
return ctrl.Result{}, nil
}
Expand Down
Loading