Skip to content
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
30 changes: 24 additions & 6 deletions cluster-autoscaler/config/autoscaling_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ type AutoscalingOptions struct {
// NodeGroupDefaults are default values for per NodeGroup options.
// They will be used any time a specific value is not provided for a given NodeGroup.
NodeGroupDefaults NodeGroupAutoscalingOptions
// MaxEmptyBulkDelete is a number of empty nodes that can be removed at the same time.
MaxEmptyBulkDelete int
// MaxNodesTotal sets the maximum number of nodes in the whole cluster
MaxNodesTotal int
// MaxCoresTotal sets the maximum number of cores in the whole cluster
Expand Down Expand Up @@ -198,10 +196,6 @@ type AutoscalingOptions struct {
ConfigNamespace string
// ClusterName if available
ClusterName string
// NodeAutoprovisioningEnabled tells whether the node auto-provisioning is enabled for this cluster.
NodeAutoprovisioningEnabled bool
// MaxAutoprovisionedNodeGroupCount is the maximum number of autoprovisioned groups in the cluster.
MaxAutoprovisionedNodeGroupCount int
// UnremovableNodeRecheckTimeout is the timeout before we check again a node that couldn't be removed before
UnremovableNodeRecheckTimeout time.Duration
// Pods with priority below cutoff are expendable. They can be killed without any consideration during scale down and they don't cause scale-up.
Expand Down Expand Up @@ -318,6 +312,30 @@ type AutoscalingOptions struct {
// It only refers to check capacity ProvisioningRequests, but if not empty, best-effort atomic ProvisioningRequests processing is disabled in this instance.
// Not recommended: Until CA 1.35, ProvisioningRequests with this name as prefix in their class will be also processed.
CheckCapacityProcessorInstance string
// MaxInactivityTime is the maximum duration without recorded autoscaler activity before it is considered unhealthy.
MaxInactivityTime time.Duration
// MaxFailingTime is the maximum duration without a successful autoscaler run before it is considered unhealthy.
MaxFailingTime time.Duration
// DebuggingSnapshotEnabled is used to enable/disable debugging snapshot creation.
DebuggingSnapshotEnabled bool
// EnableProfiling is debug/pprof endpoint enabled.
EnableProfiling bool
// Address is the address of an auxiliary endpoint exposing process information like metrics, health checks and profiling data.
Address string
// EmitPerNodeGroupMetrics is used to enable/disable emitting per node group metrics.
EmitPerNodeGroupMetrics bool
// FrequentLoopsEnabled is used to enable/disable frequent loops.
FrequentLoopsEnabled bool
// ScanInterval is how often cluster is reevaluated for scale up or down
ScanInterval time.Duration
// ForceDaemonSets is used to block scale-up of node groups too small for all suitable Daemon Sets pods.
ForceDaemonSets bool
// NodeInfoCacheExpireTime is the time after which the node info cache expires for each item, Default value is 10 years.
NodeInfoCacheExpireTime time.Duration
// ProactiveScaleupEnabled is used to enable/disable proactive scale up.
ProactiveScaleupEnabled bool
// PodInjectionLimit limits total number of pods while injecting fake pods.
PodInjectionLimit int
}

// KubeClientOptions specify options for kube client
Expand Down
532 changes: 532 additions & 0 deletions cluster-autoscaler/config/flags/flags.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package main
package flags

import (
"testing"

"k8s.io/autoscaler/cluster-autoscaler/config"
kubelet_config "k8s.io/kubernetes/pkg/kubelet/apis/config"

"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -91,3 +92,57 @@ func TestParseSingleGpuLimit(t *testing.T) {
}
}
}

func TestParseShutdownGracePeriodsAndPriorities(t *testing.T) {
testCases := []struct {
name string
input string
want []kubelet_config.ShutdownGracePeriodByPodPriority
}{
{
name: "empty input",
input: "",
want: nil,
},
{
name: "Incorrect string - incorrect priority grace period pairs",
input: "1:2,34",
want: nil,
},
{
name: "Incorrect string - trailing ,",
input: "1:2, 3:4,",
want: nil,
},
{
name: "Incorrect string - trailing space",
input: "1:2,3:4 ",
want: nil,
},
{
name: "Non integers - 1",
input: "1:2,3:a",
want: nil,
},
{
name: "Non integers - 2",
input: "1:2,3:23.2",
want: nil,
},
{
name: "parsable input",
input: "1:2,3:4",
want: []kubelet_config.ShutdownGracePeriodByPodPriority{
{1, 2},
{3, 4},
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
shutdownGracePeriodByPodPriority := parseShutdownGracePeriodsAndPriorities(tc.input)
assert.Equal(t, tc.want, shutdownGracePeriodByPodPriority)
})
}
}
36 changes: 0 additions & 36 deletions cluster-autoscaler/core/scaledown/actuation/priority.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,8 @@ package actuation
import (
"math"
"sort"
"strconv"
"strings"

apiv1 "k8s.io/api/core/v1"
"k8s.io/klog/v2"
kubelet_config "k8s.io/kubernetes/pkg/kubelet/apis/config"
)

Expand Down Expand Up @@ -73,39 +70,6 @@ func groupIndex(pod *apiv1.Pod, groups []podEvictionGroup) int {
return index
}

// ParseShutdownGracePeriodsAndPriorities parse priorityGracePeriodStr and returns an array of ShutdownGracePeriodByPodPriority if succeeded.
// Otherwise, returns an empty list
func ParseShutdownGracePeriodsAndPriorities(priorityGracePeriodStr string) []kubelet_config.ShutdownGracePeriodByPodPriority {
var priorityGracePeriodMap, emptyMap []kubelet_config.ShutdownGracePeriodByPodPriority

if priorityGracePeriodStr == "" {
return emptyMap
}
priorityGracePeriodStrArr := strings.Split(priorityGracePeriodStr, ",")
for _, item := range priorityGracePeriodStrArr {
priorityAndPeriod := strings.Split(item, ":")
if len(priorityAndPeriod) != 2 {
klog.Errorf("Parsing shutdown grace periods failed because '%s' is not a priority and grace period couple separated by ':'", item)
return emptyMap
}
priority, err := strconv.Atoi(priorityAndPeriod[0])
if err != nil {
klog.Errorf("Parsing shutdown grace periods and priorities failed: %v", err)
return emptyMap
}
shutDownGracePeriod, err := strconv.Atoi(priorityAndPeriod[1])
if err != nil {
klog.Errorf("Parsing shutdown grace periods and priorities failed: %v", err)
return emptyMap
}
priorityGracePeriodMap = append(priorityGracePeriodMap, kubelet_config.ShutdownGracePeriodByPodPriority{
Priority: int32(priority),
ShutdownGracePeriodSeconds: int64(shutDownGracePeriod),
})
}
return priorityGracePeriodMap
}

// SingleRuleDrainConfig returns an array of ShutdownGracePeriodByPodPriority with a single ShutdownGracePeriodByPodPriority
func SingleRuleDrainConfig(shutdownGracePeriodSeconds int) []kubelet_config.ShutdownGracePeriodByPodPriority {
return []kubelet_config.ShutdownGracePeriodByPodPriority{
Expand Down
54 changes: 0 additions & 54 deletions cluster-autoscaler/core/scaledown/actuation/priority_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,57 +183,3 @@ func TestGroupByPriority(t *testing.T) {
groups := groupByPriority(shutdownGracePeriodByPodPriority, []*apiv1.Pod{p1, p2, p3, p4, p5}, []*apiv1.Pod{p6, p7, p8, p9, p10})
assert.Equal(t, wantGroups, groups)
}

func TestParseShutdownGracePeriodsAndPriorities(t *testing.T) {
testCases := []struct {
name string
input string
want []kubelet_config.ShutdownGracePeriodByPodPriority
}{
{
name: "empty input",
input: "",
want: nil,
},
{
name: "Incorrect string - incorrect priority grace period pairs",
input: "1:2,34",
want: nil,
},
{
name: "Incorrect string - trailing ,",
input: "1:2, 3:4,",
want: nil,
},
{
name: "Incorrect string - trailing space",
input: "1:2,3:4 ",
want: nil,
},
{
name: "Non integers - 1",
input: "1:2,3:a",
want: nil,
},
{
name: "Non integers - 2",
input: "1:2,3:23.2",
want: nil,
},
{
name: "parsable input",
input: "1:2,3:4",
want: []kubelet_config.ShutdownGracePeriodByPodPriority{
{1, 2},
{3, 4},
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
shutdownGracePeriodByPodPriority := ParseShutdownGracePeriodsAndPriorities(tc.input)
assert.Equal(t, tc.want, shutdownGracePeriodByPodPriority)
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ func TestNodePoolAsyncInitialization(t *testing.T) {
return nil
}, nil)
options := config.AutoscalingOptions{
NodeAutoprovisioningEnabled: true,
AsyncNodeGroupsEnabled: true,
AsyncNodeGroupsEnabled: true,
}
listers := kube_util.NewListerRegistry(nil, nil, nil, nil, nil, nil, nil, nil, nil)
context, err := NewScaleTestAutoscalingContext(options, &fake.Clientset{}, listers, provider, nil, nil)
Expand Down
22 changes: 8 additions & 14 deletions cluster-autoscaler/core/scaleup/orchestrator/orchestrator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,6 @@ func TestNoCreateNodeGroupMaxCoresLimitHit(t *testing.T) {
options := defaultOptions
options.MaxCoresTotal = 7
options.MaxMemoryTotal = 100000
options.NodeAutoprovisioningEnabled = true

largeNode := BuildTestNode("n", 8000, 8000)
SetNodeReadyState(largeNode, true, time.Time{})
Expand Down Expand Up @@ -1555,11 +1554,9 @@ func TestScaleUpAutoprovisionedNodeGroup(t *testing.T) {
}, nil, []string{"T1"}, map[string]*framework.NodeInfo{"T1": ti1})

options := config.AutoscalingOptions{
EstimatorName: estimator.BinpackingEstimatorName,
MaxCoresTotal: 5000 * 64,
MaxMemoryTotal: 5000 * 64 * 20,
NodeAutoprovisioningEnabled: true,
MaxAutoprovisionedNodeGroupCount: 10,
EstimatorName: estimator.BinpackingEstimatorName,
MaxCoresTotal: 5000 * 64,
MaxMemoryTotal: 5000 * 64 * 20,
}
podLister := kube_util.NewTestPodLister([]*apiv1.Pod{})
listers := kube_util.NewListerRegistry(nil, nil, podLister, nil, nil, nil, nil, nil, nil)
Expand Down Expand Up @@ -1608,12 +1605,10 @@ func TestScaleUpBalanceAutoprovisionedNodeGroups(t *testing.T) {
}, nil, []string{"T1"}, map[string]*framework.NodeInfo{"T1": ti1})

options := config.AutoscalingOptions{
BalanceSimilarNodeGroups: true,
EstimatorName: estimator.BinpackingEstimatorName,
MaxCoresTotal: 5000 * 64,
MaxMemoryTotal: 5000 * 64 * 20,
NodeAutoprovisioningEnabled: true,
MaxAutoprovisionedNodeGroupCount: 10,
BalanceSimilarNodeGroups: true,
EstimatorName: estimator.BinpackingEstimatorName,
MaxCoresTotal: 5000 * 64,
MaxMemoryTotal: 5000 * 64 * 20,
}
podLister := kube_util.NewTestPodLister([]*apiv1.Pod{})
listers := kube_util.NewListerRegistry(nil, nil, podLister, nil, nil, nil, nil, nil, nil)
Expand Down Expand Up @@ -1762,8 +1757,7 @@ func TestScaleupAsyncNodeGroupsEnabled(t *testing.T) {
}

options := config.AutoscalingOptions{
NodeAutoprovisioningEnabled: true,
AsyncNodeGroupsEnabled: true,
AsyncNodeGroupsEnabled: true,
}
podLister := kube_util.NewTestPodLister([]*apiv1.Pod{})
listers := kube_util.NewListerRegistry(nil, nil, podLister, nil, nil, nil, nil, nil, nil)
Expand Down
12 changes: 5 additions & 7 deletions cluster-autoscaler/core/static_autoscaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -807,13 +807,11 @@ func TestStaticAutoscalerRunOnceWithAutoprovisionedEnabled(t *testing.T) {
ScaleDownUtilizationThreshold: 0.5,
MaxNodeProvisionTime: 10 * time.Second,
},
EstimatorName: estimator.BinpackingEstimatorName,
ScaleDownEnabled: true,
MaxNodesTotal: 100,
MaxCoresTotal: 100,
MaxMemoryTotal: 100000,
NodeAutoprovisioningEnabled: true,
MaxAutoprovisionedNodeGroupCount: 10,
EstimatorName: estimator.BinpackingEstimatorName,
ScaleDownEnabled: true,
MaxNodesTotal: 100,
MaxCoresTotal: 100,
MaxMemoryTotal: 100000,
}
processorCallbacks := newStaticAutoscalerProcessorCallbacks()

Expand Down
3 changes: 0 additions & 3 deletions cluster-autoscaler/core/test/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,9 +248,6 @@ func (p *MockAutoprovisioningNodeGroupManager) createNodeGroup(context *context.

// RemoveUnneededNodeGroups removes uneeded node groups
func (p *MockAutoprovisioningNodeGroupManager) RemoveUnneededNodeGroups(context *context.AutoscalingContext) (removedNodeGroups []cloudprovider.NodeGroup, err error) {
if !context.AutoscalingOptions.NodeAutoprovisioningEnabled {
return nil, nil
}
removedNodeGroups = make([]cloudprovider.NodeGroup, 0)
nodeGroups := context.CloudProvider.NodeGroups()
for _, nodeGroup := range nodeGroups {
Expand Down
Loading
Loading