Skip to content

Commit 0488bc5

Browse files
committed
add support to filter out certain pods during node draining process
**What this PR does / why we need it**: The PR adds support to filter out certain pods during node draining process **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes #11024 <!-- Please label this pull request according to what area(s) you are addressing. For reference on PR/issue labels, see: https://github.com/kubernetes-sigs/cluster-api/labels?q=area+ Area example: /area runtime-sdk -->
1 parent 0440940 commit 0488bc5

10 files changed

+225
-3
lines changed

api/v1beta1/machine_types.go

+4
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ type MachineSpec struct {
132132
// Defaults to 10 seconds.
133133
// +optional
134134
NodeDeletionTimeout *metav1.Duration `json:"nodeDeletionTimeout,omitempty"`
135+
136+
// NodeDrainPodFilters allows to specify filters for pods to be excluded during node drain
137+
// +optional
138+
NodeDrainPodFilters *metav1.LabelSelector `json:"nodeDrainPodFilters,omitempty"`
135139
}
136140

137141
// ANCHOR_END: MachineSpec

api/v1beta1/zz_generated.deepcopy.go

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/v1beta1/zz_generated.openapi.go

+7-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/cluster.x-k8s.io_machinedeployments.yaml

+47
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/cluster.x-k8s.io_machinepools.yaml

+47
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/cluster.x-k8s.io_machines.yaml

+47
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/cluster.x-k8s.io_machinesets.yaml

+47
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/apis/core/v1alpha3/zz_generated.conversion.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/apis/core/v1alpha4/zz_generated.conversion.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/controllers/machine/machine_controller.go

+19-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
apierrors "k8s.io/apimachinery/pkg/api/errors"
2727
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2828
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
29+
"k8s.io/apimachinery/pkg/labels"
2930
"k8s.io/apimachinery/pkg/types"
3031
kerrors "k8s.io/apimachinery/pkg/util/errors"
3132
"k8s.io/apimachinery/pkg/util/wait"
@@ -386,7 +387,7 @@ func (r *Reconciler) reconcileDelete(ctx context.Context, cluster *clusterv1.Clu
386387
return ctrl.Result{}, errors.Wrap(err, "failed to patch Machine")
387388
}
388389

389-
if result, err := r.drainNode(ctx, cluster, m.Status.NodeRef.Name); !result.IsZero() || err != nil {
390+
if result, err := r.drainNode(ctx, cluster, m); !result.IsZero() || err != nil {
390391
if err != nil {
391392
conditions.MarkFalse(m, clusterv1.DrainingSucceededCondition, clusterv1.DrainingFailedReason, clusterv1.ConditionSeverityWarning, err.Error())
392393
r.recorder.Eventf(m, corev1.EventTypeWarning, "FailedDrainNode", "error draining Machine's node %q: %v", m.Status.NodeRef.Name, err)
@@ -615,7 +616,8 @@ func (r *Reconciler) isDeleteNodeAllowed(ctx context.Context, cluster *clusterv1
615616
return nil
616617
}
617618

618-
func (r *Reconciler) drainNode(ctx context.Context, cluster *clusterv1.Cluster, nodeName string) (ctrl.Result, error) {
619+
func (r *Reconciler) drainNode(ctx context.Context, cluster *clusterv1.Cluster, m *clusterv1.Machine) (ctrl.Result, error) {
620+
nodeName := m.Status.NodeRef.Name
619621
log := ctrl.LoggerFrom(ctx, "Node", klog.KRef("", nodeName))
620622

621623
restConfig, err := r.Tracker.GetRESTConfig(ctx, util.ObjectKey(cluster))
@@ -667,6 +669,9 @@ func (r *Reconciler) drainNode(ctx context.Context, cluster *clusterv1.Cluster,
667669
ErrOut: writer{func(msg string, keysAndValues ...interface{}) {
668670
log.Error(nil, msg, keysAndValues...)
669671
}},
672+
AdditionalFilters: []kubedrain.PodFilter{
673+
SkipFuncGenerator(m.Spec.NodeDrainPodFilters),
674+
},
670675
}
671676

672677
if noderefutil.IsNodeUnreachable(node) {
@@ -700,6 +705,18 @@ func (r *Reconciler) drainNode(ctx context.Context, cluster *clusterv1.Cluster,
700705
return ctrl.Result{}, nil
701706
}
702707

708+
func SkipFuncGenerator(labelSelector *metav1.LabelSelector) func(pod corev1.Pod) kubedrain.PodDeleteStatus {
709+
return func(pod corev1.Pod) kubedrain.PodDeleteStatus {
710+
if pod.Labels == nil {
711+
return kubedrain.MakePodDeleteStatusOkay()
712+
}
713+
if labels.Equals(labelSelector.MatchLabels, pod.ObjectMeta.Labels) {
714+
return kubedrain.MakePodDeleteStatusSkip()
715+
}
716+
return kubedrain.MakePodDeleteStatusOkay()
717+
}
718+
}
719+
703720
// shouldWaitForNodeVolumes returns true if node status still have volumes attached and the node is reachable
704721
// pod deletion and volume detach happen asynchronously, so pod could be deleted before volume detached from the node
705722
// this could cause issue for some storage provisioner, for example, vsphere-volume this is problematic

0 commit comments

Comments
 (0)