mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-27 13:15:36 +00:00
memory manager: update kubelet config API
Update kubelet config API to use slice of MemoryReservation structs instead of slice of maps. Signed-off-by: Artyom Lukianov <alukiano@redhat.com>
This commit is contained in:
@@ -221,7 +221,14 @@ var (
|
||||
"ReadOnlyPort",
|
||||
"RegistryBurst",
|
||||
"RegistryPullQPS",
|
||||
"ReservedMemory[*][*]",
|
||||
"ReservedMemory[*].Limits[*].Format",
|
||||
"ReservedMemory[*].Limits[*].d.Dec.scale",
|
||||
"ReservedMemory[*].Limits[*].d.Dec.unscaled.abs[*]",
|
||||
"ReservedMemory[*].Limits[*].d.Dec.unscaled.neg",
|
||||
"ReservedMemory[*].Limits[*].i.scale",
|
||||
"ReservedMemory[*].Limits[*].i.value",
|
||||
"ReservedMemory[*].Limits[*].s",
|
||||
"ReservedMemory[*].NumaNode",
|
||||
"ReservedSystemCPUs",
|
||||
"RuntimeRequestTimeout.Duration",
|
||||
"RunOnce",
|
||||
|
@@ -385,12 +385,20 @@ type KubeletConfiguration struct {
|
||||
// Defaults to 10 seconds, requires GracefulNodeShutdown feature gate to be enabled.
|
||||
// For example, if ShutdownGracePeriod=30s, and ShutdownGracePeriodCriticalPods=10s, during a node shutdown the first 20 seconds would be reserved for gracefully terminating normal pods, and the last 10 seconds would be reserved for terminating critical pods.
|
||||
ShutdownGracePeriodCriticalPods metav1.Duration
|
||||
// A comma separated list of bracket-enclosed configurations for memory manager.
|
||||
// Each configuration describes pre-reserved memory for the particular memory type on a specific NUMA node.
|
||||
// The Memory Manager validates whether total amount of pre-reserved memory is identical to reserved-memory by the Node Allocatable feature.
|
||||
// The format is {numa-node=integer, memory-type=string, limit=string}
|
||||
// (e.g. {numa-node=0, type=memory, limit=1Gi}, {numa-node=1, type=memory, limit=1Gi})
|
||||
ReservedMemory []map[string]string
|
||||
// ReservedMemory specifies a comma-separated list of memory reservations for NUMA nodes.
|
||||
// The parameter makes sense only in the context of the memory manager feature. The memory manager will not allocate reserved memory for container workloads.
|
||||
// For example, if you have a NUMA0 with 10Gi of memory and the ReservedMemory was specified to reserve 1Gi of memory at NUMA0,
|
||||
// the memory manager will assume that only 9Gi is available for allocation.
|
||||
// You can specify a different amount of NUMA node and memory types.
|
||||
// You can omit this parameter at all, but you should be aware that the amount of reserved memory from all NUMA nodes
|
||||
// should be equal to the amount of memory specified by the node allocatable features(https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable).
|
||||
// If at least one node allocatable parameter has a non-zero value, you will need to specify at least one NUMA node.
|
||||
// Also, avoid specifying:
|
||||
// 1. Duplicates, the same NUMA node, and memory type, but with a different value.
|
||||
// 2. zero limits for any memory type.
|
||||
// 3. NUMAs nodes IDs that do not exist under the machine.
|
||||
// 4. memory types except for memory and hugepages-<size>
|
||||
ReservedMemory []MemoryReservation
|
||||
}
|
||||
|
||||
// KubeletAuthorizationMode denotes the authorization mode for the kubelet
|
||||
@@ -544,3 +552,9 @@ type ExecEnvVar struct {
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
||||
// MemoryReservation specifies the memory reservation of different types for each NUMA node
|
||||
type MemoryReservation struct {
|
||||
NumaNode int32
|
||||
Limits v1.ResourceList
|
||||
}
|
||||
|
@@ -19,10 +19,12 @@ go_library(
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/apis/config/v1beta1",
|
||||
deps = [
|
||||
"//pkg/apis/core/v1:go_default_library",
|
||||
"//pkg/cluster/ports:go_default_library",
|
||||
"//pkg/kubelet/apis/config:go_default_library",
|
||||
"//pkg/kubelet/qos:go_default_library",
|
||||
"//pkg/kubelet/types:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
|
@@ -23,6 +23,7 @@ package v1beta1
|
||||
import (
|
||||
unsafe "unsafe"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
conversion "k8s.io/apimachinery/pkg/conversion"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -108,6 +109,16 @@ func RegisterConversions(s *runtime.Scheme) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1beta1.MemoryReservation)(nil), (*config.MemoryReservation)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_MemoryReservation_To_config_MemoryReservation(a.(*v1beta1.MemoryReservation), b.(*config.MemoryReservation), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*config.MemoryReservation)(nil), (*v1beta1.MemoryReservation)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_config_MemoryReservation_To_v1beta1_MemoryReservation(a.(*config.MemoryReservation), b.(*v1beta1.MemoryReservation), scope)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.AddGeneratedConversionFunc((*v1beta1.SerializedNodeConfigSource)(nil), (*config.SerializedNodeConfigSource)(nil), func(a, b interface{}, scope conversion.Scope) error {
|
||||
return Convert_v1beta1_SerializedNodeConfigSource_To_config_SerializedNodeConfigSource(a.(*v1beta1.SerializedNodeConfigSource), b.(*config.SerializedNodeConfigSource), scope)
|
||||
}); err != nil {
|
||||
@@ -353,7 +364,7 @@ func autoConvert_v1beta1_KubeletConfiguration_To_config_KubeletConfiguration(in
|
||||
}
|
||||
out.ShutdownGracePeriod = in.ShutdownGracePeriod
|
||||
out.ShutdownGracePeriodCriticalPods = in.ShutdownGracePeriodCriticalPods
|
||||
out.ReservedMemory = *(*[]map[string]string)(unsafe.Pointer(&in.ReservedMemory))
|
||||
out.ReservedMemory = *(*[]config.MemoryReservation)(unsafe.Pointer(&in.ReservedMemory))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -508,7 +519,7 @@ func autoConvert_config_KubeletConfiguration_To_v1beta1_KubeletConfiguration(in
|
||||
}
|
||||
out.ShutdownGracePeriod = in.ShutdownGracePeriod
|
||||
out.ShutdownGracePeriodCriticalPods = in.ShutdownGracePeriodCriticalPods
|
||||
out.ReservedMemory = *(*[]map[string]string)(unsafe.Pointer(&in.ReservedMemory))
|
||||
out.ReservedMemory = *(*[]v1beta1.MemoryReservation)(unsafe.Pointer(&in.ReservedMemory))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -585,6 +596,28 @@ func Convert_config_KubeletX509Authentication_To_v1beta1_KubeletX509Authenticati
|
||||
return autoConvert_config_KubeletX509Authentication_To_v1beta1_KubeletX509Authentication(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_MemoryReservation_To_config_MemoryReservation(in *v1beta1.MemoryReservation, out *config.MemoryReservation, s conversion.Scope) error {
|
||||
out.NumaNode = in.NumaNode
|
||||
out.Limits = *(*corev1.ResourceList)(unsafe.Pointer(&in.Limits))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1beta1_MemoryReservation_To_config_MemoryReservation is an autogenerated conversion function.
|
||||
func Convert_v1beta1_MemoryReservation_To_config_MemoryReservation(in *v1beta1.MemoryReservation, out *config.MemoryReservation, s conversion.Scope) error {
|
||||
return autoConvert_v1beta1_MemoryReservation_To_config_MemoryReservation(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_config_MemoryReservation_To_v1beta1_MemoryReservation(in *config.MemoryReservation, out *v1beta1.MemoryReservation, s conversion.Scope) error {
|
||||
out.NumaNode = in.NumaNode
|
||||
out.Limits = *(*corev1.ResourceList)(unsafe.Pointer(&in.Limits))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_config_MemoryReservation_To_v1beta1_MemoryReservation is an autogenerated conversion function.
|
||||
func Convert_config_MemoryReservation_To_v1beta1_MemoryReservation(in *config.MemoryReservation, out *v1beta1.MemoryReservation, s conversion.Scope) error {
|
||||
return autoConvert_config_MemoryReservation_To_v1beta1_MemoryReservation(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1beta1_SerializedNodeConfigSource_To_config_SerializedNodeConfigSource(in *v1beta1.SerializedNodeConfigSource, out *config.SerializedNodeConfigSource, s conversion.Scope) error {
|
||||
out.Source = in.Source
|
||||
return nil
|
||||
|
@@ -23,6 +23,7 @@ package v1beta1
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
v1beta1 "k8s.io/kubelet/config/v1beta1"
|
||||
v1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
)
|
||||
|
||||
// RegisterDefaults adds defaulters functions to the given scheme.
|
||||
@@ -35,4 +36,8 @@ func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
|
||||
func SetObjectDefaults_KubeletConfiguration(in *v1beta1.KubeletConfiguration) {
|
||||
SetDefaults_KubeletConfiguration(in)
|
||||
for i := range in.ReservedMemory {
|
||||
a := &in.ReservedMemory[i]
|
||||
v1.SetDefaults_ResourceList(&a.Limits)
|
||||
}
|
||||
}
|
||||
|
34
pkg/kubelet/apis/config/zz_generated.deepcopy.go
generated
34
pkg/kubelet/apis/config/zz_generated.deepcopy.go
generated
@@ -21,6 +21,7 @@ limitations under the License.
|
||||
package config
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
@@ -275,15 +276,9 @@ func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) {
|
||||
out.ShutdownGracePeriodCriticalPods = in.ShutdownGracePeriodCriticalPods
|
||||
if in.ReservedMemory != nil {
|
||||
in, out := &in.ReservedMemory, &out.ReservedMemory
|
||||
*out = make([]map[string]string, len(*in))
|
||||
*out = make([]MemoryReservation, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -358,6 +353,29 @@ func (in *KubeletX509Authentication) DeepCopy() *KubeletX509Authentication {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MemoryReservation) DeepCopyInto(out *MemoryReservation) {
|
||||
*out = *in
|
||||
if in.Limits != nil {
|
||||
in, out := &in.Limits, &out.Limits
|
||||
*out = make(corev1.ResourceList, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val.DeepCopy()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemoryReservation.
|
||||
func (in *MemoryReservation) DeepCopy() *MemoryReservation {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MemoryReservation)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *SerializedNodeConfigSource) DeepCopyInto(out *SerializedNodeConfigSource) {
|
||||
*out = *in
|
||||
|
@@ -838,14 +838,22 @@ type KubeletConfiguration struct {
|
||||
// Default: "10s"
|
||||
// +optional
|
||||
ShutdownGracePeriodCriticalPods metav1.Duration `json:"shutdownGracePeriodCriticalPods,omitempty"`
|
||||
// A comma separated list of bracket-enclosed configurations for memory manager.
|
||||
// Each configuration describes pre-reserved memory for the certain memory type on a specific NUMA node.
|
||||
// The Memory Manager validates whether total amount of pre-reserved memory is identical to reserved-memory by the Node Allocatable feature.
|
||||
// The format is {numa-node=integer, memory-type=string, limit=string}
|
||||
// (e.g. {numa-node=0, type=memory, limit=1Gi}, {numa-node=1, type=memory, limit=1Gi})
|
||||
// ReservedMemory specifies a comma-separated list of memory reservations for NUMA nodes.
|
||||
// The parameter makes sense only in the context of the memory manager feature. The memory manager will not allocate reserved memory for container workloads.
|
||||
// For example, if you have a NUMA0 with 10Gi of memory and the ReservedMemory was specified to reserve 1Gi of memory at NUMA0,
|
||||
// the memory manager will assume that only 9Gi is available for allocation.
|
||||
// You can specify a different amount of NUMA node and memory types.
|
||||
// You can omit this parameter at all, but you should be aware that the amount of reserved memory from all NUMA nodes
|
||||
// should be equal to the amount of memory specified by the node allocatable features(https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable).
|
||||
// If at least one node allocatable parameter has a non-zero value, you will need to specify at least one NUMA node.
|
||||
// Also, avoid specifying:
|
||||
// 1. Duplicates, the same NUMA node, and memory type, but with a different value.
|
||||
// 2. zero limits for any memory type.
|
||||
// 3. NUMAs nodes IDs that do not exist under the machine.
|
||||
// 4. memory types except for memory and hugepages-<size>
|
||||
// Default: nil
|
||||
// +optional
|
||||
ReservedMemory []map[string]string `json:"reservedMemory,omitempty"`
|
||||
ReservedMemory []MemoryReservation `json:"reservedMemory,omitempty"`
|
||||
}
|
||||
|
||||
type KubeletAuthorizationMode string
|
||||
@@ -926,3 +934,9 @@ type SerializedNodeConfigSource struct {
|
||||
// +optional
|
||||
Source v1.NodeConfigSource `json:"source,omitempty" protobuf:"bytes,1,opt,name=source"`
|
||||
}
|
||||
|
||||
// MemoryReservation specifies the memory reservation of different types for each NUMA node
|
||||
type MemoryReservation struct {
|
||||
NumaNode int32 `json:"numaNode"`
|
||||
Limits v1.ResourceList `json:"limits"`
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ limitations under the License.
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
@@ -305,15 +306,9 @@ func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) {
|
||||
out.ShutdownGracePeriodCriticalPods = in.ShutdownGracePeriodCriticalPods
|
||||
if in.ReservedMemory != nil {
|
||||
in, out := &in.ReservedMemory, &out.ReservedMemory
|
||||
*out = make([]map[string]string, len(*in))
|
||||
*out = make([]MemoryReservation, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
@@ -393,6 +388,29 @@ func (in *KubeletX509Authentication) DeepCopy() *KubeletX509Authentication {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *MemoryReservation) DeepCopyInto(out *MemoryReservation) {
|
||||
*out = *in
|
||||
if in.Limits != nil {
|
||||
in, out := &in.Limits, &out.Limits
|
||||
*out = make(corev1.ResourceList, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val.DeepCopy()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemoryReservation.
|
||||
func (in *MemoryReservation) DeepCopy() *MemoryReservation {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MemoryReservation)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *SerializedNodeConfigSource) DeepCopyInto(out *SerializedNodeConfigSource) {
|
||||
*out = *in
|
||||
|
Reference in New Issue
Block a user