@@ -39,6 +39,11 @@ import (
3939 "github.com/cloudpilot-ai/karpenter-provider-alibabacloud/pkg/providers/imagefamily"
4040)
4141
42+ const (
43+ MemoryAvailable = "memory.available"
44+ NodeFSAvailable = "nodefs.available"
45+ )
46+
4247var (
4348 instanceTypeScheme = regexp .MustCompile (`^ecs\.([a-z]+)(\-[0-9]+tb)?([0-9]+).*` )
4449)
@@ -59,55 +64,10 @@ type ZoneData struct {
5964 SpotAvailable bool
6065}
6166
62- func calculateResourceOverhead (pods , cpuM , memoryMi int64 ) corev1.ResourceList {
63- // referring to: https://help.aliyun.com/zh/ack/ack-managed-and-ack-dedicated/user-guide/resource-reservation-policy#0f5ffe176df7q
64- // CPU overhead calculation
65- cpuOverHead := calculateCPUOverhead (cpuM )
66-
67- // TODO: In a real environment, the formula does not produce accurate results,
68- // consistently yielding values that are 200MiB larger than expected.
69- // Memory overhead: min(11*pods + 255, memoryMi*0.25)
70- memoryOverHead := int64 (math .Min (float64 (11 * pods + 255 ), float64 (memoryMi )* 0.25 )) + 200
71-
72- return corev1.ResourceList {
73- corev1 .ResourceCPU : * resource .NewMilliQuantity (cpuOverHead , resource .DecimalSI ),
74- corev1 .ResourceMemory : * resources .Quantity (fmt .Sprintf ("%dMi" , memoryOverHead )),
75- }
76- }
77-
78- // thresholds defines CPU overhead thresholds and their corresponding percentages
79- var thresholds = [... ]struct {
80- cores int64
81- overhead float64
82- }{
83- {1000 , 0.06 },
84- {2000 , 0.01 },
85- {3000 , 0.005 },
86- {4000 , 0.005 },
87- }
88-
89- func calculateCPUOverhead (cpuM int64 ) int64 {
90- var cpuOverHead int64
91-
92- // Calculate overhead for each threshold
93- for _ , t := range thresholds {
94- if cpuM >= t .cores {
95- cpuOverHead += int64 (1000 * t .overhead )
96- }
97- }
98-
99- // Additional overhead for CPU > 4 cores (0.25%)
100- if cpuM > 4000 {
101- cpuOverHead += int64 (float64 (cpuM - 4000 ) * 0.0025 )
102- }
103-
104- return cpuOverHead
105- }
106-
10767func NewInstanceType (ctx context.Context ,
10868 info * ecsclient.DescribeInstanceTypesResponseBodyInstanceTypesInstanceType ,
10969 kc * v1alpha1.KubeletConfiguration , region string , systemDisk * v1alpha1.SystemDisk ,
110- offerings cloudprovider.Offerings , clusterCNI string ) * cloudprovider.InstanceType {
70+ offerings cloudprovider.Offerings , clusterCNI string , cluster cluster. Provider ) * cloudprovider.InstanceType {
11171 if offerings == nil {
11272 return nil
11373 }
@@ -117,16 +77,10 @@ func NewInstanceType(ctx context.Context,
11777 Requirements : computeRequirements (info , offerings , region ),
11878 Offerings : offerings ,
11979 Capacity : computeCapacity (ctx , info , kc .MaxPods , kc .PodsPerCore , systemDisk , clusterCNI ),
120- Overhead : & cloudprovider.InstanceTypeOverhead {
121- KubeReserved : corev1.ResourceList {},
122- SystemReserved : corev1.ResourceList {},
123- EvictionThreshold : corev1.ResourceList {},
124- },
12580 }
12681
12782 // Follow KubeReserved/SystemReserved/EvictionThreshold will be merged, so we can set only one overhead totally
128- it .Overhead .KubeReserved = calculateResourceOverhead (it .Capacity .Pods ().Value (),
129- it .Capacity .Cpu ().MilliValue (), extractMemory (info ).Value ()/ MiBByteRatio )
83+ it .Overhead = computeOverhead (cluster , it .Capacity , kc )
13084 if it .Requirements .Compatible (scheduling .NewRequirements (scheduling .NewRequirement (corev1 .LabelOSStable , corev1 .NodeSelectorOpIn , string (corev1 .Windows )))) == nil {
13185 it .Capacity [v1alpha1 .ResourcePrivateIPv4Address ] = * privateIPv4Address (info )
13286 }
@@ -353,3 +307,42 @@ func privateIPv4Address(info *ecsclient.DescribeInstanceTypesResponseBodyInstanc
353307func getInstanceBandwidth (info * ecsclient.DescribeInstanceTypesResponseBodyInstanceTypesInstanceType ) int32 {
354308 return max (lo .FromPtr (info .InstanceBandwidthRx ), lo .FromPtr (info .InstanceBandwidthTx ))
355309}
310+
311+ func computeOverhead (cluster cluster.Provider , capacity corev1.ResourceList , kubeletConfig * v1alpha1.KubeletConfiguration ) * cloudprovider.InstanceTypeOverhead {
312+ overhead := & cloudprovider.InstanceTypeOverhead {
313+ KubeReserved : corev1.ResourceList {},
314+ SystemReserved : corev1.ResourceList {},
315+ // ref: https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/eviction/defaults_linux.go
316+ EvictionThreshold : corev1.ResourceList {
317+ corev1 .ResourceMemory : resource .MustParse ("100Mi" ),
318+ corev1 .ResourceEphemeralStorage : computeEvictionSignal (* capacity .StorageEphemeral (), "10%" ),
319+ },
320+ }
321+
322+ defaultOverhead := cluster .DefaultOverhead (capacity )
323+ if defaultOverhead .KubeReserved != nil {
324+ overhead .KubeReserved = lo .Assign (overhead .KubeReserved , defaultOverhead .KubeReserved )
325+ }
326+ if defaultOverhead .SystemReserved != nil {
327+ overhead .SystemReserved = lo .Assign (overhead .SystemReserved , defaultOverhead .SystemReserved )
328+ }
329+ if defaultOverhead .EvictionThreshold != nil {
330+ overhead .EvictionThreshold = lo .Assign (overhead .EvictionThreshold , defaultOverhead .EvictionThreshold )
331+ }
332+
333+ overhead .KubeReserved = lo .Assign (overhead .KubeReserved , lo .MapEntries (kubeletConfig .KubeReserved , func (k string , v string ) (corev1.ResourceName , resource.Quantity ) {
334+ return corev1 .ResourceName (k ), resource .MustParse (v )
335+ }))
336+ overhead .SystemReserved = lo .Assign (overhead .SystemReserved , lo .MapEntries (kubeletConfig .SystemReserved , func (k string , v string ) (corev1.ResourceName , resource.Quantity ) {
337+ return corev1 .ResourceName (k ), resource .MustParse (v )
338+ }))
339+ if kubeletConfig .EvictionHard != nil {
340+ if v , ok := kubeletConfig .EvictionHard [MemoryAvailable ]; ok {
341+ overhead .EvictionThreshold [corev1 .ResourceMemory ] = computeEvictionSignal (* capacity .Memory (), v )
342+ }
343+ if v , ok := kubeletConfig .EvictionHard [NodeFSAvailable ]; ok {
344+ overhead .EvictionThreshold [corev1 .ResourceEphemeralStorage ] = computeEvictionSignal (* capacity .StorageEphemeral (), v )
345+ }
346+ }
347+ return overhead
348+ }
0 commit comments