diff --git a/pkg/providers/amifamily/bootstrap/bottlerocket.go b/pkg/providers/amifamily/bootstrap/bottlerocket.go index f7dbddd1b9e3..0e988db8f497 100644 --- a/pkg/providers/amifamily/bootstrap/bottlerocket.go +++ b/pkg/providers/amifamily/bootstrap/bottlerocket.go @@ -64,6 +64,9 @@ func (b Bottlerocket) Script() (string, error) { if b.KubeletConfig.EvictionHard != nil { s.Settings.Kubernetes.EvictionHard = b.KubeletConfig.EvictionHard } + if b.KubeletConfig.EvictionSoft != nil { + s.Settings.Kubernetes.EvictionSoft = b.KubeletConfig.EvictionSoft + } if b.KubeletConfig.ImageGCHighThresholdPercent != nil { s.Settings.Kubernetes.ImageGCHighThresholdPercent = lo.ToPtr(strconv.FormatInt(int64(*b.KubeletConfig.ImageGCHighThresholdPercent), 10)) } diff --git a/pkg/providers/amifamily/bootstrap/bottlerocketsettings.go b/pkg/providers/amifamily/bootstrap/bottlerocketsettings.go index fe6c44d4d7f1..8d5099cf73f2 100644 --- a/pkg/providers/amifamily/bootstrap/bottlerocketsettings.go +++ b/pkg/providers/amifamily/bootstrap/bottlerocketsettings.go @@ -54,6 +54,7 @@ type BottlerocketKubernetes struct { MaxPods *int `toml:"max-pods,omitempty"` StaticPods map[string]BottlerocketStaticPod `toml:"static-pods,omitempty"` EvictionHard map[string]string `toml:"eviction-hard,omitempty"` + EvictionSoft map[string]string `toml:"eviction-soft,omitempty"` KubeReserved map[string]string `toml:"kube-reserved,omitempty"` SystemReserved map[string]string `toml:"system-reserved,omitempty"` AllowedUnsafeSysctls []string `toml:"allowed-unsafe-sysctls,omitempty"` diff --git a/pkg/providers/amifamily/bottlerocket.go b/pkg/providers/amifamily/bottlerocket.go index a6bfe1c3bd15..869cf1f6b99d 100644 --- a/pkg/providers/amifamily/bottlerocket.go +++ b/pkg/providers/amifamily/bottlerocket.go @@ -122,7 +122,6 @@ func (b Bottlerocket) FeatureFlags() FeatureFlags { return FeatureFlags{ UsesENILimitedMemoryOverhead: false, PodsPerCoreEnabled: false, - EvictionSoftEnabled: false, SupportsENILimitedPodDensity: true, } } diff --git a/test/suites/ami/suite_test.go b/test/suites/ami/suite_test.go index 7ab83cb377c5..2b801332bbf8 100644 --- a/test/suites/ami/suite_test.go +++ b/test/suites/ami/suite_test.go @@ -282,6 +282,7 @@ var _ = Describe("AMI", func() { actualUserData, err := base64.StdEncoding.DecodeString(*getInstanceAttribute(pod.Spec.NodeName, "userData").UserData.Value) Expect(err).ToNot(HaveOccurred()) Expect(string(actualUserData)).To(ContainSubstring("kube-api-qps = 30")) + Expect(string(actualUserData)).To(ContainSubstring("memory.available = 300Mi")) }) // Windows tests are can flake due to the instance types that are used in testing. // The VPC Resource controller will need to support the instance types that are used. diff --git a/test/suites/ami/testdata/br_userdata_input.sh b/test/suites/ami/testdata/br_userdata_input.sh index c157a6769852..c98793054bf2 100644 --- a/test/suites/ami/testdata/br_userdata_input.sh +++ b/test/suites/ami/testdata/br_userdata_input.sh @@ -2,3 +2,5 @@ kube-api-qps = 30 [settings.kubernetes.node-taints] "node.cilium.io/agent-not-ready" = ["true:NoExecute"] +[settings.kubernetes.eviction-soft] +"memory.available" = "300Mi" diff --git a/test/suites/integration/kubelet_config_test.go b/test/suites/integration/kubelet_config_test.go index b7f06f3175c8..967239fb1151 100644 --- a/test/suites/integration/kubelet_config_test.go +++ b/test/suites/integration/kubelet_config_test.go @@ -240,6 +240,28 @@ var _ = Describe("KubeletConfiguration Overrides", func() { }) selector := labels.SelectorFromSet(dep.Spec.Selector.MatchLabels) + env.ExpectCreated(nodeClass, nodePool, dep) + env.EventuallyExpectHealthyPodCount(selector, numPods) + env.ExpectCreatedNodeCount("==", 1) + env.EventuallyExpectUniqueNodeNames(selector, 1) + }) + It("should use evictionSoft and evictionHard settings in kubelet when Bottlerocket is used", func() { + nodeClass.Spec.AMISelectorTerms = []v1.AMISelectorTerm{{Alias: "bottlerocket@latest"}} + nodeClass.Spec.Kubelet = &v1.KubeletConfiguration{ + EvictionSoft: map[string]string{"memory.available": "10%"}, + EvictionHard: map[string]string{"memory.available": "5%"}, + } + numPods := 3 + dep := test.Deployment(test.DeploymentOptions{ + Replicas: int32(numPods), + PodOptions: test.PodOptions{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"app": "sample-app"}, + }, + }, + }) + selector := labels.SelectorFromSet(dep.Spec.Selector.MatchLabels) + env.ExpectCreated(nodeClass, nodePool, dep) env.EventuallyExpectHealthyPodCount(selector, numPods) env.ExpectCreatedNodeCount("==", 1)