mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-23 18:40:53 +00:00
Fix unbounded growth of cached OIRs in sched cache
- Added schedulercache.Resource.SetOpaque helper. - Amend kubelet allocatable sync so that when OIRs are removed from capacity they are also removed from allocatable. - Fixes #41861.
This commit is contained in:
parent
e402c5d5e5
commit
8a42189690
@ -529,6 +529,14 @@ func (kl *Kubelet) setNodeStatusMachineInfo(node *v1.Node) {
|
|||||||
if node.Status.Allocatable == nil {
|
if node.Status.Allocatable == nil {
|
||||||
node.Status.Allocatable = make(v1.ResourceList)
|
node.Status.Allocatable = make(v1.ResourceList)
|
||||||
}
|
}
|
||||||
|
// Remove opaque integer resources from allocatable that are no longer
|
||||||
|
// present in capacity.
|
||||||
|
for k := range node.Status.Allocatable {
|
||||||
|
_, found := node.Status.Capacity[k]
|
||||||
|
if !found && v1.IsOpaqueIntResourceName(k) {
|
||||||
|
delete(node.Status.Allocatable, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
allocatableReservation := kl.containerManager.GetNodeAllocatableReservation()
|
allocatableReservation := kl.containerManager.GetNodeAllocatableReservation()
|
||||||
for k, v := range node.Status.Capacity {
|
for k, v := range node.Status.Capacity {
|
||||||
value := *(v.Copy())
|
value := *(v.Copy())
|
||||||
|
@ -468,6 +468,30 @@ func (c *VolumeZoneChecker) predicate(pod *v1.Pod, meta interface{}, nodeInfo *s
|
|||||||
return true, nil, nil
|
return true, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a *schedulercache.Resource that covers the largest width in each
|
||||||
|
// resource dimension. Because init-containers run sequentially, we collect the
|
||||||
|
// max in each dimension iteratively. In contrast, we sum the resource vectors
|
||||||
|
// for regular containers since they run simultaneously.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// Pod:
|
||||||
|
// InitContainers
|
||||||
|
// IC1:
|
||||||
|
// CPU: 2
|
||||||
|
// Memory: 1G
|
||||||
|
// IC2:
|
||||||
|
// CPU: 2
|
||||||
|
// Memory: 3G
|
||||||
|
// Containers
|
||||||
|
// C1:
|
||||||
|
// CPU: 2
|
||||||
|
// Memory: 1G
|
||||||
|
// C2:
|
||||||
|
// CPU: 1
|
||||||
|
// Memory: 1G
|
||||||
|
//
|
||||||
|
// Result: CPU: 3, Memory: 3G
|
||||||
func GetResourceRequest(pod *v1.Pod) *schedulercache.Resource {
|
func GetResourceRequest(pod *v1.Pod) *schedulercache.Resource {
|
||||||
result := schedulercache.Resource{}
|
result := schedulercache.Resource{}
|
||||||
for _, container := range pod.Spec.Containers {
|
for _, container := range pod.Spec.Containers {
|
||||||
@ -505,10 +529,8 @@ func GetResourceRequest(pod *v1.Pod) *schedulercache.Resource {
|
|||||||
default:
|
default:
|
||||||
if v1.IsOpaqueIntResourceName(rName) {
|
if v1.IsOpaqueIntResourceName(rName) {
|
||||||
value := rQuantity.Value()
|
value := rQuantity.Value()
|
||||||
// Ensure the opaque resource map is initialized in the result.
|
|
||||||
result.AddOpaque(rName, int64(0))
|
|
||||||
if value > result.OpaqueIntResources[rName] {
|
if value > result.OpaqueIntResources[rName] {
|
||||||
result.OpaqueIntResources[rName] = value
|
result.SetOpaque(rName, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,11 +83,15 @@ func (r *Resource) ResourceList() v1.ResourceList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resource) AddOpaque(name v1.ResourceName, quantity int64) {
|
func (r *Resource) AddOpaque(name v1.ResourceName, quantity int64) {
|
||||||
|
r.SetOpaque(name, r.OpaqueIntResources[name]+quantity)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Resource) SetOpaque(name v1.ResourceName, quantity int64) {
|
||||||
// Lazily allocate opaque integer resource map.
|
// Lazily allocate opaque integer resource map.
|
||||||
if r.OpaqueIntResources == nil {
|
if r.OpaqueIntResources == nil {
|
||||||
r.OpaqueIntResources = map[v1.ResourceName]int64{}
|
r.OpaqueIntResources = map[v1.ResourceName]int64{}
|
||||||
}
|
}
|
||||||
r.OpaqueIntResources[name] += quantity
|
r.OpaqueIntResources[name] = quantity
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewNodeInfo returns a ready to use empty NodeInfo object.
|
// NewNodeInfo returns a ready to use empty NodeInfo object.
|
||||||
@ -333,7 +337,7 @@ func (n *NodeInfo) SetNode(node *v1.Node) error {
|
|||||||
n.allowedPodNumber = int(rQuant.Value())
|
n.allowedPodNumber = int(rQuant.Value())
|
||||||
default:
|
default:
|
||||||
if v1.IsOpaqueIntResourceName(rName) {
|
if v1.IsOpaqueIntResourceName(rName) {
|
||||||
n.allocatableResource.AddOpaque(rName, rQuant.Value())
|
n.allocatableResource.SetOpaque(rName, rQuant.Value())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user