Make ScaleDownNonEmptyCandidatesCount a flag.
This commit is contained in:
parent
4560cc0a85
commit
576e4105db
|
|
@ -96,6 +96,9 @@ type AutoscalingOptions struct {
|
|||
ScaleDownDelay time.Duration
|
||||
// ScaleDownTrialInterval sets how often scale down possibility is check
|
||||
ScaleDownTrialInterval time.Duration
|
||||
// ScaleDownNonEmptyCandidatesCount is the maximum number of non empty nodes
|
||||
// considered at once as candidates for scale down.
|
||||
ScaleDownNonEmptyCandidatesCount int
|
||||
// WriteStatusConfigMap tells if the status information should be written to a ConfigMap
|
||||
WriteStatusConfigMap bool
|
||||
// BalanceSimilarNodeGroups enables logic that identifies node groups with similar machines and tries to balance node count between them.
|
||||
|
|
|
|||
|
|
@ -58,9 +58,6 @@ const (
|
|||
ScaleDownNodeDeleteStarted ScaleDownResult = iota
|
||||
// ScaleDownDisabledKey is the name of annotation marking node as not eligible for scale down.
|
||||
ScaleDownDisabledKey = "cluster-autoscaler.kubernetes.io/scale-down-disabled"
|
||||
// ScaleDownNonEmptyCandidatesCount is the maximum number of non empty nodes
|
||||
// considered at once as candidates for scale down.
|
||||
ScaleDownNonEmptyCandidatesCount = 30
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -222,8 +219,7 @@ func (sd *ScaleDown) UpdateUnneededNodes(
|
|||
return sd.markSimulationError(simulatorErr, timestamp)
|
||||
}
|
||||
|
||||
// Check how many candidates we are still missing
|
||||
additionalCandidatesCount := ScaleDownNonEmptyCandidatesCount - len(nodesToRemove)
|
||||
additionalCandidatesCount := sd.context.AutoscalingOptions.ScaleDownNonEmptyCandidatesCount - len(nodesToRemove)
|
||||
if additionalCandidatesCount > len(currentNonCandidates) {
|
||||
additionalCandidatesCount = len(currentNonCandidates)
|
||||
}
|
||||
|
|
@ -292,6 +288,11 @@ func (sd *ScaleDown) markSimulationError(simulatorErr errors.AutoscalerError,
|
|||
// rest. Current candidates are unneeded nodes from the previous run that are
|
||||
// still in the nodes list.
|
||||
func (sd *ScaleDown) chooseCandidates(nodes []*apiv1.Node) ([]*apiv1.Node, []*apiv1.Node) {
|
||||
// Number of candidates should not be capped. We will look for nodes to remove
|
||||
// from the whole set of nodes.
|
||||
if sd.context.AutoscalingOptions.ScaleDownNonEmptyCandidatesCount <= 0 {
|
||||
return nodes, []*apiv1.Node{}
|
||||
}
|
||||
currentCandidates := make([]*apiv1.Node, 0, len(sd.unneededNodesList))
|
||||
currentNonCandidates := make([]*apiv1.Node, 0, len(nodes))
|
||||
for _, node := range nodes {
|
||||
|
|
|
|||
|
|
@ -144,11 +144,14 @@ func TestFindUnneededMaxCandidates(t *testing.T) {
|
|||
nodes = append(nodes, n)
|
||||
}
|
||||
|
||||
// shared owner reference
|
||||
ownerRef := GenerateOwnerReferences("rs", "ReplicaSet", "extensions/v1beta1", "")
|
||||
|
||||
pods := make([]*apiv1.Pod, 0, numNodes)
|
||||
for i := 0; i < numNodes; i++ {
|
||||
p := BuildTestPod(fmt.Sprintf("p%v", i), 100, 0)
|
||||
p.Annotations = GetReplicaSetAnnotation()
|
||||
p.Spec.NodeName = fmt.Sprintf("n%v", i)
|
||||
p.OwnerReferences = ownerRef
|
||||
pods = append(pods, p)
|
||||
}
|
||||
|
||||
|
|
@ -156,9 +159,12 @@ func TestFindUnneededMaxCandidates(t *testing.T) {
|
|||
fakeRecorder := kube_util.CreateEventRecorder(fakeClient)
|
||||
fakeLogRecorder, _ := utils.NewStatusMapRecorder(fakeClient, "kube-system", fakeRecorder, false)
|
||||
|
||||
numCandidates := 30
|
||||
|
||||
context := AutoscalingContext{
|
||||
AutoscalingOptions: AutoscalingOptions{
|
||||
ScaleDownUtilizationThreshold: 0.35,
|
||||
ScaleDownUtilizationThreshold: 0.35,
|
||||
ScaleDownNonEmptyCandidatesCount: numCandidates,
|
||||
},
|
||||
ClusterStateRegistry: clusterstate.NewClusterStateRegistry(provider, clusterstate.ClusterStateRegistryConfig{}),
|
||||
PredicateChecker: simulator.NewTestPredicateChecker(),
|
||||
|
|
@ -167,7 +173,7 @@ func TestFindUnneededMaxCandidates(t *testing.T) {
|
|||
sd := NewScaleDown(&context)
|
||||
|
||||
sd.UpdateUnneededNodes(nodes, nodes, pods, time.Now(), nil)
|
||||
assert.Equal(t, ScaleDownNonEmptyCandidatesCount, len(sd.unneededNodes))
|
||||
assert.Equal(t, numCandidates, len(sd.unneededNodes))
|
||||
// Simulate one of the unneeded nodes got deleted
|
||||
deleted := sd.unneededNodesList[len(sd.unneededNodesList)-1]
|
||||
for i, node := range nodes {
|
||||
|
|
@ -189,7 +195,7 @@ func TestFindUnneededMaxCandidates(t *testing.T) {
|
|||
|
||||
sd.UpdateUnneededNodes(nodes, nodes, pods, time.Now(), nil)
|
||||
// Check that the deleted node was replaced
|
||||
assert.Equal(t, ScaleDownNonEmptyCandidatesCount, len(sd.unneededNodes))
|
||||
assert.Equal(t, numCandidates, len(sd.unneededNodes))
|
||||
assert.NotContains(t, sd.unneededNodes, deleted)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,6 +83,11 @@ var (
|
|||
"Node utilization level, defined as sum of requested resources divided by capacity, below which a node can be considered for scale down")
|
||||
scaleDownTrialInterval = flag.Duration("scale-down-trial-interval", 1*time.Minute,
|
||||
"How often scale down possiblity is check")
|
||||
scaleDownNonEmptyCandidatesCount = flag.Int("scale-down-non-empty-candidates-count", 30,
|
||||
"Maximum number of non empty nodes considered in one iteration as candidates for scale down with drain."+
|
||||
"Lower value means better CA responsiveness but possible slower scale down latency."+
|
||||
"Higher value can affect CA performance with big clusters (hundreds of nodes)."+
|
||||
"Set to non posistive value to turn this heuristic off - CA will not limit the number of nodes it considers.")
|
||||
scanInterval = flag.Duration("scan-interval", 10*time.Second, "How often cluster is reevaluated for scale up or down")
|
||||
maxNodesTotal = flag.Int("max-nodes-total", 0, "Maximum number of nodes in all node groups. Cluster autoscaler will not grow the cluster beyond this number.")
|
||||
cloudProviderFlag = flag.String("cloud-provider", "gce", "Cloud provider type. Allowed values: gce, aws, kubemark")
|
||||
|
|
@ -108,30 +113,31 @@ var (
|
|||
|
||||
func createAutoscalerOptions() core.AutoscalerOptions {
|
||||
autoscalingOpts := core.AutoscalingOptions{
|
||||
CloudConfig: *cloudConfig,
|
||||
CloudProviderName: *cloudProviderFlag,
|
||||
NodeGroupAutoDiscovery: *nodeGroupAutoDiscovery,
|
||||
MaxTotalUnreadyPercentage: *maxTotalUnreadyPercentage,
|
||||
OkTotalUnreadyCount: *okTotalUnreadyCount,
|
||||
EstimatorName: *estimatorFlag,
|
||||
ExpanderName: *expanderFlag,
|
||||
MaxEmptyBulkDelete: *maxEmptyBulkDeleteFlag,
|
||||
MaxGracefulTerminationSec: *maxGracefulTerminationFlag,
|
||||
MaxNodeProvisionTime: *maxNodeProvisionTime,
|
||||
MaxNodesTotal: *maxNodesTotal,
|
||||
NodeGroups: nodeGroupsFlag,
|
||||
UnregisteredNodeRemovalTime: *unregisteredNodeRemovalTime,
|
||||
ScaleDownDelay: *scaleDownDelay,
|
||||
ScaleDownEnabled: *scaleDownEnabled,
|
||||
ScaleDownTrialInterval: *scaleDownTrialInterval,
|
||||
ScaleDownUnneededTime: *scaleDownUnneededTime,
|
||||
ScaleDownUnreadyTime: *scaleDownUnreadyTime,
|
||||
ScaleDownUtilizationThreshold: *scaleDownUtilizationThreshold,
|
||||
WriteStatusConfigMap: *writeStatusConfigMapFlag,
|
||||
BalanceSimilarNodeGroups: *balanceSimilarNodeGroupsFlag,
|
||||
ConfigNamespace: *namespace,
|
||||
ClusterName: *clusterName,
|
||||
NodeAutoprovisioningEnabled: *nodeAutoprovisioningEnabled,
|
||||
CloudConfig: *cloudConfig,
|
||||
CloudProviderName: *cloudProviderFlag,
|
||||
NodeGroupAutoDiscovery: *nodeGroupAutoDiscovery,
|
||||
MaxTotalUnreadyPercentage: *maxTotalUnreadyPercentage,
|
||||
OkTotalUnreadyCount: *okTotalUnreadyCount,
|
||||
EstimatorName: *estimatorFlag,
|
||||
ExpanderName: *expanderFlag,
|
||||
MaxEmptyBulkDelete: *maxEmptyBulkDeleteFlag,
|
||||
MaxGracefulTerminationSec: *maxGracefulTerminationFlag,
|
||||
MaxNodeProvisionTime: *maxNodeProvisionTime,
|
||||
MaxNodesTotal: *maxNodesTotal,
|
||||
NodeGroups: nodeGroupsFlag,
|
||||
UnregisteredNodeRemovalTime: *unregisteredNodeRemovalTime,
|
||||
ScaleDownDelay: *scaleDownDelay,
|
||||
ScaleDownEnabled: *scaleDownEnabled,
|
||||
ScaleDownTrialInterval: *scaleDownTrialInterval,
|
||||
ScaleDownUnneededTime: *scaleDownUnneededTime,
|
||||
ScaleDownUnreadyTime: *scaleDownUnreadyTime,
|
||||
ScaleDownUtilizationThreshold: *scaleDownUtilizationThreshold,
|
||||
ScaleDownNonEmptyCandidatesCount: *scaleDownNonEmptyCandidatesCount,
|
||||
WriteStatusConfigMap: *writeStatusConfigMapFlag,
|
||||
BalanceSimilarNodeGroups: *balanceSimilarNodeGroupsFlag,
|
||||
ConfigNamespace: *namespace,
|
||||
ClusterName: *clusterName,
|
||||
NodeAutoprovisioningEnabled: *nodeAutoprovisioningEnabled,
|
||||
}
|
||||
|
||||
configFetcherOpts := dynamic.ConfigFetcherOptions{
|
||||
|
|
|
|||
Loading…
Reference in New Issue