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

K8s-9372: Add modification for custom policy #57

Merged
merged 8 commits into from
Mar 28, 2024
17 changes: 11 additions & 6 deletions pkg/apis/cluster/v1alpha1/machineset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ type MachineSetSpec struct {
MinReadySeconds int32 `json:"minReadySeconds,omitempty"`

// DeletePolicy defines the policy used to identify nodes to delete when downscaling.
// Defaults to "Random". Valid values are "Random, "Newest", "Oldest"
// +kubebuilder:validation:Enum=Random,Newest,Oldest
// Defaults to "Default". Valid values are "Default", "Random, "Newest", "Oldest"
// +kubebuilder:validation:Enum=Default,Random,Newest,Oldest
DeletePolicy string `json:"deletePolicy,omitempty"`

// Selector is a label query over machines that should match the replica count.
Expand All @@ -78,7 +78,7 @@ type MachineSetSpec struct {
}

// MachineSetDeletePolicy defines how priority is assigned to nodes to delete when
// downscaling a MachineSet. Defaults to "Random".
// downscaling a MachineSet. Defaults to "Default".
type MachineSetDeletePolicy string

const (
Expand All @@ -99,6 +99,11 @@ const (
// (Status.ErrorReason or Status.ErrorMessage are set to a non-empty value).
// It then prioritizes the oldest Machines for deletion based on the Machine's CreationTimestamp.
OldestMachineSetDeletePolicy MachineSetDeletePolicy = "Oldest"

// DefaultDeletePolicy prioritizes deletion of newer machines or the ones
// referenced to a K8s node (relation between machine (OpenStack) - node (Kubernetes)).
// If then prioritizes the deletion of machines that have errors or deletion annotations added.
DefaultDeletePolicy MachineSetDeletePolicy = "Default"
)

/// [MachineSetSpec] // doxygen marker
Expand Down Expand Up @@ -203,9 +208,9 @@ func (m *MachineSet) Default() {
}

if m.Spec.DeletePolicy == "" {
randomPolicy := string(RandomMachineSetDeletePolicy)
log.Printf("Defaulting to %s\n", randomPolicy)
m.Spec.DeletePolicy = randomPolicy
defaultPolicy := string(DefaultDeletePolicy)
log.Printf("Defaulting to %s\n", defaultPolicy)
m.Spec.DeletePolicy = defaultPolicy
}
}

Expand Down
41 changes: 36 additions & 5 deletions pkg/controller/machineset/delete_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,22 @@ const (

// maps the creation timestamp onto the 0-100 priority range.
func oldestDeletePriority(machine *v1alpha1.Machine) deletePriority {
// DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This
// field is set by the server when a graceful deletion is requested by the user, and is not
// directly settable by a client.
// If machine deletion was already set, machine OK to delete
if machine.DeletionTimestamp != nil && !machine.DeletionTimestamp.IsZero() {
return mustDelete
}
// If machine annotations is not empty and DeleteNodeAnnotation is set, machine OK to delete
if machine.ObjectMeta.Annotations != nil && machine.ObjectMeta.Annotations[DeleteNodeAnnotation] != "" {
return mustDelete
}
// If there are machine errors, delete the machine
if machine.Status.ErrorReason != nil || machine.Status.ErrorMessage != nil {
return mustDelete
}
// If machine is new, don't delete it "CreationTimestamp is a timestamp representing the server time when this object was created"
if machine.ObjectMeta.CreationTimestamp.Time.IsZero() {
return mustNotDelete
}
Expand All @@ -67,11 +74,32 @@ func oldestDeletePriority(machine *v1alpha1.Machine) deletePriority {
return deletePriority(float64(mustDelete) * (1.0 - math.Exp(-d.Seconds()/secondsPerTenDays)))
}

// Default policies try to delete the machines that has no reference to a K8s node.
// If a reference exists, then continue with same conditions from "Newest" in different order.
func defaultDeletePolicy(machine *v1alpha1.Machine) deletePriority {
if !machine.DeletionTimestamp.IsZero() {
return mustDelete
}

if machine.Status.NodeRef == nil {
return mustDelete
}

if v, ok := machine.ObjectMeta.Annotations[DeleteNodeAnnotation]; ok && v != "" {
return mustDelete
}
if machine.Status.ErrorReason != nil || machine.Status.ErrorMessage != nil {
return mustDelete
}
// If not condition is matched from above, retrieve points from Newer to Older machines.
return mustDelete - oldestDeletePriority(machine)
}

func newestDeletePriority(machine *v1alpha1.Machine) deletePriority {
if machine.DeletionTimestamp != nil && !machine.DeletionTimestamp.IsZero() {
if !machine.DeletionTimestamp.IsZero() {
return mustDelete
}
if machine.ObjectMeta.Annotations != nil && machine.ObjectMeta.Annotations[DeleteNodeAnnotation] != "" {
if v, ok := machine.ObjectMeta.Annotations[DeleteNodeAnnotation]; ok && v != "" {
return mustDelete
}
if machine.Status.ErrorReason != nil || machine.Status.ErrorMessage != nil {
Expand All @@ -81,10 +109,10 @@ func newestDeletePriority(machine *v1alpha1.Machine) deletePriority {
}

func randomDeletePolicy(machine *v1alpha1.Machine) deletePriority {
if machine.DeletionTimestamp != nil && !machine.DeletionTimestamp.IsZero() {
if !machine.DeletionTimestamp.IsZero() {
return mustDelete
}
if machine.ObjectMeta.Annotations != nil && machine.ObjectMeta.Annotations[DeleteNodeAnnotation] != "" {
if v, ok := machine.ObjectMeta.Annotations[DeleteNodeAnnotation]; ok && v != "" {
return betterDelete
}
if machine.Status.ErrorReason != nil || machine.Status.ErrorMessage != nil {
Expand Down Expand Up @@ -124,15 +152,18 @@ func getMachinesToDeletePrioritized(filteredMachines []*v1alpha1.Machine, diff i

func getDeletePriorityFunc(ms *v1alpha1.MachineSet) (deletePriorityFunc, error) {
// Map the Spec.DeletePolicy value to the appropriate delete priority function
// Defaults to defaultDeletePolicy if not specified
switch msdp := v1alpha1.MachineSetDeletePolicy(ms.Spec.DeletePolicy); msdp {
case v1alpha1.RandomMachineSetDeletePolicy:
return randomDeletePolicy, nil
case v1alpha1.NewestMachineSetDeletePolicy:
return newestDeletePriority, nil
case v1alpha1.OldestMachineSetDeletePolicy:
return oldestDeletePriority, nil
case v1alpha1.DefaultDeletePolicy:
return defaultDeletePolicy, nil
case "":
return randomDeletePolicy, nil
return defaultDeletePolicy, nil
default:
return nil, errors.Errorf("Unsupported delete policy %q. Must be one of 'Random', 'Newest', or 'Oldest'", msdp)
}
Expand Down
Loading