@@ -29,8 +29,11 @@ import (
29
29
v1 "k8s.io/api/core/v1"
30
30
"k8s.io/apimachinery/pkg/api/resource"
31
31
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
32
+ kubeletpodresourcesv1 "k8s.io/kubelet/pkg/apis/podresources/v1"
32
33
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
34
+ "k8s.io/kubernetes/pkg/kubelet/apis/podresources"
33
35
"k8s.io/kubernetes/pkg/kubelet/cm/cpumanager"
36
+ "k8s.io/kubernetes/pkg/kubelet/util"
34
37
"k8s.io/kubernetes/test/e2e/feature"
35
38
"k8s.io/kubernetes/test/e2e/framework"
36
39
e2emetrics "k8s.io/kubernetes/test/e2e/framework/metrics"
@@ -182,6 +185,95 @@ var _ = SIGDescribe("CPU Manager Metrics", framework.WithSerial(), feature.CPUMa
182
185
ginkgo .By ("Ensuring the metrics match the expectations about alignment metrics a few more times" )
183
186
gomega .Consistently (ctx , getKubeletMetrics , 1 * time .Minute , 15 * time .Second ).Should (matchAlignmentMetrics )
184
187
})
188
+
189
+ ginkgo .It ("should report the default idle cpu pool size" , func (ctx context.Context ) {
190
+ ginkgo .By ("Querying the podresources endpoint to get the baseline" )
191
+ endpoint , err := util .LocalEndpoint (defaultPodResourcesPath , podresources .Socket )
192
+ framework .ExpectNoError (err , "LocalEndpoint() failed err: %v" , err )
193
+
194
+ cli , conn , err := podresources .GetV1Client (endpoint , defaultPodResourcesTimeout , defaultPodResourcesMaxSize )
195
+ framework .ExpectNoError (err , "GetV1Client() failed err: %v" , err )
196
+ defer func () {
197
+ framework .ExpectNoError (conn .Close ())
198
+ }()
199
+
200
+ ginkgo .By ("Checking the pool allocatable resources from the kubelet" )
201
+ resp , err := cli .GetAllocatableResources (ctx , & kubeletpodresourcesv1.AllocatableResourcesRequest {})
202
+ framework .ExpectNoError (err , "failed to get the kubelet allocatable resources" )
203
+ allocatableCPUs , _ := demuxCPUsAndDevicesFromGetAllocatableResources (resp )
204
+
205
+ matchResourceMetrics := gstruct .MatchKeys (gstruct .IgnoreExtras , gstruct.Keys {
206
+ "kubelet_cpu_manager_shared_pool_size_millicores" : gstruct .MatchAllElements (nodeID , gstruct.Elements {
207
+ "" : timelessSample (int (allocatableCPUs .Size () * 1000 )),
208
+ }),
209
+ "kubelet_cpu_manager_exclusive_cpu_allocation_count" : gstruct .MatchAllElements (nodeID , gstruct.Elements {
210
+ "" : timelessSample (0 ),
211
+ }),
212
+ })
213
+
214
+ ginkgo .By ("Giving the Kubelet time to start up and produce metrics about idle pool size" )
215
+ gomega .Eventually (ctx , getKubeletMetrics , 1 * time .Minute , 10 * time .Second ).Should (matchResourceMetrics )
216
+ ginkgo .By ("Ensuring the metrics match the expectations about idle pool size a few more times" )
217
+ gomega .Consistently (ctx , getKubeletMetrics , 30 * time .Second , 10 * time .Second ).Should (matchResourceMetrics )
218
+ })
219
+
220
+ ginkgo .It ("should report mutating cpu pool size when handling guaranteed pods" , func (ctx context.Context ) {
221
+ ginkgo .By ("Querying the podresources endpoint to get the baseline" )
222
+ endpoint , err := util .LocalEndpoint (defaultPodResourcesPath , podresources .Socket )
223
+ framework .ExpectNoError (err , "LocalEndpoint() failed err: %v" , err )
224
+
225
+ cli , conn , err := podresources .GetV1Client (endpoint , defaultPodResourcesTimeout , defaultPodResourcesMaxSize )
226
+ framework .ExpectNoError (err , "GetV1Client() failed err: %v" , err )
227
+ defer func () {
228
+ framework .ExpectNoError (conn .Close ())
229
+ }()
230
+
231
+ ginkgo .By ("Checking the pool allocatable resources from the kubelet" )
232
+ resp , err := cli .GetAllocatableResources (ctx , & kubeletpodresourcesv1.AllocatableResourcesRequest {})
233
+ framework .ExpectNoError (err , "failed to get the kubelet allocatable resources" )
234
+ allocatableCPUs , _ := demuxCPUsAndDevicesFromGetAllocatableResources (resp )
235
+
236
+ allocatableCPUsIdleMillis := int (allocatableCPUs .Size () * 1000 )
237
+
238
+ matchResourceMetricsIdle := gstruct .MatchKeys (gstruct .IgnoreExtras , gstruct.Keys {
239
+ "kubelet_cpu_manager_shared_pool_size_millicores" : gstruct .MatchAllElements (nodeID , gstruct.Elements {
240
+ "" : timelessSample (allocatableCPUsIdleMillis ),
241
+ }),
242
+ "kubelet_cpu_manager_exclusive_cpu_allocation_count" : gstruct .MatchAllElements (nodeID , gstruct.Elements {
243
+ "" : timelessSample (0 ),
244
+ }),
245
+ })
246
+ ginkgo .By (fmt .Sprintf ("Pool allocatable resources from the kubelet: shared pool %d cpus %d millis" , allocatableCPUs .Size (), allocatableCPUsIdleMillis ))
247
+
248
+ ginkgo .By ("Giving the Kubelet time to start up and produce metrics about idle pool size" )
249
+ gomega .Eventually (ctx , getKubeletMetrics , 1 * time .Minute , 10 * time .Second ).Should (matchResourceMetricsIdle )
250
+ ginkgo .By ("Ensuring the metrics match the expectations about idle pool size a few more times" )
251
+ gomega .Consistently (ctx , getKubeletMetrics , 30 * time .Second , 10 * time .Second ).Should (matchResourceMetricsIdle )
252
+
253
+ ginkgo .By ("Creating the test pod to consume exclusive cpus from the pool" )
254
+ testPod = e2epod .NewPodClient (f ).CreateSync (ctx , makeGuaranteedCPUExclusiveSleeperPod ("smt-cpupool" , smtLevel ))
255
+
256
+ matchResourceMetricsBusy := gstruct .MatchKeys (gstruct .IgnoreExtras , gstruct.Keys {
257
+ "kubelet_cpu_manager_shared_pool_size_millicores" : gstruct .MatchAllElements (nodeID , gstruct.Elements {
258
+ "" : timelessSample (allocatableCPUsIdleMillis - (smtLevel * 1000 )),
259
+ }),
260
+ "kubelet_cpu_manager_exclusive_cpu_allocation_count" : gstruct .MatchAllElements (nodeID , gstruct.Elements {
261
+ "" : timelessSample (smtLevel ),
262
+ }),
263
+ })
264
+
265
+ ginkgo .By ("Giving the Kubelet time to start up and produce metrics" )
266
+ gomega .Eventually (ctx , getKubeletMetrics , 1 * time .Minute , 10 * time .Second ).Should (matchResourceMetricsBusy )
267
+ ginkgo .By ("Ensuring the metrics match the expectations a few more times" )
268
+ gomega .Consistently (ctx , getKubeletMetrics , 30 * time .Second , 10 * time .Second ).Should (matchResourceMetricsBusy )
269
+
270
+ deletePodSyncByName (ctx , f , testPod .Name )
271
+
272
+ ginkgo .By ("Giving the Kubelet time to start up and produce metrics" )
273
+ gomega .Eventually (ctx , getKubeletMetrics , 1 * time .Minute , 10 * time .Second ).Should (matchResourceMetricsIdle )
274
+ ginkgo .By ("Ensuring the metrics match the expectations a few more times" )
275
+ gomega .Consistently (ctx , getKubeletMetrics , 30 * time .Second , 10 * time .Second ).Should (matchResourceMetricsIdle )
276
+ })
185
277
})
186
278
})
187
279
0 commit comments