mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 12:43:23 +00:00
kuberuntime: refactor linux resources for better reuse
Seperate the CPU/Memory req/limit -> linux resource conversion into its own function for better reuse. Elsewhere in kuberuntime pkg, we will want to leverage this requests/limits to Linux Resource type conversion. Signed-off-by: Eric Ernst <eric_ernst@apple.com>
This commit is contained in:
parent
ac88cd7691
commit
ddcf815d12
@ -26,6 +26,7 @@ import (
|
||||
libcontainercgroups "github.com/opencontainers/runc/libcontainer/cgroups"
|
||||
cgroupfs "github.com/opencontainers/runc/libcontainer/cgroups/fs"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
||||
"k8s.io/klog/v2"
|
||||
@ -62,42 +63,10 @@ func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *v1.C
|
||||
}
|
||||
|
||||
// set linux container resources
|
||||
var cpuShares int64
|
||||
cpuRequest := container.Resources.Requests.Cpu()
|
||||
cpuLimit := container.Resources.Limits.Cpu()
|
||||
memoryLimit := container.Resources.Limits.Memory().Value()
|
||||
memoryRequest := container.Resources.Requests.Memory().Value()
|
||||
oomScoreAdj := int64(qos.GetContainerOOMScoreAdjust(pod, container,
|
||||
int64(m.machineInfo.MemoryCapacity)))
|
||||
// If request is not specified, but limit is, we want request to default to limit.
|
||||
// API server does this for new containers, but we repeat this logic in Kubelet
|
||||
// for containers running on existing Kubernetes clusters.
|
||||
if cpuRequest.IsZero() && !cpuLimit.IsZero() {
|
||||
cpuShares = milliCPUToShares(cpuLimit.MilliValue())
|
||||
} else {
|
||||
// if cpuRequest.Amount is nil, then milliCPUToShares will return the minimal number
|
||||
// of CPU shares.
|
||||
cpuShares = milliCPUToShares(cpuRequest.MilliValue())
|
||||
}
|
||||
lc.Resources.CpuShares = cpuShares
|
||||
if memoryLimit != 0 {
|
||||
lc.Resources.MemoryLimitInBytes = memoryLimit
|
||||
}
|
||||
// Set OOM score of the container based on qos policy. Processes in lower-priority pods should
|
||||
// be killed first if the system runs out of memory.
|
||||
lc.Resources.OomScoreAdj = oomScoreAdj
|
||||
lc.Resources = m.calculateLinuxResources(container.Resources.Requests.Cpu(), container.Resources.Limits.Cpu(), container.Resources.Limits.Memory())
|
||||
|
||||
if m.cpuCFSQuota {
|
||||
// if cpuLimit.Amount is nil, then the appropriate default value is returned
|
||||
// to allow full usage of cpu resource.
|
||||
cpuPeriod := int64(quotaPeriod)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUCFSQuotaPeriod) {
|
||||
cpuPeriod = int64(m.cpuCFSQuotaPeriod.Duration / time.Microsecond)
|
||||
}
|
||||
cpuQuota := milliCPUToQuota(cpuLimit.MilliValue(), cpuPeriod)
|
||||
lc.Resources.CpuQuota = cpuQuota
|
||||
lc.Resources.CpuPeriod = cpuPeriod
|
||||
}
|
||||
lc.Resources.OomScoreAdj = int64(qos.GetContainerOOMScoreAdjust(pod, container,
|
||||
int64(m.machineInfo.MemoryCapacity)))
|
||||
|
||||
lc.Resources.HugepageLimits = GetHugepageLimitsFromResources(container.Resources)
|
||||
|
||||
@ -121,7 +90,8 @@ func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *v1.C
|
||||
// Set memory.min and memory.high to enforce MemoryQoS
|
||||
if enforceMemoryQoS {
|
||||
unified := map[string]string{}
|
||||
|
||||
memoryRequest := container.Resources.Requests.Memory().Value()
|
||||
memoryLimit := container.Resources.Limits.Memory().Value()
|
||||
if memoryRequest != 0 {
|
||||
unified[cm.MemoryMin] = strconv.FormatInt(memoryRequest, 10)
|
||||
}
|
||||
@ -158,6 +128,43 @@ func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *v1.C
|
||||
return lc
|
||||
}
|
||||
|
||||
// calculateLinuxResources will create the linuxContainerResources type based on the provided CPU and memory resource requests, limits
|
||||
func (m *kubeGenericRuntimeManager) calculateLinuxResources(cpuRequest, cpuLimit, memoryLimit *resource.Quantity) *runtimeapi.LinuxContainerResources {
|
||||
resources := runtimeapi.LinuxContainerResources{}
|
||||
var cpuShares int64
|
||||
|
||||
memLimit := memoryLimit.Value()
|
||||
|
||||
// If request is not specified, but limit is, we want request to default to limit.
|
||||
// API server does this for new containers, but we repeat this logic in Kubelet
|
||||
// for containers running on existing Kubernetes clusters.
|
||||
if cpuRequest.IsZero() && !cpuLimit.IsZero() {
|
||||
cpuShares = milliCPUToShares(cpuLimit.MilliValue())
|
||||
} else {
|
||||
// if cpuRequest.Amount is nil, then milliCPUToShares will return the minimal number
|
||||
// of CPU shares.
|
||||
cpuShares = milliCPUToShares(cpuRequest.MilliValue())
|
||||
}
|
||||
resources.CpuShares = cpuShares
|
||||
if memLimit != 0 {
|
||||
resources.MemoryLimitInBytes = memLimit
|
||||
}
|
||||
|
||||
if m.cpuCFSQuota {
|
||||
// if cpuLimit.Amount is nil, then the appropriate default value is returned
|
||||
// to allow full usage of cpu resource.
|
||||
cpuPeriod := int64(quotaPeriod)
|
||||
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUCFSQuotaPeriod) {
|
||||
cpuPeriod = int64(m.cpuCFSQuotaPeriod.Duration / time.Microsecond)
|
||||
}
|
||||
cpuQuota := milliCPUToQuota(cpuLimit.MilliValue(), cpuPeriod)
|
||||
resources.CpuQuota = cpuQuota
|
||||
resources.CpuPeriod = cpuPeriod
|
||||
}
|
||||
|
||||
return &resources
|
||||
}
|
||||
|
||||
// GetHugepageLimitsFromResources returns limits of each hugepages from resources.
|
||||
func GetHugepageLimitsFromResources(resources v1.ResourceRequirements) []*runtimeapi.HugepageLimit {
|
||||
var hugepageLimits []*runtimeapi.HugepageLimit
|
||||
|
@ -223,6 +223,50 @@ func TestGenerateLinuxContainerConfigResources(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateLinuxResources(t *testing.T) {
|
||||
_, _, m, err := createTestRuntimeManager()
|
||||
m.cpuCFSQuota = true
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
cpuReq resource.Quantity
|
||||
cpuLim resource.Quantity
|
||||
memLim resource.Quantity
|
||||
expected *runtimeapi.LinuxContainerResources
|
||||
}{
|
||||
{
|
||||
name: "Request128MBLimit256MB",
|
||||
cpuReq: resource.MustParse("1"),
|
||||
cpuLim: resource.MustParse("2"),
|
||||
memLim: resource.MustParse("128Mi"),
|
||||
expected: &runtimeapi.LinuxContainerResources{
|
||||
CpuPeriod: 100000,
|
||||
CpuQuota: 200000,
|
||||
CpuShares: 1024,
|
||||
MemoryLimitInBytes: 134217728,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "RequestNoMemory",
|
||||
cpuReq: resource.MustParse("2"),
|
||||
cpuLim: resource.MustParse("8"),
|
||||
memLim: resource.MustParse("0"),
|
||||
expected: &runtimeapi.LinuxContainerResources{
|
||||
CpuPeriod: 100000,
|
||||
CpuQuota: 800000,
|
||||
CpuShares: 2048,
|
||||
MemoryLimitInBytes: 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
linuxContainerResources := m.calculateLinuxResources(&test.cpuReq, &test.cpuLim, &test.memLim)
|
||||
assert.Equal(t, test.expected, linuxContainerResources)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateContainerConfigWithMemoryQoSEnforced(t *testing.T) {
|
||||
_, _, m, err := createTestRuntimeManager()
|
||||
assert.NoError(t, err)
|
||||
|
Loading…
Reference in New Issue
Block a user