mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-20 17:38:50 +00:00
feature: support Memory QoS for cgroups v2
This commit is contained in:
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package fuzzer
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/google/gofuzz"
|
||||
@@ -29,6 +30,7 @@ import (
|
||||
kubeletconfigv1beta1 "k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/kubelet/qos"
|
||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
// Funcs returns the fuzzer functions for the kubeletconfig apis.
|
||||
@@ -106,6 +108,7 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
|
||||
obj.Logging.Format = "text"
|
||||
}
|
||||
obj.EnableSystemLogHandler = true
|
||||
obj.MemoryThrottlingFactor = utilpointer.Float64Ptr(rand.Float64())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@@ -249,5 +249,6 @@ var (
|
||||
"VolumePluginDir",
|
||||
"ShutdownGracePeriod.Duration",
|
||||
"ShutdownGracePeriodCriticalPods.Duration",
|
||||
"MemoryThrottlingFactor",
|
||||
)
|
||||
)
|
||||
|
@@ -59,6 +59,7 @@ maxOpenFiles: 1000000
|
||||
maxPods: 110
|
||||
memoryManagerPolicy: None
|
||||
memorySwap: {}
|
||||
memoryThrottlingFactor: 0.8
|
||||
nodeLeaseDurationSeconds: 40
|
||||
nodeStatusMaxImages: 50
|
||||
nodeStatusReportFrequency: 5m0s
|
||||
|
@@ -59,6 +59,7 @@ maxOpenFiles: 1000000
|
||||
maxPods: 110
|
||||
memoryManagerPolicy: None
|
||||
memorySwap: {}
|
||||
memoryThrottlingFactor: 0.8
|
||||
nodeLeaseDurationSeconds: 40
|
||||
nodeStatusMaxImages: 50
|
||||
nodeStatusReportFrequency: 5m0s
|
||||
|
@@ -413,6 +413,15 @@ type KubeletConfiguration struct {
|
||||
EnableDebugFlagsHandler bool
|
||||
// SeccompDefault enables the use of `RuntimeDefault` as the default seccomp profile for all workloads.
|
||||
SeccompDefault bool
|
||||
// MemoryThrottlingFactor specifies the factor multiplied by the memory limit or node allocatable memory
|
||||
// when setting the cgroupv2 memory.high value to enforce MemoryQoS.
|
||||
// Decreasing this factor will set lower high limit for container cgroups and put heavier reclaim pressure
|
||||
// while increasing will put less reclaim pressure.
|
||||
// See http://kep.k8s.io/2570 for more details.
|
||||
// Default: 0.8
|
||||
// +featureGate=MemoryQoS
|
||||
// +optional
|
||||
MemoryThrottlingFactor *float64
|
||||
}
|
||||
|
||||
// KubeletAuthorizationMode denotes the authorization mode for the kubelet
|
||||
|
@@ -36,6 +36,9 @@ const (
|
||||
DefaultIPTablesMasqueradeBit = 14
|
||||
DefaultIPTablesDropBit = 15
|
||||
DefaultVolumePluginDir = "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/"
|
||||
|
||||
// See https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2570-memory-qos
|
||||
DefaultMemoryThrottlingFactor = 0.8
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -255,4 +258,7 @@ func SetDefaults_KubeletConfiguration(obj *kubeletconfigv1beta1.KubeletConfigura
|
||||
if obj.SeccompDefault == nil {
|
||||
obj.SeccompDefault = utilpointer.BoolPtr(false)
|
||||
}
|
||||
if obj.MemoryThrottlingFactor == nil {
|
||||
obj.MemoryThrottlingFactor = utilpointer.Float64Ptr(DefaultMemoryThrottlingFactor)
|
||||
}
|
||||
}
|
||||
|
@@ -387,6 +387,7 @@ func autoConvert_v1beta1_KubeletConfiguration_To_config_KubeletConfiguration(in
|
||||
if err := v1.Convert_Pointer_bool_To_bool(&in.SeccompDefault, &out.SeccompDefault, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.MemoryThrottlingFactor = (*float64)(unsafe.Pointer(in.MemoryThrottlingFactor))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -554,6 +555,7 @@ func autoConvert_config_KubeletConfiguration_To_v1beta1_KubeletConfiguration(in
|
||||
if err := v1.Convert_bool_To_Pointer_bool(&in.SeccompDefault, &out.SeccompDefault, s); err != nil {
|
||||
return err
|
||||
}
|
||||
out.MemoryThrottlingFactor = (*float64)(unsafe.Pointer(in.MemoryThrottlingFactor))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@@ -212,5 +212,13 @@ func ValidateKubeletConfiguration(kc *kubeletconfig.KubeletConfiguration) error
|
||||
if errs := logs.ValidateLoggingConfiguration(&kc.Logging, field.NewPath("logging")); len(errs) > 0 {
|
||||
allErrors = append(allErrors, errs.ToAggregate().Errors()...)
|
||||
}
|
||||
|
||||
if localFeatureGate.Enabled(features.MemoryQoS) && kc.MemoryThrottlingFactor == nil {
|
||||
allErrors = append(allErrors, fmt.Errorf("invalid configuration: memoryThrottlingFactor is required when MemoryQoS feature flag is enabled"))
|
||||
}
|
||||
if kc.MemoryThrottlingFactor != nil && (*kc.MemoryThrottlingFactor <= 0 || *kc.MemoryThrottlingFactor > 1.0) {
|
||||
allErrors = append(allErrors, fmt.Errorf("invalid configuration: memoryThrottlingFactor %v must be greater than 0 and less than or equal to 1.0", kc.MemoryThrottlingFactor))
|
||||
}
|
||||
|
||||
return utilerrors.NewAggregate(allErrors)
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ import (
|
||||
componentbaseconfig "k8s.io/component-base/config"
|
||||
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
||||
utilpointer "k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
func TestValidateKubeletConfiguration(t *testing.T) {
|
||||
@@ -59,9 +60,11 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
||||
TopologyManagerPolicy: kubeletconfig.SingleNumaNodeTopologyManagerPolicy,
|
||||
ShutdownGracePeriod: metav1.Duration{Duration: 30 * time.Second},
|
||||
ShutdownGracePeriodCriticalPods: metav1.Duration{Duration: 10 * time.Second},
|
||||
MemoryThrottlingFactor: utilpointer.Float64Ptr(0.8),
|
||||
FeatureGates: map[string]bool{
|
||||
"CustomCPUCFSQuotaPeriod": true,
|
||||
"GracefulNodeShutdown": true,
|
||||
"MemoryQoS": true,
|
||||
},
|
||||
Logging: componentbaseconfig.LoggingConfiguration{
|
||||
Format: "text",
|
||||
@@ -103,8 +106,10 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
||||
TopologyManagerPolicy: kubeletconfig.NoneTopologyManagerPolicy,
|
||||
ShutdownGracePeriod: metav1.Duration{Duration: 10 * time.Minute},
|
||||
ShutdownGracePeriodCriticalPods: metav1.Duration{Duration: 0},
|
||||
MemoryThrottlingFactor: utilpointer.Float64Ptr(0.9),
|
||||
FeatureGates: map[string]bool{
|
||||
"CustomCPUCFSQuotaPeriod": true,
|
||||
"MemoryQoS": true,
|
||||
},
|
||||
Logging: componentbaseconfig.LoggingConfiguration{
|
||||
Format: "text",
|
||||
@@ -147,10 +152,12 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
||||
ShutdownGracePeriod: metav1.Duration{Duration: 10 * time.Minute},
|
||||
ShutdownGracePeriodCriticalPods: metav1.Duration{Duration: 0},
|
||||
MemorySwap: kubeletconfig.MemorySwapConfiguration{SwapBehavior: kubetypes.UnlimitedSwap},
|
||||
MemoryThrottlingFactor: utilpointer.Float64Ptr(0.5),
|
||||
FeatureGates: map[string]bool{
|
||||
"CustomCPUCFSQuotaPeriod": true,
|
||||
"GracefulNodeShutdown": true,
|
||||
"NodeSwapEnabled": true,
|
||||
"MemoryQoS": true,
|
||||
},
|
||||
Logging: componentbaseconfig.LoggingConfiguration{
|
||||
Format: "text",
|
||||
@@ -230,16 +237,18 @@ func TestValidateKubeletConfiguration(t *testing.T) {
|
||||
ShutdownGracePeriod: metav1.Duration{Duration: 40 * time.Second},
|
||||
ShutdownGracePeriodCriticalPods: metav1.Duration{Duration: 10 * time.Second},
|
||||
MemorySwap: kubeletconfig.MemorySwapConfiguration{SwapBehavior: "invalid"},
|
||||
MemoryThrottlingFactor: utilpointer.Float64Ptr(1.1),
|
||||
FeatureGates: map[string]bool{
|
||||
"CustomCPUCFSQuotaPeriod": true,
|
||||
"GracefulNodeShutdown": true,
|
||||
"NodeSwapEnabled": true,
|
||||
"MemoryQoS": true,
|
||||
},
|
||||
Logging: componentbaseconfig.LoggingConfiguration{
|
||||
Format: "text",
|
||||
},
|
||||
}
|
||||
const numErrsErrorCase2 = 4
|
||||
const numErrsErrorCase2 = 5
|
||||
if allErrors := ValidateKubeletConfiguration(errorCase2); len(allErrors.(utilerrors.Aggregate).Errors()) != numErrsErrorCase2 {
|
||||
t.Errorf("expect %d errors, got %v", numErrsErrorCase2, len(allErrors.(utilerrors.Aggregate).Errors()))
|
||||
}
|
||||
|
5
pkg/kubelet/apis/config/zz_generated.deepcopy.go
generated
5
pkg/kubelet/apis/config/zz_generated.deepcopy.go
generated
@@ -282,6 +282,11 @@ func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.MemoryThrottlingFactor != nil {
|
||||
in, out := &in.MemoryThrottlingFactor, &out.MemoryThrottlingFactor
|
||||
*out = new(float64)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user