Skip to content

DRA driver skeleton - #788

Open
bart0sh wants to merge 3 commits into
containers:mainfrom
bart0sh:PR003-dra-driver-skeleton
Open

bart0sh wants to merge 3 commits into
containers:mainfrom
bart0sh:PR003-dra-driver-skeleton

Conversation

@bart0sh

@bart0sh bart0sh commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Add a DRA driver skeleton to the resource manager

This PR adds DRA driver - registration, ResourceSlice publishing and the two claim entry points — and wires it into the resource manager behind a dra.enabled configuration option that defaults to off. No policy publishes devices yet, so with this PR alone an enabled driver registers and publishes an empty ResourceSlice. Policies get to say what they provide in the PRs that follow.

Why the driver belongs to the resource manager

The driver is node-scoped infrastructure: one plugin registration, one socket, one ResourceSlice publisher per node, all of which outlive any particular allocation decision. Device semantics — what a device is, which ones exist,
what allocating one means — belong to the active policy. So pkg/resmgr/dra knows how to be a DRA driver and nothing about CPUs, memory or cache; it never inspects a device's attributes. The package comment states that boundary, and the tests assert it.

What is here

  • pkg/resmgr/dra — the plugin: New, Start, an idempotent Stop, and PrepareResourceClaims/UnprepareResourceClaims. Built on k8s.io/dynamic-resource-allocation/kubeletplugin.
  • dra.enabled in the common resource manager configuration, exposed by all three policy CRDs. "Common" here means the resource manager reads the switch from one place because it owns the driver — each policy CRD still carries its own spec.dra.enabled, so DRA is enabled per policy (and per node group, via the usual config CR layering), not cluster-wide.
  • resource manager wiring: setupDRA/startDRA from start(), Stop() from shutdown.
  • Helm: the resource.k8s.io/resourceslices RBAC and the kubelet plugin and plugin-registry host mounts, in all three charts, gated on config.dra.enabled so a disabled deployment renders exactly as before.

Details worth a reviewer's attention

The driver is named after the active policytopology-aware.nri.io. The published devices are the policy's, so a node running a different policy publishes devices of a different kind, and a DeviceClass selecting on device.driver stays specific without further qualification. The cost is that switching a node's policy orphans the old driver's ResourceSlices until the node object goes away.

The plugin takes the resource manager's lock directly. dra.Options has a sync.Locker, and the resource manager passes itself: it embeds sync.RWMutex already. Every kubelet request takes that lock, which serializes claim handling against NRI request handling.

Stop() stops the plugin before taking the lock. Helper.Stop() drains the gRPC handlers in flight, and a handler arriving mid-drain blocks on the lock, so stopping the plugin under the lock deadlocks. There is a test for the ordering,
not just a comment: it starts a real plugin against a fake clientset, holds the lock to stand in for a request being served, and waits for the plugin's socket to disappear.

Turning DRA on or off at runtime is refused, with a message asking for a restart. Both directions have to happen with the lock released, and reconfiguration holds it.

Missing cluster access degrades rather than fails. A plugin configured from a local file has no kubernetes client and no node name; enabling DRA there logs a warning and leaves DRA off instead of refusing to start.

Testing

go test ./... passes. Unit tests cover the plugin (registration, double start, idempotent stop, both claim entry points, and the boundary property that device attributes are never read), the configuration option across all three policy types, and the resource manager wiring including the shutdown ordering. helm template and helm lint verified on all three charts with DRA both enabled and disabled.

An end-to-end test arrives with the policy-side implementation, and will skip cleanly on clusters without the required feature gates.

Add the kubelet-facing side of a DRA driver: registration, the gRPC
lifecycle, and publishing a single empty ResourceSlice so the driver is
visible in the cluster. Claims are answered with empty results for now,
under a lock provided by the owner, so kubelet requests serialize
against NRI ones.

Signed-off-by: Ed Bartosh <eduard.bartosh@intel.com>
Add a DRA section to the common resource manager configuration, with a
single option for turning the DRA driver on. It defaults to off, so
existing deployments register no driver and publish no ResourceSlices.

Signed-off-by: Ed Bartosh <eduard.bartosh@intel.com>
@bart0sh
bart0sh force-pushed the PR003-dra-driver-skeleton branch from 8abfa6f to 70f2a87 Compare September 15, 2026 15:31
@bart0sh
bart0sh marked this pull request as ready for review September 15, 2026 16:00
@bart0sh

bart0sh commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

/cc @klihub @askervin

@klihub
klihub requested review from askervin and klihub September 15, 2026 16:14
// DRAConfig provides configuration data for the DRA (Dynamic Resource
// Allocation) driver. The driver is owned by the resource manager, not by a
// policy, so this is common configuration for all policies.
type DRAConfig struct {

@klihub klihub Sep 15, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I wonder if this should go under pkg/apis/config/v1alpha1/resmgr/dra (mirroring where the driver skeleton itself lives which IIUC this is the configuration for), for consistency with our other stuff. I think this might have been modelled after AgentConfig, which I suspect is one of the existing inconsistencies. Not entirely sure though ATM, and not insisting on this at all. Just something that caught my eye so I thought I should mention it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, sorry. I think I was clearly wrong. That's the DRA skeleton, but this configures stuff in pkg/resmgr/dra.go. This is in the right place then I think.

@klihub klihub left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bart0sh I did a first skim through and I haven't spotted anything off. I'll do one more with more fresh eyes tomorrow.

Create and start the kubelet plugin from the resource manager, passing
it the resource manager's lock so kubelet requests serialize against
NRI ones. Enabling or disabling DRA needs a restart. Add the RBAC and
host mounts the driver needs to the helm charts.

Signed-off-by: Ed Bartosh <eduard.bartosh@intel.com>
@@ -223,6 +233,10 @@ func (m *resmgr) start(cfg cfgapi.ResmgrConfig) error {
func (m *resmgr) Stop() {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@klihub This function is not called anywhere as far as I can see. It's not related to this PR, but we may want to either remove it if it's not needed or call it when resource manager is stopped.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bart0sh Looking at how fairly plain it is, let's just get rid of it, if it is unused.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bart0sh, I ran into that, too, when looking for a spot for clearing published extended resources.

Discussion about such clean-ups finally produced this open issue:

#709

but based on @marquiz's advice, I finally gave up whole idea of trying to clear published resources on highly unreliable plugin exit handlers. Instead of following plugin pod/container life cycle, extended resource (un)publishing follows reconciliation model: if the desired state expressed in most recent configuration is "don't publish", and if the plugin notices resources being published anyway, then it clears them.

@bart0sh bart0sh Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@askervin Having some cleanup capabilities is not mandatory, but it's not a bad thing either. Can we simply catch SIGTERM or/and other signals and call resmgr.Stop in the signal handler? Did you try this approach?
Anyway, this is not part of DRA, so I'll leave this code here. If we decide to remove it, it would be better to do it in another PR.

@bart0sh
bart0sh force-pushed the PR003-dra-driver-skeleton branch from 70f2a87 to 5cea989 Compare September 16, 2026 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants