kubelet: add and use ImageMaximumGCAge in KubeletConfiguration

Signed-off-by: Peter Hunt <pehunt@redhat.com>
This commit is contained in:
Peter Hunt 2023-10-06 12:43:37 -04:00
parent 28f335a339
commit d992ea4b30
14 changed files with 46 additions and 1 deletions

View File

@ -897,6 +897,13 @@ const (
// alpha: v1.29 // alpha: v1.29
// LoadBalancerIPMode enables the IPMode field in the LoadBalancerIngress status of a Service // LoadBalancerIPMode enables the IPMode field in the LoadBalancerIngress status of a Service
LoadBalancerIPMode featuregate.Feature = "LoadBalancerIPMode" LoadBalancerIPMode featuregate.Feature = "LoadBalancerIPMode"
// owner: @haircommander
// kep: http://kep.k8s.io/4210
// alpha: v1.29
// ImageMaximumGCAge enables the Kubelet configuration field of the same name, allowing an admin
// to specify the age after which an image will be garbage collected.
ImageMaximumGCAge featuregate.Feature = "ImageMaximumGCAge"
) )
func init() { func init() {
@ -1140,6 +1147,8 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
LoadBalancerIPMode: {Default: false, PreRelease: featuregate.Alpha}, LoadBalancerIPMode: {Default: false, PreRelease: featuregate.Alpha},
ImageMaximumGCAge: {Default: false, PreRelease: featuregate.Alpha},
// inherited features from generic apiserver, relisted here to get a conflict if it is changed // inherited features from generic apiserver, relisted here to get a conflict if it is changed
// unintentionally on either side: // unintentionally on either side:

View File

@ -55592,6 +55592,12 @@ func schema_k8sio_kubelet_config_v1beta1_KubeletConfiguration(ref common.Referen
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Duration"), Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Duration"),
}, },
}, },
"imageMaximumGCAge": {
SchemaProps: spec.SchemaProps{
Description: "imageMaximumGCAge is the maximum age an image can be unused before it is garbage collected. The default of this field is \"0s\", which disables this field--meaning images won't be garbage collected based on being unused for too long. Default: \"0s\" (disabled)",
Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Duration"),
},
},
"imageGCHighThresholdPercent": { "imageGCHighThresholdPercent": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "imageGCHighThresholdPercent is the percent of disk usage after which image garbage collection is always run. The percent is calculated by dividing this field value by 100, so this field must be between 0 and 100, inclusive. When specified, the value must be greater than imageGCLowThresholdPercent. Default: 85", Description: "imageGCHighThresholdPercent is the percent of disk usage after which image garbage collection is always run. The percent is calculated by dividing this field value by 100, so this field must be between 0 and 100, inclusive. When specified, the value must be greater than imageGCLowThresholdPercent. Default: 85",

View File

@ -61,6 +61,7 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
obj.HealthzPort = 10248 obj.HealthzPort = 10248
obj.HTTPCheckFrequency = metav1.Duration{Duration: 20 * time.Second} obj.HTTPCheckFrequency = metav1.Duration{Duration: 20 * time.Second}
obj.ImageMinimumGCAge = metav1.Duration{Duration: 2 * time.Minute} obj.ImageMinimumGCAge = metav1.Duration{Duration: 2 * time.Minute}
obj.ImageMaximumGCAge = metav1.Duration{}
obj.ImageGCHighThresholdPercent = 85 obj.ImageGCHighThresholdPercent = 85
obj.ImageGCLowThresholdPercent = 80 obj.ImageGCLowThresholdPercent = 80
obj.KernelMemcgNotification = false obj.KernelMemcgNotification = false

View File

@ -230,6 +230,7 @@ var (
"ImageGCHighThresholdPercent", "ImageGCHighThresholdPercent",
"ImageGCLowThresholdPercent", "ImageGCLowThresholdPercent",
"ImageMinimumGCAge.Duration", "ImageMinimumGCAge.Duration",
"ImageMaximumGCAge.Duration",
"KernelMemcgNotification", "KernelMemcgNotification",
"KubeAPIBurst", "KubeAPIBurst",
"KubeAPIQPS", "KubeAPIQPS",

View File

@ -43,6 +43,7 @@ healthzPort: 10248
httpCheckFrequency: 20s httpCheckFrequency: 20s
imageGCHighThresholdPercent: 85 imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80 imageGCLowThresholdPercent: 80
imageMaximumGCAge: 0s
imageMinimumGCAge: 2m0s imageMinimumGCAge: 2m0s
iptablesDropBit: 15 iptablesDropBit: 15
iptablesMasqueradeBit: 14 iptablesMasqueradeBit: 14

View File

@ -43,6 +43,7 @@ healthzPort: 10248
httpCheckFrequency: 20s httpCheckFrequency: 20s
imageGCHighThresholdPercent: 85 imageGCHighThresholdPercent: 85
imageGCLowThresholdPercent: 80 imageGCLowThresholdPercent: 80
imageMaximumGCAge: 0s
imageMinimumGCAge: 2m0s imageMinimumGCAge: 2m0s
iptablesDropBit: 15 iptablesDropBit: 15
iptablesMasqueradeBit: 14 iptablesMasqueradeBit: 14

View File

@ -192,9 +192,13 @@ type KubeletConfiguration struct {
NodeStatusReportFrequency metav1.Duration NodeStatusReportFrequency metav1.Duration
// nodeLeaseDurationSeconds is the duration the Kubelet will set on its corresponding Lease. // nodeLeaseDurationSeconds is the duration the Kubelet will set on its corresponding Lease.
NodeLeaseDurationSeconds int32 NodeLeaseDurationSeconds int32
// imageMinimumGCAge is the minimum age for an unused image before it is // ImageMinimumGCAge is the minimum age for an unused image before it is
// garbage collected. // garbage collected.
ImageMinimumGCAge metav1.Duration ImageMinimumGCAge metav1.Duration
// ImageMaximumGCAge is the maximum age an image can be unused before it is garbage collected.
// The default of this field is "0s", which disables this field--meaning images won't be garbage
// collected based on being unused for too long.
ImageMaximumGCAge metav1.Duration
// imageGCHighThresholdPercent is the percent of disk usage after which // imageGCHighThresholdPercent is the percent of disk usage after which
// image garbage collection is always run. The percent is calculated as // image garbage collection is always run. The percent is calculated as
// this field value out of 100. // this field value out of 100.

View File

@ -77,6 +77,7 @@ func TestSetDefaultsKubeletConfiguration(t *testing.T) {
NodeStatusReportFrequency: metav1.Duration{Duration: 5 * time.Minute}, NodeStatusReportFrequency: metav1.Duration{Duration: 5 * time.Minute},
NodeLeaseDurationSeconds: 40, NodeLeaseDurationSeconds: 40,
ImageMinimumGCAge: metav1.Duration{Duration: 2 * time.Minute}, ImageMinimumGCAge: metav1.Duration{Duration: 2 * time.Minute},
ImageMaximumGCAge: metav1.Duration{},
ImageGCHighThresholdPercent: utilpointer.Int32(85), ImageGCHighThresholdPercent: utilpointer.Int32(85),
ImageGCLowThresholdPercent: utilpointer.Int32(80), ImageGCLowThresholdPercent: utilpointer.Int32(80),
ContainerRuntimeEndpoint: "unix:///run/containerd/containerd.sock", ContainerRuntimeEndpoint: "unix:///run/containerd/containerd.sock",

View File

@ -392,6 +392,7 @@ func autoConvert_v1beta1_KubeletConfiguration_To_config_KubeletConfiguration(in
out.NodeStatusReportFrequency = in.NodeStatusReportFrequency out.NodeStatusReportFrequency = in.NodeStatusReportFrequency
out.NodeLeaseDurationSeconds = in.NodeLeaseDurationSeconds out.NodeLeaseDurationSeconds = in.NodeLeaseDurationSeconds
out.ImageMinimumGCAge = in.ImageMinimumGCAge out.ImageMinimumGCAge = in.ImageMinimumGCAge
out.ImageMaximumGCAge = in.ImageMaximumGCAge
if err := v1.Convert_Pointer_int32_To_int32(&in.ImageGCHighThresholdPercent, &out.ImageGCHighThresholdPercent, s); err != nil { if err := v1.Convert_Pointer_int32_To_int32(&in.ImageGCHighThresholdPercent, &out.ImageGCHighThresholdPercent, s); err != nil {
return err return err
} }
@ -579,6 +580,7 @@ func autoConvert_config_KubeletConfiguration_To_v1beta1_KubeletConfiguration(in
out.NodeStatusReportFrequency = in.NodeStatusReportFrequency out.NodeStatusReportFrequency = in.NodeStatusReportFrequency
out.NodeLeaseDurationSeconds = in.NodeLeaseDurationSeconds out.NodeLeaseDurationSeconds = in.NodeLeaseDurationSeconds
out.ImageMinimumGCAge = in.ImageMinimumGCAge out.ImageMinimumGCAge = in.ImageMinimumGCAge
out.ImageMaximumGCAge = in.ImageMaximumGCAge
if err := v1.Convert_int32_To_Pointer_int32(&in.ImageGCHighThresholdPercent, &out.ImageGCHighThresholdPercent, s); err != nil { if err := v1.Convert_int32_To_Pointer_int32(&in.ImageGCHighThresholdPercent, &out.ImageGCHighThresholdPercent, s); err != nil {
return err return err
} }

View File

@ -202,6 +202,7 @@ func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) {
out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency
out.NodeStatusReportFrequency = in.NodeStatusReportFrequency out.NodeStatusReportFrequency = in.NodeStatusReportFrequency
out.ImageMinimumGCAge = in.ImageMinimumGCAge out.ImageMinimumGCAge = in.ImageMinimumGCAge
out.ImageMaximumGCAge = in.ImageMaximumGCAge
out.VolumeStatsAggPeriod = in.VolumeStatsAggPeriod out.VolumeStatsAggPeriod = in.VolumeStatsAggPeriod
if in.CPUManagerPolicyOptions != nil { if in.CPUManagerPolicyOptions != nil {
in, out := &in.CPUManagerPolicyOptions, &out.CPUManagerPolicyOptions in, out := &in.CPUManagerPolicyOptions, &out.CPUManagerPolicyOptions

View File

@ -78,6 +78,11 @@ type ImageGCPolicy struct {
// Minimum age at which an image can be garbage collected. // Minimum age at which an image can be garbage collected.
MinAge time.Duration MinAge time.Duration
// Maximum age after which an image can be garbage collected, regardless of disk usage.
// Currently gated by MaximumImageGCAge feature gate and Kubelet configuration.
// If 0, the feature is disabled.
MaxAge time.Duration
} }
type realImageGCManager struct { type realImageGCManager struct {

View File

@ -424,6 +424,12 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
LowThresholdPercent: int(kubeCfg.ImageGCLowThresholdPercent), LowThresholdPercent: int(kubeCfg.ImageGCLowThresholdPercent),
} }
if utilfeature.DefaultFeatureGate.Enabled(features.ImageMaximumGCAge) {
imageGCPolicy.MaxAge = kubeCfg.ImageMaximumGCAge.Duration
} else if kubeCfg.ImageMaximumGCAge.Duration != 0 {
klog.InfoS("ImageMaximumGCAge flag enabled, but corresponding feature gate is not enabled. Ignoring flag.")
}
enforceNodeAllocatable := kubeCfg.EnforceNodeAllocatable enforceNodeAllocatable := kubeCfg.EnforceNodeAllocatable
if experimentalNodeAllocatableIgnoreEvictionThreshold { if experimentalNodeAllocatableIgnoreEvictionThreshold {
// Do not provide kubeCfg.EnforceNodeAllocatable to eviction threshold parsing if we are not enforcing Evictions // Do not provide kubeCfg.EnforceNodeAllocatable to eviction threshold parsing if we are not enforcing Evictions

View File

@ -290,6 +290,12 @@ type KubeletConfiguration struct {
// Default: "2m" // Default: "2m"
// +optional // +optional
ImageMinimumGCAge metav1.Duration `json:"imageMinimumGCAge,omitempty"` ImageMinimumGCAge metav1.Duration `json:"imageMinimumGCAge,omitempty"`
// imageMaximumGCAge is the maximum age an image can be unused before it is garbage collected.
// The default of this field is "0s", which disables this field--meaning images won't be garbage
// collected based on being unused for too long.
// Default: "0s" (disabled)
// +optional
ImageMaximumGCAge metav1.Duration `json:"imageMaximumGCAge,omitempty"`
// imageGCHighThresholdPercent is the percent of disk usage after which // imageGCHighThresholdPercent is the percent of disk usage after which
// image garbage collection is always run. The percent is calculated by // image garbage collection is always run. The percent is calculated by
// dividing this field value by 100, so this field must be between 0 and // dividing this field value by 100, so this field must be between 0 and

View File

@ -237,6 +237,7 @@ func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) {
out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency out.NodeStatusUpdateFrequency = in.NodeStatusUpdateFrequency
out.NodeStatusReportFrequency = in.NodeStatusReportFrequency out.NodeStatusReportFrequency = in.NodeStatusReportFrequency
out.ImageMinimumGCAge = in.ImageMinimumGCAge out.ImageMinimumGCAge = in.ImageMinimumGCAge
out.ImageMaximumGCAge = in.ImageMaximumGCAge
if in.ImageGCHighThresholdPercent != nil { if in.ImageGCHighThresholdPercent != nil {
in, out := &in.ImageGCHighThresholdPercent, &out.ImageGCHighThresholdPercent in, out := &in.ImageGCHighThresholdPercent, &out.ImageGCHighThresholdPercent
*out = new(int32) *out = new(int32)