memory manager: update all relevant part of code to use []MemoryReservation

Signed-off-by: Artyom Lukianov <alukiano@redhat.com>
This commit is contained in:
Artyom Lukianov 2020-11-18 00:22:43 +02:00
parent 7561a0f96e
commit e8ea461bfd
7 changed files with 186 additions and 98 deletions

View File

@ -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

View File

@ -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",

View File

@ -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
} }

View File

@ -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,

View File

@ -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",
], ],

View File

@ -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

View File

@ -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"},