...

Source file src/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope.go

Documentation: k8s.io/kubernetes/pkg/kubelet/cm/topologymanager

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package topologymanager
    18  
    19  import (
    20  	"sync"
    21  
    22  	"k8s.io/api/core/v1"
    23  	"k8s.io/klog/v2"
    24  	"k8s.io/kubernetes/pkg/kubelet/cm/admission"
    25  	"k8s.io/kubernetes/pkg/kubelet/cm/containermap"
    26  	"k8s.io/kubernetes/pkg/kubelet/lifecycle"
    27  )
    28  
    29  const (
    30  	// containerTopologyScope specifies the TopologyManagerScope per container.
    31  	containerTopologyScope = "container"
    32  	// podTopologyScope specifies the TopologyManagerScope per pod.
    33  	podTopologyScope = "pod"
    34  	// noneTopologyScope specifies the TopologyManagerScope when topologyPolicyName is none.
    35  	noneTopologyScope = "none"
    36  )
    37  
    38  type podTopologyHints map[string]map[string]TopologyHint
    39  
    40  // Scope interface for Topology Manager
    41  type Scope interface {
    42  	Name() string
    43  	GetPolicy() Policy
    44  	Admit(pod *v1.Pod) lifecycle.PodAdmitResult
    45  	// AddHintProvider adds a hint provider to manager to indicate the hint provider
    46  	// wants to be consoluted with when making topology hints
    47  	AddHintProvider(h HintProvider)
    48  	// AddContainer adds pod to Manager for tracking
    49  	AddContainer(pod *v1.Pod, container *v1.Container, containerID string)
    50  	// RemoveContainer removes pod from Manager tracking
    51  	RemoveContainer(containerID string) error
    52  	// Store is the interface for storing pod topology hints
    53  	Store
    54  }
    55  
    56  type scope struct {
    57  	mutex sync.Mutex
    58  	name  string
    59  	// Mapping of a Pods mapping of Containers and their TopologyHints
    60  	// Indexed by PodUID to ContainerName
    61  	podTopologyHints podTopologyHints
    62  	// The list of components registered with the Manager
    63  	hintProviders []HintProvider
    64  	// Topology Manager Policy
    65  	policy Policy
    66  	// Mapping of (PodUid, ContainerName) to ContainerID for Adding/Removing Pods from PodTopologyHints mapping
    67  	podMap containermap.ContainerMap
    68  }
    69  
    70  func (s *scope) Name() string {
    71  	return s.name
    72  }
    73  
    74  func (s *scope) getTopologyHints(podUID string, containerName string) TopologyHint {
    75  	s.mutex.Lock()
    76  	defer s.mutex.Unlock()
    77  	return s.podTopologyHints[podUID][containerName]
    78  }
    79  
    80  func (s *scope) setTopologyHints(podUID string, containerName string, th TopologyHint) {
    81  	s.mutex.Lock()
    82  	defer s.mutex.Unlock()
    83  
    84  	if s.podTopologyHints[podUID] == nil {
    85  		s.podTopologyHints[podUID] = make(map[string]TopologyHint)
    86  	}
    87  	s.podTopologyHints[podUID][containerName] = th
    88  }
    89  
    90  func (s *scope) GetAffinity(podUID string, containerName string) TopologyHint {
    91  	return s.getTopologyHints(podUID, containerName)
    92  }
    93  
    94  func (s *scope) GetPolicy() Policy {
    95  	return s.policy
    96  }
    97  
    98  func (s *scope) AddHintProvider(h HintProvider) {
    99  	s.hintProviders = append(s.hintProviders, h)
   100  }
   101  
   102  // It would be better to implement this function in topologymanager instead of scope
   103  // but topologymanager do not track mapping anymore
   104  func (s *scope) AddContainer(pod *v1.Pod, container *v1.Container, containerID string) {
   105  	s.mutex.Lock()
   106  	defer s.mutex.Unlock()
   107  
   108  	s.podMap.Add(string(pod.UID), container.Name, containerID)
   109  }
   110  
   111  // It would be better to implement this function in topologymanager instead of scope
   112  // but topologymanager do not track mapping anymore
   113  func (s *scope) RemoveContainer(containerID string) error {
   114  	s.mutex.Lock()
   115  	defer s.mutex.Unlock()
   116  
   117  	klog.InfoS("RemoveContainer", "containerID", containerID)
   118  	// Get the podUID and containerName associated with the containerID to be removed and remove it
   119  	podUIDString, containerName, err := s.podMap.GetContainerRef(containerID)
   120  	if err != nil {
   121  		return nil
   122  	}
   123  	s.podMap.RemoveByContainerID(containerID)
   124  
   125  	// In cases where a container has been restarted, it's possible that the same podUID and
   126  	// containerName are already associated with a *different* containerID now. Only remove
   127  	// the TopologyHints associated with that podUID and containerName if this is not true
   128  	if _, err := s.podMap.GetContainerID(podUIDString, containerName); err != nil {
   129  		delete(s.podTopologyHints[podUIDString], containerName)
   130  		if len(s.podTopologyHints[podUIDString]) == 0 {
   131  			delete(s.podTopologyHints, podUIDString)
   132  		}
   133  	}
   134  
   135  	return nil
   136  }
   137  
   138  func (s *scope) admitPolicyNone(pod *v1.Pod) lifecycle.PodAdmitResult {
   139  	for _, container := range append(pod.Spec.InitContainers, pod.Spec.Containers...) {
   140  		err := s.allocateAlignedResources(pod, &container)
   141  		if err != nil {
   142  			return admission.GetPodAdmitResult(err)
   143  		}
   144  	}
   145  	return admission.GetPodAdmitResult(nil)
   146  }
   147  
   148  // It would be better to implement this function in topologymanager instead of scope
   149  // but topologymanager do not track providers anymore
   150  func (s *scope) allocateAlignedResources(pod *v1.Pod, container *v1.Container) error {
   151  	for _, provider := range s.hintProviders {
   152  		err := provider.Allocate(pod, container)
   153  		if err != nil {
   154  			return err
   155  		}
   156  	}
   157  	return nil
   158  }
   159  

View as plain text