diff --git a/test/kubernetes/testcluster/objects.go b/test/kubernetes/testcluster/objects.go index 384a5d5fed..bef7569fda 100644 --- a/test/kubernetes/testcluster/objects.go +++ b/test/kubernetes/testcluster/objects.go @@ -408,6 +408,13 @@ func (t RuntimeType) KataShimName() (string, error) { } } +// RequiresExplicitResourceLimits returns true if the runtime requires +// explicit resource limits on pods in order to function correctly. +func (t RuntimeType) RequiresExplicitResourceLimits() bool { + // Kata containers requires VMs which require explicit sizing. + return t.IsKata() +} + // ApplyNodepool modifies the nodepool to configure it to use the runtime. func (t RuntimeType) ApplyNodepool(nodepool *cspb.NodePool) { if nodepool.GetConfig().GetLabels() == nil { diff --git a/test/kubernetes/testcluster/testcluster.go b/test/kubernetes/testcluster/testcluster.go index 6c31690aef..3927380934 100644 --- a/test/kubernetes/testcluster/testcluster.go +++ b/test/kubernetes/testcluster/testcluster.go @@ -712,6 +712,46 @@ func (t *TestCluster) applyCommonPodConfigurations(ctx context.Context, np *Node } // Apply the runtime we've chosen, whether by override or autodetection. applyRuntime.ApplyPodSpec(podSpec) + if applyRuntime.RequiresExplicitResourceLimits() { + const ( + overheadMargin = 0.2 + leftoverRatio = 1.0 - overheadMargin + ) + cores := int(float64(np.spec.NumCores) * leftoverRatio) + if cores < 1 { + cores = 1 + } + memMiB := int(float64(np.spec.MemoryGiB) * 1024 * leftoverRatio) + resCPU := resource.MustParse(fmt.Sprintf("%d", cores)) + resMem := resource.MustParse(fmt.Sprintf("%dMi", memMiB)) + for _, containers := range [][]v13.Container{ + podSpec.InitContainers, + podSpec.Containers, + } { + for i := range containers { + if containers[i].Resources.Limits == nil { + containers[i].Resources.Limits = make(v13.ResourceList) + } + if containers[i].Resources.Requests == nil { + containers[i].Resources.Requests = make(v13.ResourceList) + } + for _, res := range []struct { + key v13.ResourceName + val resource.Quantity + }{ + {v13.ResourceCPU, resCPU}, + {v13.ResourceMemory, resMem}, + } { + if _, ok := containers[i].Resources.Requests[res.key]; !ok { + containers[i].Resources.Requests[res.key] = res.val + } + if _, ok := containers[i].Resources.Limits[res.key]; !ok { + containers[i].Resources.Limits[res.key] = res.val + } + } + } + } + } // If the nodepool has accelerators, copy the number of them as a node // selector option.