Merge pull request #92165 from RenaudWasTaken/v1-pod-resources

Graduate the Pod Resources API to G.A
This commit is contained in:
Kubernetes Prow Robot 2020-11-09 18:24:41 -08:00 committed by GitHub
commit 6e95025994
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 1879 additions and 56 deletions

View File

@ -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}"

View File

@ -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`.

View File

@ -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

View File

@ -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",
],

View File

@ -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
}

View 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
}

View 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())
}
})
}
}

View File

@ -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()

View File

@ -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)

View 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
}

View File

@ -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.

View File

@ -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",

View File

@ -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)

View File

@ -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",
],

View 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"],
)

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View File

@ -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",

View File

@ -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)

View File

@ -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
View File

@ -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