k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/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 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 }