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 }