k8s.io/kubernetes@v1.29.3/pkg/kubelet/apis/podresources/server_v1.go (about)

     1  /*
     2  Copyright 2018 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 podresources
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  
    23  	utilfeature "k8s.io/apiserver/pkg/util/feature"
    24  	kubefeatures "k8s.io/kubernetes/pkg/features"
    25  	"k8s.io/kubernetes/pkg/kubelet/metrics"
    26  
    27  	"k8s.io/kubelet/pkg/apis/podresources/v1"
    28  )
    29  
    30  // v1PodResourcesServer implements PodResourcesListerServer
    31  type v1PodResourcesServer struct {
    32  	podsProvider             PodsProvider
    33  	devicesProvider          DevicesProvider
    34  	cpusProvider             CPUsProvider
    35  	memoryProvider           MemoryProvider
    36  	dynamicResourcesProvider DynamicResourcesProvider
    37  }
    38  
    39  // NewV1PodResourcesServer returns a PodResourcesListerServer which lists pods provided by the PodsProvider
    40  // with device information provided by the DevicesProvider
    41  func NewV1PodResourcesServer(providers PodResourcesProviders) v1.PodResourcesListerServer {
    42  	return &v1PodResourcesServer{
    43  		podsProvider:             providers.Pods,
    44  		devicesProvider:          providers.Devices,
    45  		cpusProvider:             providers.Cpus,
    46  		memoryProvider:           providers.Memory,
    47  		dynamicResourcesProvider: providers.DynamicResources,
    48  	}
    49  }
    50  
    51  // List returns information about the resources assigned to pods on the node
    52  func (p *v1PodResourcesServer) List(ctx context.Context, req *v1.ListPodResourcesRequest) (*v1.ListPodResourcesResponse, error) {
    53  	metrics.PodResourcesEndpointRequestsTotalCount.WithLabelValues("v1").Inc()
    54  	metrics.PodResourcesEndpointRequestsListCount.WithLabelValues("v1").Inc()
    55  
    56  	pods := p.podsProvider.GetPods()
    57  	podResources := make([]*v1.PodResources, len(pods))
    58  	p.devicesProvider.UpdateAllocatedDevices()
    59  
    60  	for i, pod := range pods {
    61  		pRes := v1.PodResources{
    62  			Name:       pod.Name,
    63  			Namespace:  pod.Namespace,
    64  			Containers: make([]*v1.ContainerResources, len(pod.Spec.Containers)),
    65  		}
    66  
    67  		for j, container := range pod.Spec.Containers {
    68  			pRes.Containers[j] = &v1.ContainerResources{
    69  				Name:    container.Name,
    70  				Devices: p.devicesProvider.GetDevices(string(pod.UID), container.Name),
    71  				CpuIds:  p.cpusProvider.GetCPUs(string(pod.UID), container.Name),
    72  				Memory:  p.memoryProvider.GetMemory(string(pod.UID), container.Name),
    73  			}
    74  			if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.KubeletPodResourcesDynamicResources) {
    75  				pRes.Containers[j].DynamicResources = p.dynamicResourcesProvider.GetDynamicResources(pod, &container)
    76  			}
    77  
    78  		}
    79  		podResources[i] = &pRes
    80  	}
    81  
    82  	response := &v1.ListPodResourcesResponse{
    83  		PodResources: podResources,
    84  	}
    85  	return response, nil
    86  }
    87  
    88  // GetAllocatableResources returns information about all the resources known by the server - this more like the capacity, not like the current amount of free resources.
    89  func (p *v1PodResourcesServer) GetAllocatableResources(ctx context.Context, req *v1.AllocatableResourcesRequest) (*v1.AllocatableResourcesResponse, error) {
    90  	metrics.PodResourcesEndpointRequestsTotalCount.WithLabelValues("v1").Inc()
    91  	metrics.PodResourcesEndpointRequestsGetAllocatableCount.WithLabelValues("v1").Inc()
    92  
    93  	response := &v1.AllocatableResourcesResponse{
    94  		Devices: p.devicesProvider.GetAllocatableDevices(),
    95  		CpuIds:  p.cpusProvider.GetAllocatableCPUs(),
    96  		Memory:  p.memoryProvider.GetAllocatableMemory(),
    97  	}
    98  
    99  	return response, nil
   100  }
   101  
   102  // Get returns information about the resources assigned to a specific pod
   103  func (p *v1PodResourcesServer) Get(ctx context.Context, req *v1.GetPodResourcesRequest) (*v1.GetPodResourcesResponse, error) {
   104  	metrics.PodResourcesEndpointRequestsTotalCount.WithLabelValues("v1").Inc()
   105  	metrics.PodResourcesEndpointRequestsGetCount.WithLabelValues("v1").Inc()
   106  
   107  	if !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.KubeletPodResourcesGet) {
   108  		metrics.PodResourcesEndpointErrorsGetCount.WithLabelValues("v1").Inc()
   109  		return nil, fmt.Errorf("PodResources API Get method disabled")
   110  	}
   111  
   112  	pod, exist := p.podsProvider.GetPodByName(req.PodNamespace, req.PodName)
   113  	if !exist {
   114  		metrics.PodResourcesEndpointErrorsGetCount.WithLabelValues("v1").Inc()
   115  		return nil, fmt.Errorf("pod %s in namespace %s not found", req.PodName, req.PodNamespace)
   116  	}
   117  
   118  	podResources := &v1.PodResources{
   119  		Name:       pod.Name,
   120  		Namespace:  pod.Namespace,
   121  		Containers: make([]*v1.ContainerResources, len(pod.Spec.Containers)),
   122  	}
   123  
   124  	for i, container := range pod.Spec.Containers {
   125  		podResources.Containers[i] = &v1.ContainerResources{
   126  			Name:    container.Name,
   127  			Devices: p.devicesProvider.GetDevices(string(pod.UID), container.Name),
   128  			CpuIds:  p.cpusProvider.GetCPUs(string(pod.UID), container.Name),
   129  			Memory:  p.memoryProvider.GetMemory(string(pod.UID), container.Name),
   130  		}
   131  		if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.KubeletPodResourcesDynamicResources) {
   132  			podResources.Containers[i].DynamicResources = p.dynamicResourcesProvider.GetDynamicResources(pod, &container)
   133  		}
   134  	}
   135  
   136  	response := &v1.GetPodResourcesResponse{
   137  		PodResources: podResources,
   138  	}
   139  	return response, nil
   140  }