mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
memory manager: update all relevant part of code to use []MemoryReservation
Signed-off-by: Artyom Lukianov <alukiano@redhat.com>
This commit is contained in:
parent
7561a0f96e
commit
e8ea461bfd
@ -126,7 +126,7 @@ const (
|
|||||||
// owner: @cynepco3hahue(alukiano) @cezaryzukowski @k-wiatrzyk
|
// owner: @cynepco3hahue(alukiano) @cezaryzukowski @k-wiatrzyk
|
||||||
// alpha:: v1.20
|
// alpha:: v1.20
|
||||||
|
|
||||||
// Allows to set containers memory affinity according to NUMA topology
|
// Allows setting memory affinity for a container based on NUMA topology
|
||||||
MemoryManager featuregate.Feature = "MemoryManager"
|
MemoryManager featuregate.Feature = "MemoryManager"
|
||||||
|
|
||||||
// owner: @sjenning
|
// owner: @sjenning
|
||||||
|
@ -14,13 +14,13 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//pkg/apis/core/v1/helper:go_default_library",
|
"//pkg/apis/core/v1/helper:go_default_library",
|
||||||
"//pkg/apis/core/v1/helper/qos:go_default_library",
|
"//pkg/apis/core/v1/helper/qos:go_default_library",
|
||||||
|
"//pkg/kubelet/apis/config:go_default_library",
|
||||||
"//pkg/kubelet/cm/containermap:go_default_library",
|
"//pkg/kubelet/cm/containermap:go_default_library",
|
||||||
"//pkg/kubelet/cm/memorymanager/state:go_default_library",
|
"//pkg/kubelet/cm/memorymanager/state:go_default_library",
|
||||||
"//pkg/kubelet/cm/topologymanager:go_default_library",
|
"//pkg/kubelet/cm/topologymanager:go_default_library",
|
||||||
"//pkg/kubelet/cm/topologymanager/bitmask:go_default_library",
|
"//pkg/kubelet/cm/topologymanager/bitmask:go_default_library",
|
||||||
"//pkg/kubelet/config:go_default_library",
|
"//pkg/kubelet/config:go_default_library",
|
||||||
"//pkg/kubelet/status:go_default_library",
|
"//pkg/kubelet/status:go_default_library",
|
||||||
"//pkg/kubelet/types:go_default_library",
|
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||||
"//staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2:go_default_library",
|
"//staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2:go_default_library",
|
||||||
@ -37,12 +37,12 @@ go_test(
|
|||||||
],
|
],
|
||||||
embed = [":go_default_library"],
|
embed = [":go_default_library"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//pkg/kubelet/apis/config:go_default_library",
|
||||||
"//pkg/kubelet/cm/containermap:go_default_library",
|
"//pkg/kubelet/cm/containermap:go_default_library",
|
||||||
"//pkg/kubelet/cm/memorymanager/state:go_default_library",
|
"//pkg/kubelet/cm/memorymanager/state:go_default_library",
|
||||||
"//pkg/kubelet/cm/topologymanager:go_default_library",
|
"//pkg/kubelet/cm/topologymanager:go_default_library",
|
||||||
"//pkg/kubelet/cm/topologymanager/bitmask:go_default_library",
|
"//pkg/kubelet/cm/topologymanager/bitmask:go_default_library",
|
||||||
"//pkg/kubelet/lifecycle:go_default_library",
|
"//pkg/kubelet/lifecycle:go_default_library",
|
||||||
"//pkg/kubelet/types:go_default_library",
|
|
||||||
"//pkg/kubelet/util/format:go_default_library",
|
"//pkg/kubelet/util/format:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||||
|
@ -29,12 +29,12 @@ import (
|
|||||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
corev1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
corev1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper"
|
||||||
|
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/cm/containermap"
|
"k8s.io/kubernetes/pkg/kubelet/cm/containermap"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state"
|
"k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
|
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/config"
|
"k8s.io/kubernetes/pkg/kubelet/config"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/status"
|
"k8s.io/kubernetes/pkg/kubelet/status"
|
||||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// memoryManagerStateFileName is the file name where memory manager stores its state
|
// memoryManagerStateFileName is the file name where memory manager stores its state
|
||||||
@ -67,7 +67,7 @@ type Manager interface {
|
|||||||
Allocate(pod *v1.Pod, container *v1.Container) error
|
Allocate(pod *v1.Pod, container *v1.Container) error
|
||||||
|
|
||||||
// RemoveContainer is called after Kubelet decides to kill or delete a
|
// RemoveContainer is called after Kubelet decides to kill or delete a
|
||||||
// container. After this call, any memory allocated to the container are freed.
|
// container. After this call, any memory allocated to the container is freed.
|
||||||
RemoveContainer(containerID string) error
|
RemoveContainer(containerID string) error
|
||||||
|
|
||||||
// State returns a read-only interface to the internal memory manager state.
|
// State returns a read-only interface to the internal memory manager state.
|
||||||
@ -119,7 +119,7 @@ type manager struct {
|
|||||||
var _ Manager = &manager{}
|
var _ Manager = &manager{}
|
||||||
|
|
||||||
// NewManager returns new instance of the memory manager
|
// NewManager returns new instance of the memory manager
|
||||||
func NewManager(policyName string, machineInfo *cadvisorapi.MachineInfo, nodeAllocatableReservation v1.ResourceList, reservedMemory kubetypes.NUMANodeResources, stateFileDirectory string, affinity topologymanager.Store) (Manager, error) {
|
func NewManager(policyName string, machineInfo *cadvisorapi.MachineInfo, nodeAllocatableReservation v1.ResourceList, reservedMemory []kubeletconfig.MemoryReservation, stateFileDirectory string, affinity topologymanager.Store) (Manager, error) {
|
||||||
var policy Policy
|
var policy Policy
|
||||||
|
|
||||||
switch policyType(policyName) {
|
switch policyType(policyName) {
|
||||||
@ -321,7 +321,7 @@ func (m *manager) policyRemoveContainerByRef(podUID string, containerName string
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTotalMemoryTypeReserved(machineInfo *cadvisorapi.MachineInfo, reservedMemory kubetypes.NUMANodeResources) map[v1.ResourceName]resource.Quantity {
|
func getTotalMemoryTypeReserved(machineInfo *cadvisorapi.MachineInfo, reservedMemory []kubeletconfig.MemoryReservation) map[v1.ResourceName]resource.Quantity {
|
||||||
totalMemoryType := map[v1.ResourceName]resource.Quantity{}
|
totalMemoryType := map[v1.ResourceName]resource.Quantity{}
|
||||||
|
|
||||||
numaNodes := map[int]bool{}
|
numaNodes := map[int]bool{}
|
||||||
@ -329,24 +329,24 @@ func getTotalMemoryTypeReserved(machineInfo *cadvisorapi.MachineInfo, reservedMe
|
|||||||
numaNodes[numaNode.Id] = true
|
numaNodes[numaNode.Id] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
for nodeID, node := range reservedMemory {
|
for _, reservation := range reservedMemory {
|
||||||
if !numaNodes[nodeID] {
|
if !numaNodes[int(reservation.NumaNode)] {
|
||||||
klog.Warningf("The NUMA node %d specified under --reserved- memory does not exist on the machine", nodeID)
|
klog.Warningf("The NUMA node %d specified under --reserved-memory does not exist on the machine", reservation.NumaNode)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for memType, memVal := range node {
|
for resourceName, q := range reservation.Limits {
|
||||||
if totalMem, exists := totalMemoryType[memType]; exists {
|
if value, ok := totalMemoryType[resourceName]; ok {
|
||||||
memVal.Add(totalMem)
|
q.Add(value)
|
||||||
}
|
}
|
||||||
totalMemoryType[memType] = memVal
|
totalMemoryType[resourceName] = q
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return totalMemoryType
|
return totalMemoryType
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateReservedMemory(machineInfo *cadvisorapi.MachineInfo, nodeAllocatableReservation v1.ResourceList, reservedMemory kubetypes.NUMANodeResources) error {
|
func validateReservedMemory(machineInfo *cadvisorapi.MachineInfo, nodeAllocatableReservation v1.ResourceList, reservedMemory []kubeletconfig.MemoryReservation) error {
|
||||||
totalMemoryType := getTotalMemoryTypeReserved(machineInfo, reservedMemory)
|
totalMemoryType := getTotalMemoryTypeReserved(machineInfo, reservedMemory)
|
||||||
|
|
||||||
commonMemoryTypeSet := make(map[v1.ResourceName]bool)
|
commonMemoryTypeSet := make(map[v1.ResourceName]bool)
|
||||||
@ -382,32 +382,31 @@ func validateReservedMemory(machineInfo *cadvisorapi.MachineInfo, nodeAllocatabl
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertReserved(machineInfo *cadvisorapi.MachineInfo, reservedMemory kubetypes.NUMANodeResources) (systemReservedMemory, error) {
|
func convertReserved(machineInfo *cadvisorapi.MachineInfo, reservedMemory []kubeletconfig.MemoryReservation) (systemReservedMemory, error) {
|
||||||
preReservedMemoryConverted := make(map[int]map[v1.ResourceName]uint64)
|
reservedMemoryConverted := make(map[int]map[v1.ResourceName]uint64)
|
||||||
for _, node := range machineInfo.Topology {
|
for _, node := range machineInfo.Topology {
|
||||||
preReservedMemoryConverted[node.Id] = make(map[v1.ResourceName]uint64)
|
reservedMemoryConverted[node.Id] = make(map[v1.ResourceName]uint64)
|
||||||
}
|
}
|
||||||
|
|
||||||
for numaIndex := range reservedMemory {
|
for _, reservation := range reservedMemory {
|
||||||
for memoryType := range reservedMemory[numaIndex] {
|
for resourceName, q := range reservation.Limits {
|
||||||
tmp := reservedMemory[numaIndex][memoryType]
|
val, success := q.AsInt64()
|
||||||
if val, success := tmp.AsInt64(); success {
|
if !success {
|
||||||
preReservedMemoryConverted[numaIndex][memoryType] = uint64(val)
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("could not covert a variable of type Quantity to int64")
|
return nil, fmt.Errorf("could not covert a variable of type Quantity to int64")
|
||||||
}
|
}
|
||||||
|
reservedMemoryConverted[int(reservation.NumaNode)][resourceName] = uint64(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return preReservedMemoryConverted, nil
|
return reservedMemoryConverted, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSystemReservedMemory(machineInfo *cadvisorapi.MachineInfo, nodeAllocatableReservation v1.ResourceList, preReservedMemory kubetypes.NUMANodeResources) (systemReservedMemory, error) {
|
func getSystemReservedMemory(machineInfo *cadvisorapi.MachineInfo, nodeAllocatableReservation v1.ResourceList, reservedMemory []kubeletconfig.MemoryReservation) (systemReservedMemory, error) {
|
||||||
if err := validateReservedMemory(machineInfo, nodeAllocatableReservation, preReservedMemory); err != nil {
|
if err := validateReservedMemory(machineInfo, nodeAllocatableReservation, reservedMemory); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
reservedMemoryConverted, err := convertReserved(machineInfo, preReservedMemory)
|
reservedMemoryConverted, err := convertReserved(machineInfo, reservedMemory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
||||||
|
|
||||||
cadvisorapi "github.com/google/cadvisor/info/v1"
|
cadvisorapi "github.com/google/cadvisor/info/v1"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
@ -34,7 +36,6 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubelet/cm/containermap"
|
"k8s.io/kubernetes/pkg/kubelet/cm/containermap"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state"
|
"k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
|
"k8s.io/kubernetes/pkg/kubelet/cm/topologymanager"
|
||||||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -59,7 +60,7 @@ type testMemoryManager struct {
|
|||||||
nodeAllocatableReservation v1.ResourceList
|
nodeAllocatableReservation v1.ResourceList
|
||||||
policyName policyType
|
policyName policyType
|
||||||
affinity topologymanager.Store
|
affinity topologymanager.Store
|
||||||
systemReservedMemory kubetypes.NUMANodeResources
|
systemReservedMemory []kubeletconfig.MemoryReservation
|
||||||
expectedHints map[string][]topologymanager.TopologyHint
|
expectedHints map[string][]topologymanager.TopologyHint
|
||||||
expectedReserved systemReservedMemory
|
expectedReserved systemReservedMemory
|
||||||
reserved systemReservedMemory
|
reserved systemReservedMemory
|
||||||
@ -69,7 +70,7 @@ type testMemoryManager struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func returnPolicyByName(testCase testMemoryManager) Policy {
|
func returnPolicyByName(testCase testMemoryManager) Policy {
|
||||||
switch policyType(testCase.policyName) {
|
switch testCase.policyName {
|
||||||
case policyTypeMock:
|
case policyTypeMock:
|
||||||
return &mockPolicy{
|
return &mockPolicy{
|
||||||
err: fmt.Errorf("fake reg error"),
|
err: fmt.Errorf("fake reg error"),
|
||||||
@ -83,8 +84,6 @@ func returnPolicyByName(testCase testMemoryManager) Policy {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type nodeResources map[v1.ResourceName]resource.Quantity
|
|
||||||
|
|
||||||
type mockPolicy struct {
|
type mockPolicy struct {
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
@ -158,22 +157,27 @@ func TestValidateReservedMemory(t *testing.T) {
|
|||||||
description string
|
description string
|
||||||
nodeAllocatableReservation v1.ResourceList
|
nodeAllocatableReservation v1.ResourceList
|
||||||
machineInfo *cadvisorapi.MachineInfo
|
machineInfo *cadvisorapi.MachineInfo
|
||||||
systemReservedMemory kubetypes.NUMANodeResources
|
systemReservedMemory []kubeletconfig.MemoryReservation
|
||||||
expectedError string
|
expectedError string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"Node Allocatable not set, reserved not set",
|
"Node Allocatable not set, reserved not set",
|
||||||
v1.ResourceList{},
|
v1.ResourceList{},
|
||||||
machineInfo,
|
machineInfo,
|
||||||
kubetypes.NUMANodeResources{},
|
[]kubeletconfig.MemoryReservation{},
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Node Allocatable set to zero, reserved set to zero",
|
"Node Allocatable set to zero, reserved set to zero",
|
||||||
v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(0, resource.DecimalSI)},
|
v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(0, resource.DecimalSI)},
|
||||||
machineInfo,
|
machineInfo,
|
||||||
kubetypes.NUMANodeResources{
|
[]kubeletconfig.MemoryReservation{
|
||||||
0: nodeResources{v1.ResourceMemory: *resource.NewQuantity(0, resource.DecimalSI)},
|
{
|
||||||
|
NumaNode: 0,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(0, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
@ -181,8 +185,13 @@ func TestValidateReservedMemory(t *testing.T) {
|
|||||||
"Node Allocatable not set (equal zero), reserved set",
|
"Node Allocatable not set (equal zero), reserved set",
|
||||||
v1.ResourceList{},
|
v1.ResourceList{},
|
||||||
machineInfo,
|
machineInfo,
|
||||||
kubetypes.NUMANodeResources{
|
[]kubeletconfig.MemoryReservation{
|
||||||
0: nodeResources{v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI)},
|
{
|
||||||
|
NumaNode: 0,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fmt.Sprintf(msgNotEqual, v1.ResourceMemory),
|
fmt.Sprintf(msgNotEqual, v1.ResourceMemory),
|
||||||
},
|
},
|
||||||
@ -190,15 +199,20 @@ func TestValidateReservedMemory(t *testing.T) {
|
|||||||
"Node Allocatable set, reserved not set",
|
"Node Allocatable set, reserved not set",
|
||||||
v1.ResourceList{hugepages2M: *resource.NewQuantity(5, resource.DecimalSI)},
|
v1.ResourceList{hugepages2M: *resource.NewQuantity(5, resource.DecimalSI)},
|
||||||
machineInfo,
|
machineInfo,
|
||||||
kubetypes.NUMANodeResources{},
|
[]kubeletconfig.MemoryReservation{},
|
||||||
fmt.Sprintf(msgNotEqual, hugepages2M),
|
fmt.Sprintf(msgNotEqual, hugepages2M),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Reserved not equal to Node Allocatable",
|
"Reserved not equal to Node Allocatable",
|
||||||
v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(5, resource.DecimalSI)},
|
v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(5, resource.DecimalSI)},
|
||||||
machineInfo,
|
machineInfo,
|
||||||
kubetypes.NUMANodeResources{
|
[]kubeletconfig.MemoryReservation{
|
||||||
0: nodeResources{v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI)},
|
{
|
||||||
|
NumaNode: 0,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fmt.Sprintf(msgNotEqual, v1.ResourceMemory),
|
fmt.Sprintf(msgNotEqual, v1.ResourceMemory),
|
||||||
},
|
},
|
||||||
@ -206,9 +220,19 @@ func TestValidateReservedMemory(t *testing.T) {
|
|||||||
"Reserved contains the NUMA node that does not exist under the machine",
|
"Reserved contains the NUMA node that does not exist under the machine",
|
||||||
v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(17, resource.DecimalSI)},
|
v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(17, resource.DecimalSI)},
|
||||||
machineInfo,
|
machineInfo,
|
||||||
kubetypes.NUMANodeResources{
|
[]kubeletconfig.MemoryReservation{
|
||||||
0: nodeResources{v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI)},
|
{
|
||||||
2: nodeResources{v1.ResourceMemory: *resource.NewQuantity(5, resource.DecimalSI)},
|
NumaNode: 0,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
NumaNode: 2,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(5, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
fmt.Sprintf(msgNotEqual, v1.ResourceMemory),
|
fmt.Sprintf(msgNotEqual, v1.ResourceMemory),
|
||||||
},
|
},
|
||||||
@ -218,12 +242,22 @@ func TestValidateReservedMemory(t *testing.T) {
|
|||||||
hugepages2M: *resource.NewQuantity(77, resource.DecimalSI),
|
hugepages2M: *resource.NewQuantity(77, resource.DecimalSI),
|
||||||
hugepages1G: *resource.NewQuantity(13, resource.DecimalSI)},
|
hugepages1G: *resource.NewQuantity(13, resource.DecimalSI)},
|
||||||
machineInfo,
|
machineInfo,
|
||||||
kubetypes.NUMANodeResources{
|
[]kubeletconfig.MemoryReservation{
|
||||||
0: nodeResources{v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI),
|
{
|
||||||
hugepages2M: *resource.NewQuantity(70, resource.DecimalSI),
|
NumaNode: 0,
|
||||||
hugepages1G: *resource.NewQuantity(13, resource.DecimalSI)},
|
Limits: v1.ResourceList{
|
||||||
1: nodeResources{v1.ResourceMemory: *resource.NewQuantity(5, resource.DecimalSI),
|
v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI),
|
||||||
hugepages2M: *resource.NewQuantity(7, resource.DecimalSI)},
|
hugepages2M: *resource.NewQuantity(70, resource.DecimalSI),
|
||||||
|
hugepages1G: *resource.NewQuantity(13, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
NumaNode: 1,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(5, resource.DecimalSI),
|
||||||
|
hugepages2M: *resource.NewQuantity(7, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"",
|
"",
|
||||||
},
|
},
|
||||||
@ -233,12 +267,22 @@ func TestValidateReservedMemory(t *testing.T) {
|
|||||||
hugepages2M: *resource.NewQuantity(14, resource.DecimalSI),
|
hugepages2M: *resource.NewQuantity(14, resource.DecimalSI),
|
||||||
hugepages1G: *resource.NewQuantity(13, resource.DecimalSI)},
|
hugepages1G: *resource.NewQuantity(13, resource.DecimalSI)},
|
||||||
machineInfo,
|
machineInfo,
|
||||||
kubetypes.NUMANodeResources{
|
[]kubeletconfig.MemoryReservation{
|
||||||
0: nodeResources{v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI),
|
{
|
||||||
hugepages2M: *resource.NewQuantity(70, resource.DecimalSI),
|
NumaNode: 0,
|
||||||
hugepages1G: *resource.NewQuantity(13, resource.DecimalSI)},
|
Limits: v1.ResourceList{
|
||||||
1: nodeResources{v1.ResourceMemory: *resource.NewQuantity(5, resource.DecimalSI),
|
v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI),
|
||||||
hugepages2M: *resource.NewQuantity(7, resource.DecimalSI)},
|
hugepages2M: *resource.NewQuantity(70, resource.DecimalSI),
|
||||||
|
hugepages1G: *resource.NewQuantity(13, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
NumaNode: 1,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(5, resource.DecimalSI),
|
||||||
|
hugepages2M: *resource.NewQuantity(7, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
fmt.Sprintf(msgNotEqual, hugepages2M),
|
fmt.Sprintf(msgNotEqual, hugepages2M),
|
||||||
@ -266,13 +310,13 @@ func TestConvertPreReserved(t *testing.T) {
|
|||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
description string
|
description string
|
||||||
systemReserved kubetypes.NUMANodeResources
|
systemReserved []kubeletconfig.MemoryReservation
|
||||||
systemReservedExpected systemReservedMemory
|
systemReservedExpected systemReservedMemory
|
||||||
expectedError string
|
expectedError string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"Empty",
|
"Empty",
|
||||||
kubetypes.NUMANodeResources{},
|
[]kubeletconfig.MemoryReservation{},
|
||||||
systemReservedMemory{
|
systemReservedMemory{
|
||||||
0: map[v1.ResourceName]uint64{},
|
0: map[v1.ResourceName]uint64{},
|
||||||
1: map[v1.ResourceName]uint64{},
|
1: map[v1.ResourceName]uint64{},
|
||||||
@ -281,10 +325,15 @@ func TestConvertPreReserved(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Single NUMA node is reserved",
|
"Single NUMA node is reserved",
|
||||||
kubetypes.NUMANodeResources{
|
[]kubeletconfig.MemoryReservation{
|
||||||
0: nodeResources{v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI),
|
{
|
||||||
hugepages2M: *resource.NewQuantity(70, resource.DecimalSI),
|
NumaNode: 0,
|
||||||
hugepages1G: *resource.NewQuantity(13, resource.DecimalSI)},
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI),
|
||||||
|
hugepages2M: *resource.NewQuantity(70, resource.DecimalSI),
|
||||||
|
hugepages1G: *resource.NewQuantity(13, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
systemReservedMemory{
|
systemReservedMemory{
|
||||||
0: map[v1.ResourceName]uint64{
|
0: map[v1.ResourceName]uint64{
|
||||||
@ -298,12 +347,22 @@ func TestConvertPreReserved(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Both NUMA nodes are reserved",
|
"Both NUMA nodes are reserved",
|
||||||
kubetypes.NUMANodeResources{
|
[]kubeletconfig.MemoryReservation{
|
||||||
0: nodeResources{v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI),
|
{
|
||||||
hugepages2M: *resource.NewQuantity(70, resource.DecimalSI),
|
NumaNode: 0,
|
||||||
hugepages1G: *resource.NewQuantity(13, resource.DecimalSI)},
|
Limits: v1.ResourceList{
|
||||||
1: nodeResources{v1.ResourceMemory: *resource.NewQuantity(5, resource.DecimalSI),
|
v1.ResourceMemory: *resource.NewQuantity(12, resource.DecimalSI),
|
||||||
hugepages2M: *resource.NewQuantity(7, resource.DecimalSI)},
|
hugepages2M: *resource.NewQuantity(70, resource.DecimalSI),
|
||||||
|
hugepages1G: *resource.NewQuantity(13, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
NumaNode: 1,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(5, resource.DecimalSI),
|
||||||
|
hugepages2M: *resource.NewQuantity(7, resource.DecimalSI),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
systemReservedMemory{
|
systemReservedMemory{
|
||||||
0: map[v1.ResourceName]uint64{
|
0: map[v1.ResourceName]uint64{
|
||||||
@ -336,7 +395,7 @@ func TestGetSystemReservedMemory(t *testing.T) {
|
|||||||
{
|
{
|
||||||
description: "Should return empty map when reservation is not done",
|
description: "Should return empty map when reservation is not done",
|
||||||
nodeAllocatableReservation: v1.ResourceList{},
|
nodeAllocatableReservation: v1.ResourceList{},
|
||||||
systemReservedMemory: kubetypes.NUMANodeResources{},
|
systemReservedMemory: []kubeletconfig.MemoryReservation{},
|
||||||
expectedReserved: systemReservedMemory{
|
expectedReserved: systemReservedMemory{
|
||||||
0: {},
|
0: {},
|
||||||
1: {},
|
1: {},
|
||||||
@ -347,8 +406,13 @@ func TestGetSystemReservedMemory(t *testing.T) {
|
|||||||
{
|
{
|
||||||
description: "Should return error when Allocatable reservation is not equal pre reserved memory",
|
description: "Should return error when Allocatable reservation is not equal pre reserved memory",
|
||||||
nodeAllocatableReservation: v1.ResourceList{},
|
nodeAllocatableReservation: v1.ResourceList{},
|
||||||
systemReservedMemory: kubetypes.NUMANodeResources{
|
systemReservedMemory: []kubeletconfig.MemoryReservation{
|
||||||
0: nodeResources{v1.ResourceMemory: *resource.NewQuantity(gb, resource.BinarySI)},
|
{
|
||||||
|
NumaNode: 0,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(gb, resource.BinarySI),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
expectedReserved: nil,
|
expectedReserved: nil,
|
||||||
expectedError: fmt.Errorf("the total amount of memory of type \"memory\" is not equal to the value determined by Node Allocatable feature"),
|
expectedError: fmt.Errorf("the total amount of memory of type \"memory\" is not equal to the value determined by Node Allocatable feature"),
|
||||||
@ -357,9 +421,19 @@ func TestGetSystemReservedMemory(t *testing.T) {
|
|||||||
{
|
{
|
||||||
description: "Reserved should be equal to systemReservedMemory",
|
description: "Reserved should be equal to systemReservedMemory",
|
||||||
nodeAllocatableReservation: v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(2*gb, resource.BinarySI)},
|
nodeAllocatableReservation: v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(2*gb, resource.BinarySI)},
|
||||||
systemReservedMemory: kubetypes.NUMANodeResources{
|
systemReservedMemory: []kubeletconfig.MemoryReservation{
|
||||||
0: nodeResources{v1.ResourceMemory: *resource.NewQuantity(gb, resource.BinarySI)},
|
{
|
||||||
1: nodeResources{v1.ResourceMemory: *resource.NewQuantity(gb, resource.BinarySI)},
|
NumaNode: 0,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(gb, resource.BinarySI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
NumaNode: 1,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(gb, resource.BinarySI),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
expectedReserved: systemReservedMemory{
|
expectedReserved: systemReservedMemory{
|
||||||
0: map[v1.ResourceName]uint64{
|
0: map[v1.ResourceName]uint64{
|
||||||
@ -2063,9 +2137,15 @@ func TestNewManager(t *testing.T) {
|
|||||||
policyName: policyTypeStatic,
|
policyName: policyTypeStatic,
|
||||||
machineInfo: machineInfo,
|
machineInfo: machineInfo,
|
||||||
nodeAllocatableReservation: v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(2*gb, resource.BinarySI)},
|
nodeAllocatableReservation: v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(2*gb, resource.BinarySI)},
|
||||||
systemReservedMemory: kubetypes.NUMANodeResources{
|
systemReservedMemory: []kubeletconfig.MemoryReservation{
|
||||||
0: nodeResources{v1.ResourceMemory: *resource.NewQuantity(gb, resource.BinarySI)},
|
{
|
||||||
1: nodeResources{v1.ResourceMemory: *resource.NewQuantity(gb, resource.BinarySI)},
|
NumaNode: 0,
|
||||||
|
Limits: v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(gb, resource.BinarySI)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
NumaNode: 1,
|
||||||
|
Limits: v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(gb, resource.BinarySI)},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
affinity: topologymanager.NewFakeManager(),
|
affinity: topologymanager.NewFakeManager(),
|
||||||
expectedError: nil,
|
expectedError: nil,
|
||||||
@ -2076,9 +2156,19 @@ func TestNewManager(t *testing.T) {
|
|||||||
policyName: policyTypeStatic,
|
policyName: policyTypeStatic,
|
||||||
machineInfo: machineInfo,
|
machineInfo: machineInfo,
|
||||||
nodeAllocatableReservation: v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(2*gb, resource.BinarySI)},
|
nodeAllocatableReservation: v1.ResourceList{v1.ResourceMemory: *resource.NewQuantity(2*gb, resource.BinarySI)},
|
||||||
systemReservedMemory: kubetypes.NUMANodeResources{
|
systemReservedMemory: []kubeletconfig.MemoryReservation{
|
||||||
0: nodeResources{v1.ResourceMemory: *resource.NewQuantity(gb, resource.BinarySI)},
|
{
|
||||||
1: nodeResources{v1.ResourceMemory: *resource.NewQuantity(2*gb, resource.BinarySI)},
|
NumaNode: 0,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(gb, resource.BinarySI),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
NumaNode: 1,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
v1.ResourceMemory: *resource.NewQuantity(2*gb, resource.BinarySI),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
affinity: topologymanager.NewFakeManager(),
|
affinity: topologymanager.NewFakeManager(),
|
||||||
expectedError: fmt.Errorf("the total amount of memory of type %q is not equal to the value determined by Node Allocatable feature", v1.ResourceMemory),
|
expectedError: fmt.Errorf("the total amount of memory of type %q is not equal to the value determined by Node Allocatable feature", v1.ResourceMemory),
|
||||||
@ -2089,7 +2179,7 @@ func TestNewManager(t *testing.T) {
|
|||||||
policyName: policyTypeStatic,
|
policyName: policyTypeStatic,
|
||||||
machineInfo: machineInfo,
|
machineInfo: machineInfo,
|
||||||
nodeAllocatableReservation: v1.ResourceList{},
|
nodeAllocatableReservation: v1.ResourceList{},
|
||||||
systemReservedMemory: kubetypes.NUMANodeResources{},
|
systemReservedMemory: []kubeletconfig.MemoryReservation{},
|
||||||
affinity: topologymanager.NewFakeManager(),
|
affinity: topologymanager.NewFakeManager(),
|
||||||
expectedError: fmt.Errorf("[memorymanager] you should specify the system reserved memory"),
|
expectedError: fmt.Errorf("[memorymanager] you should specify the system reserved memory"),
|
||||||
expectedReserved: expectedReserved,
|
expectedReserved: expectedReserved,
|
||||||
@ -2099,7 +2189,7 @@ func TestNewManager(t *testing.T) {
|
|||||||
policyName: "fake",
|
policyName: "fake",
|
||||||
machineInfo: machineInfo,
|
machineInfo: machineInfo,
|
||||||
nodeAllocatableReservation: v1.ResourceList{},
|
nodeAllocatableReservation: v1.ResourceList{},
|
||||||
systemReservedMemory: kubetypes.NUMANodeResources{},
|
systemReservedMemory: []kubeletconfig.MemoryReservation{},
|
||||||
affinity: topologymanager.NewFakeManager(),
|
affinity: topologymanager.NewFakeManager(),
|
||||||
expectedError: fmt.Errorf("unknown policy: \"fake\""),
|
expectedError: fmt.Errorf("unknown policy: \"fake\""),
|
||||||
expectedReserved: expectedReserved,
|
expectedReserved: expectedReserved,
|
||||||
@ -2109,7 +2199,7 @@ func TestNewManager(t *testing.T) {
|
|||||||
policyName: policyTypeNone,
|
policyName: policyTypeNone,
|
||||||
machineInfo: machineInfo,
|
machineInfo: machineInfo,
|
||||||
nodeAllocatableReservation: v1.ResourceList{},
|
nodeAllocatableReservation: v1.ResourceList{},
|
||||||
systemReservedMemory: kubetypes.NUMANodeResources{},
|
systemReservedMemory: []kubeletconfig.MemoryReservation{},
|
||||||
affinity: topologymanager.NewFakeManager(),
|
affinity: topologymanager.NewFakeManager(),
|
||||||
expectedError: nil,
|
expectedError: nil,
|
||||||
expectedReserved: expectedReserved,
|
expectedReserved: expectedReserved,
|
||||||
|
@ -20,7 +20,6 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//pkg/apis/scheduling:go_default_library",
|
"//pkg/apis/scheduling:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -114,6 +113,3 @@ type ResolvedPodUID types.UID
|
|||||||
|
|
||||||
// MirrorPodUID is a pod UID for a mirror pod.
|
// MirrorPodUID is a pod UID for a mirror pod.
|
||||||
type MirrorPodUID types.UID
|
type MirrorPodUID types.UID
|
||||||
|
|
||||||
// NUMANodeResources is a set of (resource name, quantity) pairs for each NUMA node.
|
|
||||||
type NUMANodeResources map[int]map[v1.ResourceName]resource.Quantity
|
|
||||||
|
@ -46,9 +46,6 @@ import (
|
|||||||
const (
|
const (
|
||||||
evictionHardMemory = "memory.available"
|
evictionHardMemory = "memory.available"
|
||||||
memoryManagerStateFile = "/var/lib/kubelet/memory_manager_state"
|
memoryManagerStateFile = "/var/lib/kubelet/memory_manager_state"
|
||||||
reservedLimit = "limit"
|
|
||||||
reservedNUMANode = "numa-node"
|
|
||||||
reservedType = "type"
|
|
||||||
resourceMemory = "memory"
|
resourceMemory = "memory"
|
||||||
staticPolicy = "static"
|
staticPolicy = "static"
|
||||||
nonePolicy = "none"
|
nonePolicy = "none"
|
||||||
@ -159,7 +156,7 @@ func getMemoryManagerState() (*state.MemoryManagerCheckpoint, error) {
|
|||||||
type kubeletParams struct {
|
type kubeletParams struct {
|
||||||
memoryManagerFeatureGate bool
|
memoryManagerFeatureGate bool
|
||||||
memoryManagerPolicy string
|
memoryManagerPolicy string
|
||||||
systemReservedMemory []map[string]string
|
systemReservedMemory []kubeletconfig.MemoryReservation
|
||||||
systemReserved map[string]string
|
systemReserved map[string]string
|
||||||
kubeReserved map[string]string
|
kubeReserved map[string]string
|
||||||
evictionHard map[string]string
|
evictionHard map[string]string
|
||||||
@ -200,10 +197,10 @@ func getUpdatedKubeletConfig(oldCfg *kubeletconfig.KubeletConfiguration, params
|
|||||||
|
|
||||||
// update reserved memory
|
// update reserved memory
|
||||||
if newCfg.ReservedMemory == nil {
|
if newCfg.ReservedMemory == nil {
|
||||||
newCfg.ReservedMemory = []map[string]string{}
|
newCfg.ReservedMemory = []kubeletconfig.MemoryReservation{}
|
||||||
}
|
}
|
||||||
for _, p := range params.systemReservedMemory {
|
for _, memoryReservation := range params.systemReservedMemory {
|
||||||
newCfg.ReservedMemory = append(newCfg.ReservedMemory, p)
|
newCfg.ReservedMemory = append(newCfg.ReservedMemory, memoryReservation)
|
||||||
}
|
}
|
||||||
|
|
||||||
return newCfg
|
return newCfg
|
||||||
@ -259,10 +256,17 @@ var _ = SIGDescribe("Memory Manager [Serial] [Feature:MemoryManager][NodeAlphaFe
|
|||||||
)
|
)
|
||||||
|
|
||||||
f := framework.NewDefaultFramework("memory-manager-test")
|
f := framework.NewDefaultFramework("memory-manager-test")
|
||||||
|
|
||||||
|
memoryQuantatity := resource.MustParse("1100Mi")
|
||||||
defaultKubeParams := &kubeletParams{
|
defaultKubeParams := &kubeletParams{
|
||||||
memoryManagerFeatureGate: true,
|
memoryManagerFeatureGate: true,
|
||||||
systemReservedMemory: []map[string]string{
|
systemReservedMemory: []kubeletconfig.MemoryReservation{
|
||||||
{reservedNUMANode: "0", reservedType: resourceMemory, reservedLimit: "1100Mi"},
|
{
|
||||||
|
NumaNode: 0,
|
||||||
|
Limits: v1.ResourceList{
|
||||||
|
resourceMemory: memoryQuantatity,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
systemReserved: map[string]string{resourceMemory: "500Mi"},
|
systemReserved: map[string]string{resourceMemory: "500Mi"},
|
||||||
kubeReserved: map[string]string{resourceMemory: "500Mi"},
|
kubeReserved: map[string]string{resourceMemory: "500Mi"},
|
||||||
|
Loading…
Reference in New Issue
Block a user