# DRA Driver for Edera Zones

## Overview

The DRA Driver for Edera Zones publishes Edera Zone capacity to the Kubernetes scheduler as first-class device resources, using the [Dynamic Resource Allocation (DRA)](https://kubernetes.io/docs/concepts/scheduling-eviction/dynamic-resource-allocation/) API. Pods request a Zone through a standard `ResourceClaim`, and the scheduler places them on a node that has Zone capacity available.

The driver runs as a DaemonSet on every node where you want Edera Zones to be schedulable. Each driver instance reports the local node’s available capacity, handles `NodePrepareResources` calls from the kubelet, and keeps the cluster view in sync as workloads come and go.

This is the Kubernetes-native counterpart to the [`protect` CLI for resource utilization](https://docs.edera.dev/guides/resource-utilization/). Where the CLI lets an operator inspect and adjust Zone resources by hand, the DRA driver makes those resources part of the scheduling decision.

## Terminology

This page uses the following terms:

- **Zone:** A security boundary that runs Kubernetes pods inside a virtual machine guest environment with a dedicated zone kernel, eliminating container escape, privilege escalation, and lateral movement attacks. See [Edera zones](https://docs.edera.dev/technical-overview/concepts/zone/).
- **DRA (Dynamic Resource Allocation):** A Kubernetes API for requesting, configuring, and sharing specialized hardware and software resources beyond the CPU and memory primitives. DRA reached general availability as `resource.k8s.io/v1` in Kubernetes 1.34.
- **DeviceClass:** A cluster-scoped DRA object that names a category of devices and the driver responsible for them. The driver ships an `edera-zone` DeviceClass that selects devices managed by `zone.edera.dev`.
- **ResourceSlice:** A per-node DRA object that advertises the devices a driver makes available on that node. The Edera driver publishes one ResourceSlice per node, listing the Zone devices currently available.
- **ResourceClaim / ResourceClaimTemplate:** The Pod-side request for a device. A Pod consumes a Zone by referencing a `ResourceClaimTemplate`; the scheduler binds the claim to a specific device on a specific node.

## Why DRA for Zones

The kubelet runs in Dom0. When Edera is installed on a node, Dom0 only has insight into the memory pool that has been explicitly granted to it; the remainder is reserved for zones. The kubelet cannot see, account for, or report on memory consumed by zones. From the kubelet’s perspective, a Pod that runs inside a zone is effectively free: it manages the Pod’s lifecycle, but the resource cost is levied somewhere the kubelet can neither observe nor track.

This accounting gap is memory-specific. Dom0 sees the node’s full CPU and storage capacity, and consumption against either is subtracted correctly. Memory is the resource that DRA needs to surface to the scheduler.

The practical consequence is that standard Kubernetes `requests`/`limits` cannot drive scheduling for zone-resident workloads. The scheduler has no signal that a node has run out of zone memory, and node-pressure eviction does not fire because nothing in cgroups reflects zone consumption.

DRA fills this gap. By modelling per-node zone capacity as a DRA device, the scheduler gains a first-class resource to bind against. Pods consuming the `edera-zone` DeviceClass go through `ResourceClaim` allocation—a parallel accounting path the kubelet does not need to participate in.

## How the driver works

### The DeviceClass

The chart installs a single cluster-scoped DeviceClass named `edera-zone`:

```yaml
apiVersion: resource.k8s.io/v1
kind: DeviceClass
metadata:
  name: edera-zone
spec:
  selectors:
  - cel:
      expression: device.driver == 'zone.edera.dev'
```

The selector matches any device whose driver is `zone.edera.dev`—the unique driver name the agent registers with the kubelet. A Pod consuming a Zone references this class through a `ResourceClaimTemplate`.

### The ResourceSlice

Each driver pod publishes a single `ResourceSlice` for its node. The slice lists the devices currently available on that node:

```yaml
apiVersion: resource.k8s.io/v1
kind: ResourceSlice
spec:
  driver: zone.edera.dev
  nodeName: <node-name>
  pool:
    generation: 1
    name: <node-name>
    resourceSliceCount: 1
  devices:
  - name: device-rc8f5
    attributes:
      version:
        string: v0.0.0
    capacity:
      memory:
        value: 4257772Ki
```

Each device represents one allocatable Zone. The device name is randomly generated and stable for the lifetime of the device—operators don’t choose it, and it persists across driver pod restarts.

### Allocation lifecycle

When a Pod with a `ResourceClaim` is scheduled to a node:

1. The scheduler binds the claim to a specific device in the node’s `ResourceSlice`.
2. The kubelet calls the driver’s `NodePrepareResources` gRPC method on the local plugin socket.
3. The driver records the claim against the device in its local ledger and tells the kubelet the device is ready.
4. The driver re-publishes the `ResourceSlice` with an additional unclaimed device that represents the node’s remaining Zone capacity.

When the Pod terminates, the kubelet calls `NodeUnprepareResources`, the driver releases the claim, and the slice is updated accordingly.

### Why a new device appears on each claim

Without the DRA “Consumable Capacity” feature, each device is a single allocation unit—one device, one claim. Consumable Capacity reached general availability in Kubernetes 1.36; the DRA Driver for Edera Zones does not yet use it.

In the meantime, the driver represents “the node still has Zone capacity available” by publishing an additional unclaimed device every time a claim is bound. The unclaimed device represents the node’s remaining capacity; the next Pod that lands on the node claims it, and the driver publishes another. Operators do not need to do anything for this to happen—it is an implementation detail.

Once the driver adopts `allowMultipleAllocations`, the per-claim re-publication will collapse into a single device per node with consumable capacity attributes. The DeviceClass and claim-side manifests will not change.

## Capacity semantics

The `capacity.memory` value published on each device represents Edera Zone capacity in a unit familiar to Kubernetes operators (`Ki`, `Mi`, `Gi`). The exact semantics—whether a claimed device’s value is a reservation, a snapshot, or a soft target—are documented separately and confirmed with the runtime team.

For scheduling purposes, treat `capacity.memory` as an indicator of available Zone capacity on the node at the time the device was published. Don’t treat it as a hard reservation enforced by the hypervisor.

## Configuration surface

A few configuration choices are worth understanding before deploying:

- **`minimumDeviceSize`** (default `315M`)—the driver does not publish an additional unclaimed device once the node’s free Zone capacity falls below this threshold. This prevents the driver from offering Zone devices that are too small to be useful. The default is an observed baseline from a minimal `busybox:stable` Pod and is not tuned for production workloads; adjust it based on the actual zone overhead of the Pods you intend to run.
- **DeviceClass scope.** The `edera-zone` DeviceClass is cluster-scoped. One installation of the chart per cluster is supported. Operators who need parallel DeviceClasses for different selectors can author their own DeviceClass objects targeting the same `zone.edera.dev` driver.

## Compatibility

- **Kubernetes:** 1.33 or later. The chart is capability-aware and selects between `resource.k8s.io/v1` (GA in 1.34), `v1beta2` (1.33), and `v1beta1` (1.32) based on what the cluster offers. The example manifests on this site use `resource.k8s.io/v1`; on earlier versions, substitute the appropriate API version.
- **Container runtime:** Nodes must be running the Edera runtime and have the `edera` RuntimeClass installed. The driver does not install or manage the runtime itself; see the [installation guides](https://docs.edera.dev/guides/install/) for runtime setup.
- **Node architecture:** Matches the Edera runtime support matrix.
