mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 06:27:05 +00:00
helpers: refactor and expose function for sum of container req/limits
Currently we only care about the sum of sandbox resources, which includes a pod overhead if defined. We have a need for also calculating *just* the sum of container requests/limits for CPU / Memory, so let's do a refactor and expose this new helper function. Signed-off-by: Eric Ernst <eric_ernst@apple.com>
This commit is contained in:
parent
91be6f7926
commit
ac88cd7691
@ -36,15 +36,17 @@ func PodRequestsAndLimits(pod *v1.Pod) (reqs, limits v1.ResourceList) {
|
||||
return PodRequestsAndLimitsReuse(pod, nil, nil)
|
||||
}
|
||||
|
||||
// PodRequestsAndLimitsReuse returns a dictionary of all defined resources summed up for all
|
||||
// containers of the pod. If PodOverhead feature is enabled, pod overhead is added to the
|
||||
// total container resource requests and to the total container limits which have a
|
||||
// non-zero quantity. The caller may avoid allocations of resource lists by passing
|
||||
// a requests and limits list to the function, which will be cleared before use.
|
||||
func PodRequestsAndLimitsReuse(pod *v1.Pod, reuseReqs, reuseLimits v1.ResourceList) (reqs, limits v1.ResourceList) {
|
||||
// attempt to reuse the maps if passed, or allocate otherwise
|
||||
reqs, limits = reuseOrClearResourceList(reuseReqs), reuseOrClearResourceList(reuseLimits)
|
||||
// PodRequestsAndLimitsWithoutOverhead will create a dictionary of all defined resources summed up for all
|
||||
// containers of the pod.
|
||||
func PodRequestsAndLimitsWithoutOverhead(pod *v1.Pod) (reqs, limits v1.ResourceList) {
|
||||
reqs = make(v1.ResourceList, 4)
|
||||
limits = make(v1.ResourceList, 4)
|
||||
podRequestsAndLimitsWithoutOverhead(pod, reqs, limits)
|
||||
|
||||
return reqs, limits
|
||||
}
|
||||
|
||||
func podRequestsAndLimitsWithoutOverhead(pod *v1.Pod, reqs, limits v1.ResourceList) {
|
||||
for _, container := range pod.Spec.Containers {
|
||||
addResourceList(reqs, container.Resources.Requests)
|
||||
addResourceList(limits, container.Resources.Limits)
|
||||
@ -54,6 +56,18 @@ func PodRequestsAndLimitsReuse(pod *v1.Pod, reuseReqs, reuseLimits v1.ResourceLi
|
||||
maxResourceList(reqs, container.Resources.Requests)
|
||||
maxResourceList(limits, container.Resources.Limits)
|
||||
}
|
||||
}
|
||||
|
||||
// PodRequestsAndLimitsReuse returns a dictionary of all defined resources summed up for all
|
||||
// containers of the pod. If PodOverhead feature is enabled, pod overhead is added to the
|
||||
// total container resource requests and to the total container limits which have a
|
||||
// non-zero quantity. The caller may avoid allocations of resource lists by passing
|
||||
// a requests and limits list to the function, which will be cleared before use.
|
||||
func PodRequestsAndLimitsReuse(pod *v1.Pod, reuseReqs, reuseLimits v1.ResourceList) (reqs, limits v1.ResourceList) {
|
||||
// attempt to reuse the maps if passed, or allocate otherwise
|
||||
reqs, limits = reuseOrClearResourceList(reuseReqs), reuseOrClearResourceList(reuseLimits)
|
||||
|
||||
podRequestsAndLimitsWithoutOverhead(pod, reqs, limits)
|
||||
|
||||
// if PodOverhead feature is supported, add overhead for running a pod
|
||||
// to the sum of requests and to non-zero limits:
|
||||
|
@ -21,7 +21,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
)
|
||||
@ -337,6 +337,192 @@ func TestPodRequestsAndLimits(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPodRequestsAndLimitsWithoutOverhead(t *testing.T) {
|
||||
cases := []struct {
|
||||
pod *v1.Pod
|
||||
name string
|
||||
expectedRequests v1.ResourceList
|
||||
expectedLimits v1.ResourceList
|
||||
}{
|
||||
{
|
||||
name: "two container no overhead - should just be sum of containers",
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "foobar",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("1"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("5"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("2"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("10"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "foobar2",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("4"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("12"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("8"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("24"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedRequests: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("5"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("17"),
|
||||
},
|
||||
expectedLimits: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("34"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "two container with overhead - shouldn't consider overhead",
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
Overhead: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("3"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("8"),
|
||||
},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "foobar",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("1"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("5"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("2"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("10"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "foobar2",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("4"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("12"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("8"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("24"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedRequests: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("5"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("17"),
|
||||
},
|
||||
expectedLimits: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("10"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("34"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "two container with overhead, massive init - should just be the largest init",
|
||||
pod: &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
Overhead: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("3"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("8"),
|
||||
},
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: "foobar",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("1"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("5"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("2"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("10"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "foobar2",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("4"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("12"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("8"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("24"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
InitContainers: []v1.Container{
|
||||
{
|
||||
Name: "small-init",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("1"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("5"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("1"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("5"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "big-init",
|
||||
Resources: v1.ResourceRequirements{
|
||||
Requests: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("40"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("120"),
|
||||
},
|
||||
Limits: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("80"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("240"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedRequests: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("40"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("120"),
|
||||
},
|
||||
expectedLimits: v1.ResourceList{
|
||||
v1.ResourceName(v1.ResourceCPU): resource.MustParse("80"),
|
||||
v1.ResourceName(v1.ResourceMemory): resource.MustParse("240"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for idx, tc := range cases {
|
||||
resRequests, resLimits := PodRequestsAndLimitsWithoutOverhead(tc.pod)
|
||||
|
||||
if !equality.Semantic.DeepEqual(tc.expectedRequests, resRequests) {
|
||||
t.Errorf("test case failure[%d]: %v, requests:\n expected:\t%v\ngot\t\t%v", idx, tc.name, tc.expectedRequests, resRequests)
|
||||
}
|
||||
|
||||
if !equality.Semantic.DeepEqual(tc.expectedLimits, resLimits) {
|
||||
t.Errorf("test case failure[%d]: %v, limits:\n expected:\t%v\ngot\t\t%v", idx, tc.name, tc.expectedLimits, resLimits)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type podResources struct {
|
||||
cpuRequest, cpuLimit, memoryRequest, memoryLimit, cpuOverhead, memoryOverhead string
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user