...

Source file src/k8s.io/kubernetes/pkg/kubelet/apis/podresources/server_v1.go

Documentation: k8s.io/kubernetes/pkg/kubelet/apis/podresources

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

View as plain text