Skip to content

Commit 59f330e

Browse files
Merge pull request #5390 from ngopalak-redhat/ngopalak/4.21-auto-sizing
OCPNODE-3719: Default Enablement of Auto Sizing Reserved in OpenShift 4.21
2 parents 275774a + 18dbd1a commit 59f330e

File tree

6 files changed

+217
-4
lines changed

6 files changed

+217
-4
lines changed

pkg/controller/common/constants.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,9 @@ const (
140140
// Stub Ignition upgrade related annotation keys
141141
StubIgnitionVersionAnnotation = "machineconfiguration.openshift.io/stub-ignition-upgraded-to"
142142
StubIgnitionTimestampAnnotation = "machineconfiguration.openshift.io/stub-ignition-upgraded-at"
143+
144+
// NodeSizingEnabledEnvPath is the file path for the node sizing enabled environment file
145+
NodeSizingEnabledEnvPath = "/etc/node-sizing-enabled.env"
143146
)
144147

145148
// Commonly-used MCO ConfigMap names

pkg/controller/kubelet-config/helpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func createNewKubeletDynamicSystemReservedIgnition(autoSystemReserved *bool, use
6868
config := fmt.Sprintf("NODE_SIZING_ENABLED=%s\nSYSTEM_RESERVED_MEMORY=%s\nSYSTEM_RESERVED_CPU=%s\nSYSTEM_RESERVED_ES=%s\n",
6969
autoNodeSizing, systemReservedMemory, systemReservedCPU, systemReservedEphemeralStorage)
7070

71-
r := ctrlcommon.NewIgnFileBytesOverwriting("/etc/node-sizing-enabled.env", []byte(config))
71+
r := ctrlcommon.NewIgnFileBytesOverwriting(ctrlcommon.NodeSizingEnabledEnvPath, []byte(config))
7272
return &r
7373
}
7474

pkg/controller/template/template_controller_test.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package template
33
import (
44
"fmt"
55
"reflect"
6+
"strings"
67
"testing"
78
"time"
89

@@ -448,3 +449,118 @@ func getKey(config *mcfgv1.ControllerConfig, t *testing.T) string {
448449
}
449450
return key
450451
}
452+
453+
func TestKubeletAutoNodeSizingEnabled(t *testing.T) {
454+
cc := newControllerConfig("test-cluster")
455+
ps := []byte(`{"dummy": "dummy"}`)
456+
457+
mcs, err := getMachineConfigsForControllerConfig(templateDir, cc, ps, nil)
458+
if err != nil {
459+
t.Fatal(err)
460+
}
461+
462+
// Find machine configs that should contain the auto-node-sizing file
463+
// The file should be in all role-based machine configs (master, worker)
464+
autoSizingFileFound := false
465+
for _, mc := range mcs {
466+
ignCfg, err := ctrlcommon.ParseAndConvertConfig(mc.Spec.Config.Raw)
467+
if err != nil {
468+
t.Fatalf("Failed to parse ignition config for %s: %v", mc.Name, err)
469+
}
470+
471+
// Look for the auto-node-sizing file
472+
for _, file := range ignCfg.Storage.Files {
473+
if file.Path == ctrlcommon.NodeSizingEnabledEnvPath {
474+
autoSizingFileFound = true
475+
476+
// Decode the file contents
477+
contents, err := ctrlcommon.DecodeIgnitionFileContents(file.Contents.Source, file.Contents.Compression)
478+
if err != nil {
479+
t.Fatalf("Failed to decode auto-node-sizing file contents: %v", err)
480+
}
481+
482+
contentsStr := string(contents)
483+
484+
// Verify NODE_SIZING_ENABLED=true is present
485+
if !strings.Contains(contentsStr, "NODE_SIZING_ENABLED=true") {
486+
t.Errorf("Expected NODE_SIZING_ENABLED=true in %s, got: %s", mc.Name, contentsStr)
487+
}
488+
489+
// Verify other expected values
490+
if !strings.Contains(contentsStr, "SYSTEM_RESERVED_MEMORY=1Gi") {
491+
t.Errorf("Expected SYSTEM_RESERVED_MEMORY=1Gi in %s, got: %s", mc.Name, contentsStr)
492+
}
493+
494+
if !strings.Contains(contentsStr, "SYSTEM_RESERVED_CPU=500m") {
495+
t.Errorf("Expected SYSTEM_RESERVED_CPU=500m in %s, got: %s", mc.Name, contentsStr)
496+
}
497+
498+
if !strings.Contains(contentsStr, "SYSTEM_RESERVED_ES=1Gi") {
499+
t.Errorf("Expected SYSTEM_RESERVED_ES=1Gi in %s, got: %s", mc.Name, contentsStr)
500+
}
501+
}
502+
}
503+
}
504+
505+
if !autoSizingFileFound {
506+
t.Errorf("Expected to find %s file in at least one machine config", ctrlcommon.NodeSizingEnabledEnvPath)
507+
}
508+
}
509+
510+
func TestKubeletAutoNodeSizingDisabledForHypershift(t *testing.T) {
511+
cc := newControllerConfig("test-cluster")
512+
// Set ControlPlaneTopology to External to simulate Hypershift
513+
cc.Spec.Infra.Status.ControlPlaneTopology = configv1.ExternalTopologyMode
514+
ps := []byte(`{"dummy": "dummy"}`)
515+
516+
mcs, err := getMachineConfigsForControllerConfig(templateDir, cc, ps, nil)
517+
if err != nil {
518+
t.Fatal(err)
519+
}
520+
521+
// Find machine configs that should contain the auto-node-sizing file
522+
autoSizingFileFound := false
523+
for _, mc := range mcs {
524+
ignCfg, err := ctrlcommon.ParseAndConvertConfig(mc.Spec.Config.Raw)
525+
if err != nil {
526+
t.Fatalf("Failed to parse ignition config for %s: %v", mc.Name, err)
527+
}
528+
529+
// Look for the auto-node-sizing file
530+
for _, file := range ignCfg.Storage.Files {
531+
if file.Path == ctrlcommon.NodeSizingEnabledEnvPath {
532+
autoSizingFileFound = true
533+
534+
// Decode the file contents
535+
contents, err := ctrlcommon.DecodeIgnitionFileContents(file.Contents.Source, file.Contents.Compression)
536+
if err != nil {
537+
t.Fatalf("Failed to decode auto-node-sizing file contents: %v", err)
538+
}
539+
540+
contentsStr := string(contents)
541+
542+
// Verify NODE_SIZING_ENABLED=false is present for Hypershift
543+
if !strings.Contains(contentsStr, "NODE_SIZING_ENABLED=false") {
544+
t.Errorf("Expected NODE_SIZING_ENABLED=false for Hypershift in %s, got: %s", mc.Name, contentsStr)
545+
}
546+
547+
// Verify other expected values are still present
548+
if !strings.Contains(contentsStr, "SYSTEM_RESERVED_MEMORY=1Gi") {
549+
t.Errorf("Expected SYSTEM_RESERVED_MEMORY=1Gi in %s, got: %s", mc.Name, contentsStr)
550+
}
551+
552+
if !strings.Contains(contentsStr, "SYSTEM_RESERVED_CPU=500m") {
553+
t.Errorf("Expected SYSTEM_RESERVED_CPU=500m in %s, got: %s", mc.Name, contentsStr)
554+
}
555+
556+
if !strings.Contains(contentsStr, "SYSTEM_RESERVED_ES=1Gi") {
557+
t.Errorf("Expected SYSTEM_RESERVED_ES=1Gi in %s, got: %s", mc.Name, contentsStr)
558+
}
559+
}
560+
}
561+
}
562+
563+
if !autoSizingFileFound {
564+
t.Errorf("Expected to find %s file in at least one machine config", ctrlcommon.NodeSizingEnabledEnvPath)
565+
}
566+
}

templates/common/_base/files/kubelet-auto-node-sizing-enabled.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mode: 0644
22
path: "/etc/node-sizing-enabled.env"
33
contents:
44
inline: |
5-
NODE_SIZING_ENABLED=false
5+
NODE_SIZING_ENABLED={{if eq .Infra.Status.ControlPlaneTopology "External"}}false{{else}}true{{end}}
66
SYSTEM_RESERVED_MEMORY=1Gi
77
SYSTEM_RESERVED_CPU=500m
88
SYSTEM_RESERVED_ES=1Gi

test/e2e-2of2/kubeletcfg_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,13 @@ func TestKubeletConfigDefaultUpdateFreq(t *testing.T) {
5050
func TestKubeletConfigMaxPods(t *testing.T) {
5151
kcRaw1, err := kcfg.EncodeKubeletConfig(&kubeletconfigv1beta1.KubeletConfiguration{MaxPods: 100}, kubeletconfigv1beta1.SchemeGroupVersion, runtime.ContentTypeJSON)
5252
require.Nil(t, err, "failed to encode kubelet config")
53-
autoNodeSizing := true
53+
autoNodeSizingEnabled := true
54+
autoNodeSizingDisabled := false
55+
// Initial default is enabled
5456
kc1 := &mcfgv1.KubeletConfig{
5557
ObjectMeta: metav1.ObjectMeta{Name: "test-101"},
5658
Spec: mcfgv1.KubeletConfigSpec{
57-
AutoSizingReserved: &autoNodeSizing,
59+
AutoSizingReserved: &autoNodeSizingDisabled,
5860
KubeletConfig: &runtime.RawExtension{
5961
Raw: kcRaw1,
6062
},
@@ -65,6 +67,7 @@ func TestKubeletConfigMaxPods(t *testing.T) {
6567
kc2 := &mcfgv1.KubeletConfig{
6668
ObjectMeta: metav1.ObjectMeta{Name: "test-200"},
6769
Spec: mcfgv1.KubeletConfigSpec{
70+
AutoSizingReserved: &autoNodeSizingEnabled,
6871
KubeletConfig: &runtime.RawExtension{
6972
Raw: kcRaw2,
7073
},

test/e2e-bootstrap/bootstrap_test.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,97 @@ metadata:
389389
}
390390
}
391391

392+
func TestNodeSizingEnabled(t *testing.T) {
393+
ctx := context.Background()
394+
395+
testEnv := framework.NewTestEnv(t)
396+
397+
configv1.Install(scheme.Scheme)
398+
configv1alpha1.Install(scheme.Scheme)
399+
mcfgv1.Install(scheme.Scheme)
400+
apioperatorsv1alpha1.Install(scheme.Scheme)
401+
402+
baseTestManifests := loadBaseTestManifests(t)
403+
404+
cfg, err := testEnv.Start()
405+
require.NoError(t, err)
406+
defer func() {
407+
assert.NoError(t, testEnv.Stop())
408+
}()
409+
410+
clientSet := framework.NewClientSetFromConfig(cfg)
411+
412+
_, err = clientSet.Namespaces().Create(ctx, &corev1.Namespace{
413+
ObjectMeta: metav1.ObjectMeta{
414+
Name: framework.OpenshiftConfigNamespace,
415+
},
416+
}, metav1.CreateOptions{})
417+
require.NoError(t, err)
418+
419+
_, err = clientSet.Namespaces().Create(ctx, &corev1.Namespace{
420+
ObjectMeta: metav1.ObjectMeta{
421+
Name: bootstrapTestName,
422+
},
423+
}, metav1.CreateOptions{})
424+
require.NoError(t, err)
425+
426+
objs := append([]runtime.Object{}, baseTestManifests...)
427+
428+
// Add node config
429+
nodeConfigManifest := [][]byte{
430+
[]byte(`apiVersion: config.openshift.io/v1
431+
kind: Node
432+
metadata:
433+
name: cluster`),
434+
}
435+
objs = append(objs, loadRawManifests(t, nodeConfigManifest)...)
436+
437+
fixture := newTestFixture(t, cfg, objs)
438+
defer framework.CleanEnvironment(t, clientSet)
439+
defer fixture.stop()
440+
441+
// Fetch the controller rendered configurations
442+
controllerRenderedMasterConfigName, err := helpers.WaitForRenderedConfigs(t, clientSet, "master", []string{"99-master-ssh", "99-master-generated-registries"}...)
443+
require.NoError(t, err)
444+
t.Logf("Controller rendered master config as %q", controllerRenderedMasterConfigName)
445+
446+
controllerRenderedWorkerConfigName, err := helpers.WaitForRenderedConfigs(t, clientSet, "worker", []string{"99-worker-ssh", "99-worker-generated-registries"}...)
447+
require.NoError(t, err)
448+
t.Logf("Controller rendered worker config as %q", controllerRenderedWorkerConfigName)
449+
450+
// Verify node sizing enabled file for master
451+
verifyNodeSizingEnabled(t, clientSet, controllerRenderedMasterConfigName)
452+
453+
// Verify node sizing enabled file for worker
454+
verifyNodeSizingEnabled(t, clientSet, controllerRenderedWorkerConfigName)
455+
}
456+
457+
func verifyNodeSizingEnabled(t *testing.T, clientSet *framework.ClientSet, renderedConfigName string) {
458+
controllerMC, err := clientSet.MachineConfigs().Get(context.Background(), renderedConfigName, metav1.GetOptions{})
459+
require.NoError(t, err)
460+
461+
ignCfg, err := ctrlcommon.ParseAndConvertConfig(controllerMC.Spec.Config.Raw)
462+
require.NoError(t, err)
463+
464+
// Find the node sizing enabled file
465+
var foundFile bool
466+
for _, file := range ignCfg.Storage.Files {
467+
if file.Path == "/etc/node-sizing-enabled.env" {
468+
foundFile = true
469+
470+
// Decode the file contents
471+
contents, err := ctrlcommon.DecodeIgnitionFileContents(file.Contents.Source, file.Contents.Compression)
472+
require.NoError(t, err, "Failed to decode node-sizing-enabled.env file contents")
473+
474+
contentsStr := string(contents)
475+
require.Contains(t, contentsStr, "NODE_SIZING_ENABLED=true", "Expected /etc/node-sizing-enabled.env to contain NODE_SIZING_ENABLED=true in machine config %s", renderedConfigName)
476+
break
477+
}
478+
}
479+
480+
require.True(t, foundFile, "Expected to find /etc/node-sizing-enabled.env in machine config %s", renderedConfigName)
481+
}
482+
392483
func compareRenderedConfigPool(t *testing.T, clientSet *framework.ClientSet, destDir, poolName, controllerRenderedConfigName string) {
393484
paths, err := filepath.Glob(filepath.Join(destDir, "machine-configs", fmt.Sprintf("rendered-%s-*.yaml", poolName)))
394485
require.NoError(t, err)

0 commit comments

Comments
 (0)