Using device plugins to access external resources with pods

Device plugins allow you to use a particular device type (GPU, InfiniBand, or other similar computing resources that require vendor-specific initialization and setup) in your OKD pod without needing to write custom code.

Understanding device plugins

The device plugin provides a consistent and portable solution to consume hardware devices across clusters. The device plugin provides support for these devices through an extension mechanism, which makes these devices available to Containers, provides health checks of these devices, and securely shares them.

OKD supports the device plugin API, but the device plugin Containers are supported by individual vendors.

A device plugin is a gRPC service running on the nodes (external to the kubelet) that is responsible for managing specific hardware resources. Any device plugin must support following remote procedure calls (RPCs):

  1. service DevicePlugin {
  2. // GetDevicePluginOptions returns options to be communicated with Device
  3. // Manager
  4. rpc GetDevicePluginOptions(Empty) returns (DevicePluginOptions) {}
  5. // ListAndWatch returns a stream of List of Devices
  6. // Whenever a Device state change or a Device disappears, ListAndWatch
  7. // returns the new list
  8. rpc ListAndWatch(Empty) returns (stream ListAndWatchResponse) {}
  9. // Allocate is called during container creation so that the Device
  10. // Plug-in can run device specific operations and instruct Kubelet
  11. // of the steps to make the Device available in the container
  12. rpc Allocate(AllocateRequest) returns (AllocateResponse) {}
  13. // PreStartcontainer is called, if indicated by Device Plug-in during
  14. // registration phase, before each container start. Device plug-in
  15. // can run device specific operations such as resetting the device
  16. // before making devices available to the container
  17. rpc PreStartcontainer(PreStartcontainerRequest) returns (PreStartcontainerResponse) {}
  18. }

Example device plugins

For easy device plugin reference implementation, there is a stub device plugin in the Device Manager code: vendor/k8s.io/kubernetes/pkg/kubelet/cm/deviceplugin/device_plugin_stub.go.

Methods for deploying a device plugin

  • Daemon sets are the recommended approach for device plugin deployments.

  • Upon start, the device plugin will try to create a UNIX domain socket at /var/lib/kubelet/device-plugin/ on the node to serve RPCs from Device Manager.

  • Since device plugins must manage hardware resources, access to the host file system, as well as socket creation, they must be run in a privileged security context.

  • More specific details regarding deployment steps can be found with each device plugin implementation.

Understanding the Device Manager

Device Manager provides a mechanism for advertising specialized node hardware resources with the help of plugins known as device plugins.

You can advertise specialized hardware without requiring any upstream code changes.

OKD supports the device plugin API, but the device plugin Containers are supported by individual vendors.

Device Manager advertises devices as Extended Resources. User pods can consume devices, advertised by Device Manager, using the same Limit/Request mechanism, which is used for requesting any other Extended Resource.

Upon start, the device plugin registers itself with Device Manager invoking Register on the /var/lib/kubelet/device-plugins/kubelet.sock and starts a gRPC service at /var/lib/kubelet/device-plugins/<plugin>.sock for serving Device Manager requests.

Device Manager, while processing a new registration request, invokes ListAndWatch remote procedure call (RPC) at the device plugin service. In response, Device Manager gets a list of Device objects from the plugin over a gRPC stream. Device Manager will keep watching on the stream for new updates from the plugin. On the plugin side, the plugin will also keep the stream open and whenever there is a change in the state of any of the devices, a new device list is sent to the Device Manager over the same streaming connection.

While handling a new pod admission request, Kubelet passes requested Extended Resources to the Device Manager for device allocation. Device Manager checks in its database to verify if a corresponding plugin exists or not. If the plugin exists and there are free allocatable devices as well as per local cache, Allocate RPC is invoked at that particular device plugin.

Additionally, device plugins can also perform several other device-specific operations, such as driver installation, device initialization, and device resets. These functionalities vary from implementation to implementation.

Enabling Device Manager

Enable Device Manager to implement a device plugin to advertise specialized hardware without any upstream code changes.

Device Manager provides a mechanism for advertising specialized node hardware resources with the help of plugins known as device plugins.

  1. Obtain the label associated with the static MachineConfigPool CRD for the type of node you want to configure by entering the following command. Perform one of the following steps:

    1. View the machine config:

      1. # oc describe machineconfig <name>

      For example:

      1. # oc describe machineconfig 00-worker

      Example output

      1. Name: 00-worker
      2. Namespace:
      3. Labels: machineconfiguration.openshift.io/role=worker (1)
      1Label required for the Device Manager.

Procedure

  1. Create a custom resource (CR) for your configuration change.

    Sample configuration for a Device Manager CR

    1. apiVersion: machineconfiguration.openshift.io/v1
    2. kind: KubeletConfig
    3. metadata:
    4. name: devicemgr (1)
    5. spec:
    6. machineConfigPoolSelector:
    7. matchLabels:
    8. machineconfiguration.openshift.io: devicemgr (2)
    9. kubeletConfig:
    10. feature-gates:
    11. - DevicePlugins=true (3)
    1Assign a name to CR.
    2Enter the label from the Machine Config Pool.
    3Set DevicePlugins to ‘true`.
  2. Create the Device Manager:

    1. $ oc create -f devicemgr.yaml

    Example output

    1. kubeletconfig.machineconfiguration.openshift.io/devicemgr created
  3. Ensure that Device Manager was actually enabled by confirming that /var/lib/kubelet/device-plugins/kubelet.sock is created on the node. This is the UNIX domain socket on which the Device Manager gRPC server listens for new plugin registrations. This sock file is created when the Kubelet is started only if Device Manager is enabled.