1
16
17 package e2enode
18
19 import (
20 "context"
21 "path/filepath"
22 "strings"
23
24 v1 "k8s.io/api/core/v1"
25 nodev1 "k8s.io/api/node/v1"
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 "k8s.io/kubernetes/pkg/kubelet/cm"
28 "k8s.io/kubernetes/test/e2e/framework"
29 e2eruntimeclass "k8s.io/kubernetes/test/e2e/framework/node/runtimeclass"
30 e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
31 imageutils "k8s.io/kubernetes/test/utils/image"
32 admissionapi "k8s.io/pod-security-admission/api"
33
34 "github.com/onsi/ginkgo/v2"
35 )
36
37
38 func makePodToVerifyCgroupSize(cgroupNames []string, expectedCPU string, expectedMemory string) *v1.Pod {
39
40 cgroupFsNames := []string{}
41 rootCgroupName := cm.NewCgroupName(cm.RootCgroupName, defaultNodeAllocatableCgroup)
42 for _, baseName := range cgroupNames {
43
44 cgroupComponents := strings.Split(baseName, "/")
45 cgroupName := cm.NewCgroupName(rootCgroupName, cgroupComponents...)
46 cgroupFsNames = append(cgroupFsNames, toCgroupFsName(cgroupName))
47 }
48 framework.Logf("expecting %v cgroups to be found", cgroupFsNames)
49
50
51 command := ""
52 for _, cgroupFsName := range cgroupFsNames {
53 memLimitCgroup := filepath.Join("/host_cgroups/memory", cgroupFsName, "memory.limit_in_bytes")
54 cpuQuotaCgroup := filepath.Join("/host_cgroups/cpu", cgroupFsName, "cpu.cfs_quota_us")
55 localCommand := "if [ ! $(cat " + memLimitCgroup + ") == " + expectedMemory + " ] || [ ! $(cat " + cpuQuotaCgroup + ") == " + expectedCPU + " ]; then exit 1; fi; "
56
57 framework.Logf("command: %v: ", localCommand)
58 command += localCommand
59 }
60
61 pod := &v1.Pod{
62 ObjectMeta: metav1.ObjectMeta{
63 GenerateName: "cgroup-verification-pod-",
64 },
65 Spec: v1.PodSpec{
66 RestartPolicy: v1.RestartPolicyNever,
67 Containers: []v1.Container{
68 {
69 Image: busyboxImage,
70 Name: "container",
71 Command: []string{"sh", "-c", command},
72 VolumeMounts: []v1.VolumeMount{
73 {
74 Name: "sysfscgroup",
75 MountPath: "/host_cgroups",
76 },
77 },
78 },
79 },
80 Volumes: []v1.Volume{
81 {
82 Name: "sysfscgroup",
83 VolumeSource: v1.VolumeSource{
84 HostPath: &v1.HostPathVolumeSource{Path: "/sys/fs/cgroup"},
85 },
86 },
87 },
88 },
89 }
90 return pod
91 }
92
93 var _ = SIGDescribe("Kubelet PodOverhead handling [LinuxOnly]", func() {
94 f := framework.NewDefaultFramework("podoverhead-handling")
95 f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
96 ginkgo.Describe("PodOverhead cgroup accounting", func() {
97 ginkgo.Context("On running pod with PodOverhead defined", func() {
98 ginkgo.It("Pod cgroup should be sum of overhead and resource limits", func(ctx context.Context) {
99 if !kubeletCfg.CgroupsPerQOS {
100 return
101 }
102
103 var (
104 guaranteedPod *v1.Pod
105 podUID string
106 handler string
107 )
108 ginkgo.By("Creating a RuntimeClass with Overhead definied", func() {
109 handler = e2eruntimeclass.PreconfiguredRuntimeClassHandler
110 rc := &nodev1.RuntimeClass{
111 ObjectMeta: metav1.ObjectMeta{Name: handler},
112 Handler: handler,
113 Overhead: &nodev1.Overhead{
114 PodFixed: getResourceList("200m", "140Mi"),
115 },
116 }
117 _, err := f.ClientSet.NodeV1().RuntimeClasses().Create(ctx, rc, metav1.CreateOptions{})
118 framework.ExpectNoError(err, "failed to create RuntimeClass resource")
119 })
120 ginkgo.By("Creating a Guaranteed pod with which has Overhead defined", func() {
121 guaranteedPod = e2epod.NewPodClient(f).CreateSync(ctx, &v1.Pod{
122 ObjectMeta: metav1.ObjectMeta{
123 GenerateName: "pod-with-overhead-",
124 Namespace: f.Namespace.Name,
125 },
126 Spec: v1.PodSpec{
127 Containers: []v1.Container{
128 {
129 Image: imageutils.GetPauseImageName(),
130 Name: "container",
131 Resources: getResourceRequirements(getResourceList("100m", "100Mi"), getResourceList("100m", "100Mi")),
132 },
133 },
134 RuntimeClassName: &handler,
135 Overhead: getResourceList("200m", "140Mi"),
136 },
137 })
138 podUID = string(guaranteedPod.UID)
139 })
140 ginkgo.By("Checking if the pod cgroup was created appropriately", func() {
141 cgroupsToVerify := []string{"pod" + podUID}
142 pod := makePodToVerifyCgroupSize(cgroupsToVerify, "30000", "251658240")
143 pod = e2epod.NewPodClient(f).Create(ctx, pod)
144 err := e2epod.WaitForPodSuccessInNamespace(ctx, f.ClientSet, pod.Name, f.Namespace.Name)
145 framework.ExpectNoError(err)
146 })
147 })
148 })
149 })
150 })
151
View as plain text