mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
Merge pull request #92165 from RenaudWasTaken/v1-pod-resources
Graduate the Pod Resources API to G.A
This commit is contained in:
commit
6e95025994
@ -16,14 +16,14 @@
|
||||
|
||||
# This script generates `*/api.pb.go` from the protobuf file `*/api.proto`.
|
||||
# Example:
|
||||
# kube::protoc::generate_proto "${POD_RESOURCES_ALPHA}"
|
||||
# kube::protoc::generate_proto "${POD_RESOURCES}"
|
||||
|
||||
set -o errexit
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
KUBE_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../" && pwd -P)"
|
||||
POD_RESOURCES_ALPHA="${KUBE_ROOT}/staging/src/k8s.io/kubelet/pkg/apis/podresources/v1alpha1/"
|
||||
POD_RESOURCES="${KUBE_ROOT}/staging/src/k8s.io/kubelet/pkg/apis/podresources/v1/"
|
||||
|
||||
source "${KUBE_ROOT}/hack/lib/protoc.sh"
|
||||
kube::protoc::generate_proto "${POD_RESOURCES_ALPHA}"
|
||||
kube::protoc::generate_proto "${POD_RESOURCES}"
|
||||
|
@ -14,8 +14,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# This script generates `/staging/src/k8s.io/kubelet/pkg/apis/podresources/v1alpha1/api.pb.go`
|
||||
# from the protobuf file `/staging/src/k8s.io/kubelet/pkg/apis/podresources/v1alpha1/api.proto`
|
||||
# This script generates `/staging/src/k8s.io/kubelet/pkg/apis/podresources/v1/api.pb.go`
|
||||
# from the protobuf file `/staging/src/k8s.io/kubelet/pkg/apis/podresources/v1/api.proto`
|
||||
# for pods.
|
||||
# Usage: `hack/update-generated-pod-resources.sh`.
|
||||
|
||||
|
@ -24,26 +24,26 @@ set -o nounset
|
||||
set -o pipefail
|
||||
|
||||
KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
|
||||
POD_RESOURCES_ALPHA="${KUBE_ROOT}/staging/src/k8s.io/kubelet/pkg/apis/podresources/v1alpha1/"
|
||||
POD_RESOURCES="${KUBE_ROOT}/staging/src/k8s.io/kubelet/pkg/apis/podresources/v1/"
|
||||
source "${KUBE_ROOT}/hack/lib/init.sh"
|
||||
|
||||
kube::golang::setup_env
|
||||
|
||||
function cleanup {
|
||||
rm -rf "${POD_RESOURCES_ALPHA}/_tmp/"
|
||||
rm -rf "${POD_RESOURCES}/_tmp/"
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
mkdir -p "${POD_RESOURCES_ALPHA}/_tmp"
|
||||
cp "${POD_RESOURCES_ALPHA}/api.pb.go" "${POD_RESOURCES_ALPHA}/_tmp/"
|
||||
mkdir -p "${POD_RESOURCES}/_tmp"
|
||||
cp "${POD_RESOURCES}/api.pb.go" "${POD_RESOURCES}/_tmp/"
|
||||
|
||||
ret=0
|
||||
KUBE_VERBOSE=3 "${KUBE_ROOT}/hack/update-generated-pod-resources.sh"
|
||||
diff -I "gzipped FileDescriptorProto" -I "0x" -Naupr "${POD_RESOURCES_ALPHA}/_tmp/api.pb.go" "${POD_RESOURCES_ALPHA}/api.pb.go" || ret=$?
|
||||
diff -I "gzipped FileDescriptorProto" -I "0x" -Naupr "${POD_RESOURCES}/_tmp/api.pb.go" "${POD_RESOURCES}/api.pb.go" || ret=$?
|
||||
if [[ $ret -eq 0 ]]; then
|
||||
echo "Generated pod resources api is up to date."
|
||||
cp "${POD_RESOURCES_ALPHA}/_tmp/api.pb.go" "${POD_RESOURCES_ALPHA}/"
|
||||
cp "${POD_RESOURCES}/_tmp/api.pb.go" "${POD_RESOURCES}/"
|
||||
else
|
||||
echo "Generated pod resources api is out of date. Please run hack/update-generated-pod-resources.sh"
|
||||
exit 1
|
||||
|
@ -5,13 +5,17 @@ go_library(
|
||||
srcs = [
|
||||
"client.go",
|
||||
"constants.go",
|
||||
"server.go",
|
||||
"server_v1.go",
|
||||
"server_v1alpha1.go",
|
||||
"types.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/apis/podresources",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/kubelet/metrics:go_default_library",
|
||||
"//pkg/kubelet/util:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/podresources/v1:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/podresources/v1alpha1:go_default_library",
|
||||
"//vendor/google.golang.org/grpc:go_default_library",
|
||||
],
|
||||
@ -19,12 +23,16 @@ go_library(
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["server_test.go"],
|
||||
srcs = [
|
||||
"server_v1_test.go",
|
||||
"server_v1alpha1_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/podresources/v1:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/podresources/v1alpha1:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/mock:go_default_library",
|
||||
],
|
||||
|
@ -23,12 +23,17 @@ import (
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1alpha1"
|
||||
"k8s.io/kubelet/pkg/apis/podresources/v1"
|
||||
"k8s.io/kubelet/pkg/apis/podresources/v1alpha1"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util"
|
||||
)
|
||||
|
||||
// GetClient returns a client for the PodResourcesLister grpc service
|
||||
func GetClient(socket string, connectionTimeout time.Duration, maxMsgSize int) (podresourcesapi.PodResourcesListerClient, *grpc.ClientConn, error) {
|
||||
// Note: Consumers of the pod resources API should not be importing this package.
|
||||
// They should copy paste the function in their project.
|
||||
|
||||
// GetV1alpha1Client returns a client for the PodResourcesLister grpc service
|
||||
// Note: This is deprecated
|
||||
func GetV1alpha1Client(socket string, connectionTimeout time.Duration, maxMsgSize int) (v1alpha1.PodResourcesListerClient, *grpc.ClientConn, error) {
|
||||
addr, dialer, err := util.GetAddressAndDialer(socket)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@ -40,5 +45,21 @@ func GetClient(socket string, connectionTimeout time.Duration, maxMsgSize int) (
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error dialing socket %s: %v", socket, err)
|
||||
}
|
||||
return podresourcesapi.NewPodResourcesListerClient(conn), conn, nil
|
||||
return v1alpha1.NewPodResourcesListerClient(conn), conn, nil
|
||||
}
|
||||
|
||||
// GetV1Client returns a client for the PodResourcesLister grpc service
|
||||
func GetV1Client(socket string, connectionTimeout time.Duration, maxMsgSize int) (v1.PodResourcesListerClient, *grpc.ClientConn, error) {
|
||||
addr, dialer, err := util.GetAddressAndDialer(socket)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), connectionTimeout)
|
||||
defer cancel()
|
||||
|
||||
conn, err := grpc.DialContext(ctx, addr, grpc.WithInsecure(), grpc.WithContextDialer(dialer), grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(maxMsgSize)))
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("error dialing socket %s: %v", socket, err)
|
||||
}
|
||||
return v1.NewPodResourcesListerClient(conn), conn, nil
|
||||
}
|
||||
|
80
pkg/kubelet/apis/podresources/server_v1.go
Normal file
80
pkg/kubelet/apis/podresources/server_v1.go
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package podresources
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubelet/metrics"
|
||||
|
||||
"k8s.io/kubelet/pkg/apis/podresources/v1"
|
||||
"k8s.io/kubelet/pkg/apis/podresources/v1alpha1"
|
||||
)
|
||||
|
||||
// podResourcesServerV1alpha1 implements PodResourcesListerServer
|
||||
type v1PodResourcesServer struct {
|
||||
podsProvider PodsProvider
|
||||
devicesProvider DevicesProvider
|
||||
}
|
||||
|
||||
// NewV1PodResourcesServer returns a PodResourcesListerServer which lists pods provided by the PodsProvider
|
||||
// with device information provided by the DevicesProvider
|
||||
func NewV1PodResourcesServer(podsProvider PodsProvider, devicesProvider DevicesProvider) v1.PodResourcesListerServer {
|
||||
return &v1PodResourcesServer{
|
||||
podsProvider: podsProvider,
|
||||
devicesProvider: devicesProvider,
|
||||
}
|
||||
}
|
||||
|
||||
func alphaDevicesToV1(alphaDevs []*v1alpha1.ContainerDevices) []*v1.ContainerDevices {
|
||||
var devs []*v1.ContainerDevices
|
||||
for _, alphaDev := range alphaDevs {
|
||||
dev := v1.ContainerDevices(*alphaDev)
|
||||
devs = append(devs, &dev)
|
||||
}
|
||||
|
||||
return devs
|
||||
}
|
||||
|
||||
// List returns information about the resources assigned to pods on the node
|
||||
func (p *v1PodResourcesServer) List(ctx context.Context, req *v1.ListPodResourcesRequest) (*v1.ListPodResourcesResponse, error) {
|
||||
metrics.PodResourcesEndpointRequestsTotalCount.WithLabelValues("v1").Inc()
|
||||
|
||||
pods := p.podsProvider.GetPods()
|
||||
podResources := make([]*v1.PodResources, len(pods))
|
||||
p.devicesProvider.UpdateAllocatedDevices()
|
||||
|
||||
for i, pod := range pods {
|
||||
pRes := v1.PodResources{
|
||||
Name: pod.Name,
|
||||
Namespace: pod.Namespace,
|
||||
Containers: make([]*v1.ContainerResources, len(pod.Spec.Containers)),
|
||||
}
|
||||
|
||||
for j, container := range pod.Spec.Containers {
|
||||
pRes.Containers[j] = &v1.ContainerResources{
|
||||
Name: container.Name,
|
||||
Devices: alphaDevicesToV1(p.devicesProvider.GetDevices(string(pod.UID), container.Name)),
|
||||
}
|
||||
}
|
||||
podResources[i] = &pRes
|
||||
}
|
||||
|
||||
return &v1.ListPodResourcesResponse{
|
||||
PodResources: podResources,
|
||||
}, nil
|
||||
}
|
139
pkg/kubelet/apis/podresources/server_v1_test.go
Normal file
139
pkg/kubelet/apis/podresources/server_v1_test.go
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package podresources
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1"
|
||||
"k8s.io/kubelet/pkg/apis/podresources/v1alpha1"
|
||||
)
|
||||
|
||||
func TestListPodResourcesV1(t *testing.T) {
|
||||
podName := "pod-name"
|
||||
podNamespace := "pod-namespace"
|
||||
podUID := types.UID("pod-uid")
|
||||
containerName := "container-name"
|
||||
|
||||
devs := []*v1alpha1.ContainerDevices{
|
||||
{
|
||||
ResourceName: "resource",
|
||||
DeviceIds: []string{"dev0", "dev1"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range []struct {
|
||||
desc string
|
||||
pods []*v1.Pod
|
||||
devices []*v1alpha1.ContainerDevices
|
||||
expectedResponse *podresourcesapi.ListPodResourcesResponse
|
||||
}{
|
||||
{
|
||||
desc: "no pods",
|
||||
pods: []*v1.Pod{},
|
||||
devices: []*v1alpha1.ContainerDevices{},
|
||||
expectedResponse: &podresourcesapi.ListPodResourcesResponse{},
|
||||
},
|
||||
{
|
||||
desc: "pod without devices",
|
||||
pods: []*v1.Pod{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
UID: podUID,
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: containerName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
devices: []*v1alpha1.ContainerDevices{},
|
||||
expectedResponse: &podresourcesapi.ListPodResourcesResponse{
|
||||
PodResources: []*podresourcesapi.PodResources{
|
||||
{
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
Containers: []*podresourcesapi.ContainerResources{
|
||||
{
|
||||
Name: containerName,
|
||||
Devices: []*podresourcesapi.ContainerDevices{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "pod with devices",
|
||||
pods: []*v1.Pod{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
UID: podUID,
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
Containers: []v1.Container{
|
||||
{
|
||||
Name: containerName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
devices: devs,
|
||||
expectedResponse: &podresourcesapi.ListPodResourcesResponse{
|
||||
PodResources: []*podresourcesapi.PodResources{
|
||||
{
|
||||
Name: podName,
|
||||
Namespace: podNamespace,
|
||||
Containers: []*podresourcesapi.ContainerResources{
|
||||
{
|
||||
Name: containerName,
|
||||
Devices: alphaDevicesToV1(devs),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
m := new(mockProvider)
|
||||
m.On("GetPods").Return(tc.pods)
|
||||
m.On("GetDevices", string(podUID), containerName).Return(tc.devices)
|
||||
m.On("UpdateAllocatedDevices").Return()
|
||||
server := NewV1PodResourcesServer(m, m)
|
||||
resp, err := server.List(context.TODO(), &podresourcesapi.ListPodResourcesRequest{})
|
||||
if err != nil {
|
||||
t.Errorf("want err = %v, got %q", nil, err)
|
||||
}
|
||||
if tc.expectedResponse.String() != resp.String() {
|
||||
t.Errorf("want resp = %s, got %s", tc.expectedResponse.String(), resp.String())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -19,38 +19,29 @@ package podresources
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/kubernetes/pkg/kubelet/metrics"
|
||||
|
||||
"k8s.io/kubelet/pkg/apis/podresources/v1alpha1"
|
||||
)
|
||||
|
||||
// DevicesProvider knows how to provide the devices used by the given container
|
||||
type DevicesProvider interface {
|
||||
GetDevices(podUID, containerName string) []*v1alpha1.ContainerDevices
|
||||
UpdateAllocatedDevices()
|
||||
}
|
||||
|
||||
// PodsProvider knows how to provide the pods admitted by the node
|
||||
type PodsProvider interface {
|
||||
GetPods() []*v1.Pod
|
||||
}
|
||||
|
||||
// podResourcesServer implements PodResourcesListerServer
|
||||
type podResourcesServer struct {
|
||||
// podResourcesServerV1alpha1 implements PodResourcesListerServer
|
||||
type v1alpha1PodResourcesServer struct {
|
||||
podsProvider PodsProvider
|
||||
devicesProvider DevicesProvider
|
||||
}
|
||||
|
||||
// NewPodResourcesServer returns a PodResourcesListerServer which lists pods provided by the PodsProvider
|
||||
// NewV1alpha1PodResourcesServer returns a PodResourcesListerServer which lists pods provided by the PodsProvider
|
||||
// with device information provided by the DevicesProvider
|
||||
func NewPodResourcesServer(podsProvider PodsProvider, devicesProvider DevicesProvider) v1alpha1.PodResourcesListerServer {
|
||||
return &podResourcesServer{
|
||||
func NewV1alpha1PodResourcesServer(podsProvider PodsProvider, devicesProvider DevicesProvider) v1alpha1.PodResourcesListerServer {
|
||||
return &v1alpha1PodResourcesServer{
|
||||
podsProvider: podsProvider,
|
||||
devicesProvider: devicesProvider,
|
||||
}
|
||||
}
|
||||
|
||||
// List returns information about the resources assigned to pods on the node
|
||||
func (p *podResourcesServer) List(ctx context.Context, req *v1alpha1.ListPodResourcesRequest) (*v1alpha1.ListPodResourcesResponse, error) {
|
||||
func (p *v1alpha1PodResourcesServer) List(ctx context.Context, req *v1alpha1.ListPodResourcesRequest) (*v1alpha1.ListPodResourcesResponse, error) {
|
||||
metrics.PodResourcesEndpointRequestsTotalCount.WithLabelValues("v1alpha1").Inc()
|
||||
pods := p.podsProvider.GetPods()
|
||||
podResources := make([]*v1alpha1.PodResources, len(pods))
|
||||
p.devicesProvider.UpdateAllocatedDevices()
|
@ -46,7 +46,7 @@ func (m *mockProvider) UpdateAllocatedDevices() {
|
||||
m.Called()
|
||||
}
|
||||
|
||||
func TestListPodResources(t *testing.T) {
|
||||
func TestListPodResourcesV1alpha1(t *testing.T) {
|
||||
podName := "pod-name"
|
||||
podNamespace := "pod-namespace"
|
||||
podUID := types.UID("pod-uid")
|
||||
@ -145,7 +145,7 @@ func TestListPodResources(t *testing.T) {
|
||||
m.On("GetPods").Return(tc.pods)
|
||||
m.On("GetDevices", string(podUID), containerName).Return(tc.devices)
|
||||
m.On("UpdateAllocatedDevices").Return()
|
||||
server := NewPodResourcesServer(m, m)
|
||||
server := NewV1alpha1PodResourcesServer(m, m)
|
||||
resp, err := server.List(context.TODO(), &v1alpha1.ListPodResourcesRequest{})
|
||||
if err != nil {
|
||||
t.Errorf("want err = %v, got %q", nil, err)
|
33
pkg/kubelet/apis/podresources/types.go
Normal file
33
pkg/kubelet/apis/podresources/types.go
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
Copyright 2020 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package podresources
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/kubelet/pkg/apis/podresources/v1alpha1"
|
||||
)
|
||||
|
||||
// DevicesProvider knows how to provide the devices used by the given container
|
||||
type DevicesProvider interface {
|
||||
GetDevices(podUID, containerName string) []*v1alpha1.ContainerDevices
|
||||
UpdateAllocatedDevices()
|
||||
}
|
||||
|
||||
// PodsProvider knows how to provide the pods admitted by the node
|
||||
type PodsProvider interface {
|
||||
GetPods() []*v1.Pod
|
||||
}
|
@ -60,6 +60,8 @@ const (
|
||||
// Metrics keys of device plugin operations
|
||||
DevicePluginRegistrationCountKey = "device_plugin_registration_total"
|
||||
DevicePluginAllocationDurationKey = "device_plugin_alloc_duration_seconds"
|
||||
// Metrics keys of pod resources operations
|
||||
PodResourcesEndpointRequestsTotalKey = "pod_resources_endpoint_requests_total"
|
||||
|
||||
// Metric keys for node config
|
||||
AssignedConfigKey = "node_config_assigned"
|
||||
@ -277,6 +279,18 @@ var (
|
||||
[]string{"resource_name"},
|
||||
)
|
||||
|
||||
// PodResourcesEndpointRequestsTotalCount is a Counter that tracks the cumulative number of requests to the PodResource endpoints.
|
||||
// Broken down by server API version.
|
||||
PodResourcesEndpointRequestsTotalCount = metrics.NewCounterVec(
|
||||
&metrics.CounterOpts{
|
||||
Subsystem: KubeletSubsystem,
|
||||
Name: PodResourcesEndpointRequestsTotalKey,
|
||||
Help: "Cumulative number of requests to the PodResource endpoint. Broken down by server api version.",
|
||||
StabilityLevel: metrics.ALPHA,
|
||||
},
|
||||
[]string{"server_api_version"},
|
||||
)
|
||||
|
||||
// Metrics for node config
|
||||
|
||||
// AssignedConfig is a Gauge that is set 1 if the Kubelet has a NodeConfig assigned.
|
||||
|
@ -50,6 +50,7 @@ go_library(
|
||||
"//staging/src/k8s.io/component-base/logs:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/metrics:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/metrics/legacyregistry:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/podresources/v1:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/podresources/v1alpha1:go_default_library",
|
||||
"//vendor/github.com/emicklei/go-restful:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/container:go_default_library",
|
||||
|
@ -60,7 +60,8 @@ import (
|
||||
"k8s.io/component-base/logs"
|
||||
compbasemetrics "k8s.io/component-base/metrics"
|
||||
"k8s.io/component-base/metrics/legacyregistry"
|
||||
podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1alpha1"
|
||||
podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1"
|
||||
podresourcesapiv1alpha1 "k8s.io/kubelet/pkg/apis/podresources/v1alpha1"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/core/v1/validation"
|
||||
@ -180,7 +181,8 @@ func ListenAndServeKubeletReadOnlyServer(host HostInterface, resourceAnalyzer st
|
||||
// ListenAndServePodResources initializes a gRPC server to serve the PodResources service
|
||||
func ListenAndServePodResources(socket string, podsProvider podresources.PodsProvider, devicesProvider podresources.DevicesProvider) {
|
||||
server := grpc.NewServer()
|
||||
podresourcesapi.RegisterPodResourcesListerServer(server, podresources.NewPodResourcesServer(podsProvider, devicesProvider))
|
||||
podresourcesapiv1alpha1.RegisterPodResourcesListerServer(server, podresources.NewV1alpha1PodResourcesServer(podsProvider, devicesProvider))
|
||||
podresourcesapi.RegisterPodResourcesListerServer(server, podresources.NewV1PodResourcesServer(podsProvider, devicesProvider))
|
||||
l, err := util.CreateListener(socket)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed to create listener for podResources endpoint: %v", err)
|
||||
|
@ -15,6 +15,7 @@ filegroup(
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/pluginregistration/v1:all-srcs",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/pluginregistration/v1alpha1:all-srcs",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/pluginregistration/v1beta1:all-srcs",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/podresources/v1:all-srcs",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/podresources/v1alpha1:all-srcs",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/stats/v1alpha1:all-srcs",
|
||||
],
|
||||
|
30
staging/src/k8s.io/kubelet/pkg/apis/podresources/v1/BUILD
Normal file
30
staging/src/k8s.io/kubelet/pkg/apis/podresources/v1/BUILD
Normal file
@ -0,0 +1,30 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = ["api.pb.go"],
|
||||
importmap = "k8s.io/kubernetes/vendor/k8s.io/kubelet/pkg/apis/podresources/v1",
|
||||
importpath = "k8s.io/kubelet/pkg/apis/podresources/v1",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//vendor/github.com/gogo/protobuf/gogoproto:go_default_library",
|
||||
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
|
||||
"//vendor/google.golang.org/grpc:go_default_library",
|
||||
"//vendor/google.golang.org/grpc/codes:go_default_library",
|
||||
"//vendor/google.golang.org/grpc/status:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
1400
staging/src/k8s.io/kubelet/pkg/apis/podresources/v1/api.pb.go
Normal file
1400
staging/src/k8s.io/kubelet/pkg/apis/podresources/v1/api.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,48 @@
|
||||
// To regenerate api.pb.go run hack/update-generated-pod-resources.sh
|
||||
syntax = "proto3";
|
||||
|
||||
package v1;
|
||||
|
||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||
|
||||
option (gogoproto.goproto_stringer_all) = false;
|
||||
option (gogoproto.stringer_all) = true;
|
||||
option (gogoproto.goproto_getters_all) = true;
|
||||
option (gogoproto.marshaler_all) = true;
|
||||
option (gogoproto.sizer_all) = true;
|
||||
option (gogoproto.unmarshaler_all) = true;
|
||||
option (gogoproto.goproto_unrecognized_all) = false;
|
||||
|
||||
|
||||
// PodResourcesLister is a service provided by the kubelet that provides information about the
|
||||
// node resources consumed by pods and containers on the node
|
||||
service PodResourcesLister {
|
||||
rpc List(ListPodResourcesRequest) returns (ListPodResourcesResponse) {}
|
||||
}
|
||||
|
||||
// ListPodResourcesRequest is the request made to the PodResourcesLister service
|
||||
message ListPodResourcesRequest {}
|
||||
|
||||
// ListPodResourcesResponse is the response returned by List function
|
||||
message ListPodResourcesResponse {
|
||||
repeated PodResources pod_resources = 1;
|
||||
}
|
||||
|
||||
// PodResources contains information about the node resources assigned to a pod
|
||||
message PodResources {
|
||||
string name = 1;
|
||||
string namespace = 2;
|
||||
repeated ContainerResources containers = 3;
|
||||
}
|
||||
|
||||
// ContainerResources contains information about the resources assigned to a container
|
||||
message ContainerResources {
|
||||
string name = 1;
|
||||
repeated ContainerDevices devices = 2;
|
||||
}
|
||||
|
||||
// ContainerDevices contains information about the devices assigned to a container
|
||||
message ContainerDevices {
|
||||
string resource_name = 1;
|
||||
repeated string device_ids = 2;
|
||||
}
|
@ -47,6 +47,7 @@ go_library(
|
||||
"//staging/src/k8s.io/cri-api/pkg/apis:go_default_library",
|
||||
"//staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/config/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/podresources/v1:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/podresources/v1alpha1:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/stats/v1alpha1:go_default_library",
|
||||
"//test/e2e/common:go_default_library",
|
||||
@ -197,6 +198,7 @@ go_test(
|
||||
"//staging/src/k8s.io/component-base/metrics/testutil:go_default_library",
|
||||
"//staging/src/k8s.io/cri-api/pkg/apis:go_default_library",
|
||||
"//staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/podresources/v1:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/podresources/v1alpha1:go_default_library",
|
||||
"//staging/src/k8s.io/kubelet/pkg/apis/stats/v1alpha1:go_default_library",
|
||||
"//staging/src/k8s.io/mount-utils:go_default_library",
|
||||
|
@ -32,6 +32,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
kubeletpodresourcesv1 "k8s.io/kubelet/pkg/apis/podresources/v1"
|
||||
kubeletpodresourcesv1alpha1 "k8s.io/kubelet/pkg/apis/podresources/v1alpha1"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
|
||||
@ -157,25 +158,56 @@ func testDevicePlugin(f *framework.Framework, pluginSockDir string) {
|
||||
devID1 := parseLog(f, pod1.Name, pod1.Name, deviceIDRE)
|
||||
gomega.Expect(devID1).To(gomega.Not(gomega.Equal("")))
|
||||
|
||||
podResources, err := getNodeDevices()
|
||||
var resourcesForOurPod *kubeletpodresourcesv1alpha1.PodResources
|
||||
framework.Logf("pod resources %v", podResources)
|
||||
v1alphaPodResources, err := getV1alpha1NodeDevices()
|
||||
framework.ExpectNoError(err)
|
||||
framework.ExpectEqual(len(podResources.PodResources), 2)
|
||||
for _, res := range podResources.GetPodResources() {
|
||||
framework.Logf("v1alpha pod resources %v", v1alphaPodResources)
|
||||
|
||||
v1PodResources, err := getV1NodeDevices()
|
||||
framework.ExpectNoError(err)
|
||||
framework.Logf("v1 pod resources %v", v1PodResources)
|
||||
|
||||
framework.ExpectEqual(len(v1alphaPodResources.PodResources), 2)
|
||||
framework.ExpectEqual(len(v1PodResources.PodResources), 2)
|
||||
|
||||
var v1alphaResourcesForOurPod *kubeletpodresourcesv1alpha1.PodResources
|
||||
for _, res := range v1alphaPodResources.GetPodResources() {
|
||||
if res.Name == pod1.Name {
|
||||
resourcesForOurPod = res
|
||||
v1alphaResourcesForOurPod = res
|
||||
}
|
||||
}
|
||||
framework.Logf("resourcesForOurPod %v", resourcesForOurPod)
|
||||
gomega.Expect(resourcesForOurPod).NotTo(gomega.BeNil())
|
||||
framework.ExpectEqual(resourcesForOurPod.Name, pod1.Name)
|
||||
framework.ExpectEqual(resourcesForOurPod.Namespace, pod1.Namespace)
|
||||
framework.ExpectEqual(len(resourcesForOurPod.Containers), 1)
|
||||
framework.ExpectEqual(resourcesForOurPod.Containers[0].Name, pod1.Spec.Containers[0].Name)
|
||||
framework.ExpectEqual(len(resourcesForOurPod.Containers[0].Devices), 1)
|
||||
framework.ExpectEqual(resourcesForOurPod.Containers[0].Devices[0].ResourceName, resourceName)
|
||||
framework.ExpectEqual(len(resourcesForOurPod.Containers[0].Devices[0].DeviceIds), 1)
|
||||
framework.Logf("v1alphaResourcesForOurPod %v", v1alphaResourcesForOurPod)
|
||||
|
||||
var v1ResourcesForOurPod *kubeletpodresourcesv1.PodResources
|
||||
for _, res := range v1PodResources.GetPodResources() {
|
||||
if res.Name == pod1.Name {
|
||||
v1ResourcesForOurPod = res
|
||||
}
|
||||
}
|
||||
framework.Logf("v1ResourcesForOurPod %v", v1ResourcesForOurPod)
|
||||
|
||||
gomega.Expect(v1alphaResourcesForOurPod).NotTo(gomega.BeNil())
|
||||
gomega.Expect(v1ResourcesForOurPod).NotTo(gomega.BeNil())
|
||||
|
||||
framework.ExpectEqual(v1alphaResourcesForOurPod.Name, pod1.Name)
|
||||
framework.ExpectEqual(v1ResourcesForOurPod.Name, pod1.Name)
|
||||
|
||||
framework.ExpectEqual(v1alphaResourcesForOurPod.Namespace, pod1.Namespace)
|
||||
framework.ExpectEqual(v1ResourcesForOurPod.Namespace, pod1.Namespace)
|
||||
|
||||
framework.ExpectEqual(len(v1alphaResourcesForOurPod.Containers), 1)
|
||||
framework.ExpectEqual(len(v1ResourcesForOurPod.Containers), 1)
|
||||
|
||||
framework.ExpectEqual(v1alphaResourcesForOurPod.Containers[0].Name, pod1.Spec.Containers[0].Name)
|
||||
framework.ExpectEqual(v1ResourcesForOurPod.Containers[0].Name, pod1.Spec.Containers[0].Name)
|
||||
|
||||
framework.ExpectEqual(len(v1alphaResourcesForOurPod.Containers[0].Devices), 1)
|
||||
framework.ExpectEqual(len(v1ResourcesForOurPod.Containers[0].Devices), 1)
|
||||
|
||||
framework.ExpectEqual(v1alphaResourcesForOurPod.Containers[0].Devices[0].ResourceName, resourceName)
|
||||
framework.ExpectEqual(v1ResourcesForOurPod.Containers[0].Devices[0].ResourceName, resourceName)
|
||||
|
||||
framework.ExpectEqual(len(v1alphaResourcesForOurPod.Containers[0].Devices[0].DeviceIds), 1)
|
||||
framework.ExpectEqual(len(v1ResourcesForOurPod.Containers[0].Devices[0].DeviceIds), 1)
|
||||
|
||||
pod1, err = f.PodClient().Get(context.TODO(), pod1.Name, metav1.GetOptions{})
|
||||
framework.ExpectNoError(err)
|
||||
|
@ -38,6 +38,7 @@ import (
|
||||
internalapi "k8s.io/cri-api/pkg/apis"
|
||||
"k8s.io/klog/v2"
|
||||
kubeletconfigv1beta1 "k8s.io/kubelet/config/v1beta1"
|
||||
kubeletpodresourcesv1 "k8s.io/kubelet/pkg/apis/podresources/v1"
|
||||
kubeletpodresourcesv1alpha1 "k8s.io/kubelet/pkg/apis/podresources/v1alpha1"
|
||||
stats "k8s.io/kubelet/pkg/apis/stats/v1alpha1"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
@ -103,12 +104,12 @@ func getNodeSummary() (*stats.Summary, error) {
|
||||
return &summary, nil
|
||||
}
|
||||
|
||||
func getNodeDevices() (*kubeletpodresourcesv1alpha1.ListPodResourcesResponse, error) {
|
||||
func getV1alpha1NodeDevices() (*kubeletpodresourcesv1alpha1.ListPodResourcesResponse, error) {
|
||||
endpoint, err := util.LocalEndpoint(defaultPodResourcesPath, podresources.Socket)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting local endpoint: %v", err)
|
||||
}
|
||||
client, conn, err := podresources.GetClient(endpoint, defaultPodResourcesTimeout, defaultPodResourcesMaxSize)
|
||||
client, conn, err := podresources.GetV1alpha1Client(endpoint, defaultPodResourcesTimeout, defaultPodResourcesMaxSize)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting grpc client: %v", err)
|
||||
}
|
||||
@ -122,6 +123,25 @@ func getNodeDevices() (*kubeletpodresourcesv1alpha1.ListPodResourcesResponse, er
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func getV1NodeDevices() (*kubeletpodresourcesv1.ListPodResourcesResponse, error) {
|
||||
endpoint, err := util.LocalEndpoint(defaultPodResourcesPath, podresources.Socket)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting local endpoint: %v", err)
|
||||
}
|
||||
client, conn, err := podresources.GetV1Client(endpoint, defaultPodResourcesTimeout, defaultPodResourcesMaxSize)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error getting gRPC client: %v", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
resp, err := client.List(ctx, &kubeletpodresourcesv1.ListPodResourcesRequest{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v.Get(_) = _, %v", client, err)
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// Returns the current KubeletConfiguration
|
||||
func getCurrentKubeletConfig() (*kubeletconfig.KubeletConfiguration, error) {
|
||||
// namespace only relevant if useProxy==true, so we don't bother
|
||||
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
@ -2427,6 +2427,7 @@ k8s.io/kubectl/pkg/validation
|
||||
k8s.io/kubelet/config/v1beta1
|
||||
k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1
|
||||
k8s.io/kubelet/pkg/apis/pluginregistration/v1
|
||||
k8s.io/kubelet/pkg/apis/podresources/v1
|
||||
k8s.io/kubelet/pkg/apis/podresources/v1alpha1
|
||||
k8s.io/kubelet/pkg/apis/stats/v1alpha1
|
||||
# k8s.io/legacy-cloud-providers v0.0.0 => ./staging/src/k8s.io/legacy-cloud-providers
|
||||
|
Loading…
Reference in New Issue
Block a user