From c440246966db1320862cbf17a624436405d6bafd Mon Sep 17 00:00:00 2001 From: Renaud Gaubert Date: Fri, 11 Aug 2017 16:43:10 -0700 Subject: [PATCH] Added Device plugin API Signed-off-by: Renaud Gaubert --- hack/.golint_failures | 1 + .../apis/deviceplugin/v1alpha1/api.proto | 127 ++++++++++++++++++ .../apis/deviceplugin/v1alpha1/constants.go | 33 +++++ 3 files changed, 161 insertions(+) create mode 100644 pkg/kubelet/apis/deviceplugin/v1alpha1/api.proto create mode 100644 pkg/kubelet/apis/deviceplugin/v1alpha1/constants.go diff --git a/hack/.golint_failures b/hack/.golint_failures index d6e06a7d23..835883837d 100644 --- a/hack/.golint_failures +++ b/hack/.golint_failures @@ -233,6 +233,7 @@ pkg/kubelet pkg/kubelet/apis pkg/kubelet/apis/cri/testing pkg/kubelet/apis/cri/v1alpha1/runtime +pkg/kubelet/apis/deviceplugin/v1alpha1 pkg/kubelet/apis/kubeletconfig pkg/kubelet/apis/kubeletconfig/v1alpha1 pkg/kubelet/cadvisor diff --git a/pkg/kubelet/apis/deviceplugin/v1alpha1/api.proto b/pkg/kubelet/apis/deviceplugin/v1alpha1/api.proto new file mode 100644 index 0000000000..e222d14a76 --- /dev/null +++ b/pkg/kubelet/apis/deviceplugin/v1alpha1/api.proto @@ -0,0 +1,127 @@ +// To regenerate api.pb.go run hack/update-device-plugin.sh +syntax = 'proto3'; + +package deviceplugin; + +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; + + +// Registration is the service advertised by the Kubelet +// Only when Kubelet answers with a success code to a Register Request +// may Device Plugins start their service +// Registration may fail when device plugin version is not supported by +// Kubelet or the registered resourceName is already taken by another +// active device plugin. Device plugin is expected to terminate upon registration failure +service Registration { + rpc Register(RegisterRequest) returns (Empty) {} +} + +message RegisterRequest { + // Version of the API the Device Plugin was built against + string version = 1; + // Name of the unix socket the device plugin is listening on + // PATH = path.Join(DevicePluginPath, endpoint) + string endpoint = 2; + // Schedulable resource name. As of now it's expected to be a DNS Label + string resource_name = 3; +} + +message Empty { +} + +// DevicePlugin is the service advertised by Device Plugins +service DevicePlugin { + // ListAndWatch returns a stream of List of Devices + // Whenever a Device state change or a Device disapears, ListAndWatch + // returns the new list + rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {} + + // Allocate is called during container creation so that the Device + // Plugin can run device specific operations and instruct Kubelet + // of the steps to make the Device available in the container + rpc Allocate(AllocateRequest) returns (AllocateResponse) {} +} + +// ListAndWatch returns a stream of List of Devices +// Whenever a Device state change or a Device disapears, ListAndWatch +// returns the new list +message ListAndWatchResponse { + repeated Device devices = 1; +} + +/* E.g: +* struct Device { +* ID: "GPU-fef8089b-4820-abfc-e83e-94318197576e", +* State: "Healthy", +*} */ +message Device { + // A unique ID assigned by the device plugin used + // to identify devices during the communication + // Max length of this field is 63 characters + string ID = 1; + // Health of the device, can be healthy or unhealthy, see constants.go + string health = 2; +} + +// - Allocate is expected to be called during pod creation since allocation +// failures for any container would result in pod startup failure. +// - Allocate allows kubelet to exposes additional artifacts in a pod's +// environment as directed by the plugin. +// - Allocate allows Device Plugin to run device specific operations on +// the Devices requested +message AllocateRequest { + repeated string devicesIDs = 1; +} + +// Failure Handling: +// if Kubelet sends an allocation request for dev1 and dev2. +// Allocation on dev1 succeeds but allocation on dev2 fails. +// The Device plugin should send a ListAndWatch update and fail the +// Allocation request +message AllocateResponse { + repeated DeviceRuntimeSpec spec = 1; +} + +// The list to be added to the CRI spec +message DeviceRuntimeSpec { + // ID of the Device + string ID = 1; + // List of environment variable to set in the container. + map envs = 2; + // Mounts for the container. + repeated Mount mounts = 3; + // Devices for the container + repeated DeviceSpec devices = 4; +} + +// Mount specifies a host volume to mount into a container. +// where device library or tools are installed on host and container +message Mount { + // Path of the mount within the container. + string container_path = 1; + // Path of the mount on the host. + string host_path = 2; + // If set, the mount is read-only. + bool read_only = 3; +} + +// DeviceSpec specifies a host device to mount into a container. +message DeviceSpec { + // Path of the device within the container. + string container_path = 1; + // Path of the device on the host. + string host_path = 2; + // Cgroups permissions of the device, candidates are one or more of + // * r - allows container to read from the specified device. + // * w - allows container to write to the specified device. + // * m - allows container to create device files that do not yet exist. + string permissions = 3; +} diff --git a/pkg/kubelet/apis/deviceplugin/v1alpha1/constants.go b/pkg/kubelet/apis/deviceplugin/v1alpha1/constants.go new file mode 100644 index 0000000000..fb0440cce5 --- /dev/null +++ b/pkg/kubelet/apis/deviceplugin/v1alpha1/constants.go @@ -0,0 +1,33 @@ +/* +Copyright 2017 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 deviceplugin + +const ( + // Healthy means that the device is healty + Healthy = "Healthy" + // UnHealthy means that the device is unhealty + Unhealthy = "Unhealthy" + + // Version is the API version + Version = "0.1" + // DevicePluginPath is the folder the Device Plugin is expecting sockets to be on + // Only privileged pods have access to this path + // Note: Placeholder until we find a "standard path" + DevicePluginPath = "/var/lib/kubelet/device-plugins/" + // KubeletSocket is the path of the Kubelet registry socket + KubeletSocket = DevicePluginPath + "kubelet.sock" +)