SR-IOV plumbing: device plugin, CNI and operator
S2·E2The NAD that set a priority and no VLAN · A 7 a.m. call, day two of acceptance week
Builds on: How kubelet learns a NIC exists
Before you read: what do you already know?
3 quick questions. Wrong answers are fine and expected; trying first makes the lesson stick.
After this lesson you can
- Write an sriov-network-device-plugin resourceList that advertises ConnectX VFs under a chosen prefix.
- Configure an SR-IOV CNI delegate with the fields the reference marks required and validate the optional ones against their allowed ranges.
- Map each of the four SR-IOV Network Operator CRDs to the question it answers.
- Predict whether a given ConfigMap and pod spec pair will schedule and name the evidence that proves it.
Episode 2 — The NAD that set a priority and no VLAN
The prefix is fixed and the pods schedule now, which is progress you get to enjoy for about eleven hours. At seven the next morning every pod on the fast network is failing during attachment, and the customer’s platform engineer is back to suspecting the cards. They are not the problem: these pods reached CNI at all, which already proves the name matched and the scheduler placed them.
You read the delegate config back over the call. type: sriov, no vlan key, vlanQoS: 3. The reference is exact about that pair - vlanQoS must be in the range 0-7, and “This option requires vlan field to be set to a non-zero value. Otherwise, the error will be returned.”[3] A priority was set on a function with no VLAN to carry it, and the plugin refuses rather than guess.
The mistake sits on a seam, and the seam is why this plumbing exists at all. Counting hardware and attaching it are different jobs with different owners: the device plugin decides which function a pod gets, and the CNI only configures the one it is handed - “A metaplugin such as Multus gets the allocated VF’s deviceID (PCI address) and is responsible for invoking the SR-IOV CNI plugin with that deviceID.”[2] Two owners, two vocabularies, one hand-written file that mixed them.
Optional in the reference does not mean independent - check every field against the rule printed next to it.
Segment 1 starts where the name is minted: the device-plugin ConfigMap.
1Three programs, three jobs
SR-IOV in Kubernetes is not one component. It is three, and every escalation gets easier once you can say which one owns the symptom.
The device plugin counts. “The SR-IOV Network Device Plugin is Kubernetes device plugin for discovering and advertising networking resources”, covering SR-IOV VFs, PCI PFs and auxiliary network devices.[1] It turns hardware into a schedulable integer under a name it chooses.
The CNI attaches. “This plugin enables the configuration and usage of SR-IOV VF networks in containers and orchestrators like Kubernetes.”[2] Crucially it does not choose a VF: “A metaplugin such as Multus gets the allocated VF’s deviceID (PCI address) and is responsible for invoking the SR-IOV CNI plugin with that deviceID.”[2]
The operator configures the node. “The SR-IOV Network Operator simplifies the deployment and management of SR-IOV networking in Kubernetes and OpenShift clusters”, and it is what creates VFs and generates the network definitions rather than leaving you to hand-write them.[4]
The sequence is fixed: advertise, schedule, delegate, attach. Multus only reads the k8s.v1.cni.cncf.io/networks annotation after the pod is placed, and the delegate only runs after Multus resolves the NetworkAttachmentDefinition.[8] Everything downstream of scheduling is invisible while a pod is Pending - which is the whole reason the last segment of this lesson exists.
Without the operator the same path still works; you just write more YAML. NVIDIA’s older bare-metal Ethernet page shows exactly that shape: resource name nvidia.com/mlnx_sriov_netdevice with a hand-written NAD whose plugins array holds {"type":"sriov", ...}.[9] Keep that example in mind as the “what the operator is doing for you” reference.
Checks
no forbidden combination- warnNo {"type":"rdma"} in the chain: the pod gets the VF netdev, but the RDMA device stays in the host namespace — no per-pod isolation. NVIDIA’s IB example chains it: [{"type":"ib-sriov",…},{"type":"rdma"}]. [rdma-cni is what moves the RDMA interface into the pod netns]
- warnresourceName must match a name the device plugin advertised, prefix included: sriov-network-device-plugin defaults to intel.com, the Network Operator writes nvidia.com, OpenShift writes openshift.io. A mismatch keeps the pod Pending with no CNI error at all (kubectl describe node | grep -A20 Allocatable). deviceID is never hand-written — Multus passes the allocated VF. [resourcePrefix default is intel.com]
- infoCalico owns eth0 only. Confirm it has not autodetected ens1f0 as its uplink: sharing one interface with the fast path works until Felix reconfigures it, and then RDMA disappears. [primary CNI must not claim the fast-path interface]
Delegate — sriov
Slices a PF into VFs. Multus gets the allocated VF’s deviceID from the device plugin and invokes sriov with it.
- deviceID is required — a valid PCI address of an SR-IOV NIC’s VF, e.g. "0000:03:02.3". Do not hand-write it: Multus passes the allocated VF.
- vlan 0–4094, vlanQoS 0–7, vlanProto default "802.1q" (or "802.1ad"), mac, spoofchk on/off, trust on/off, link_state auto|enable|disable, min_tx_rate / max_tx_rate in Mbps.
- The DHCP IPAM plugin cannot be used for a VF bound to a DPDK driver (uio/vfio).
- Device-plugin side: resourceList entries take resourceName (required), resourcePrefix, deviceType (netDevice default, accelerator, auxNetDevice) and selectors (vendors, devices, drivers, pciAddresses, pfNames, rootDevices, linkTypes, isRdma).
- Operator route: SriovNetwork (SR-IOV Network Operator) generates the NAD from a resourceName; SriovNetworkNodePolicy creates the VFs.
FAE angle: the pod also gets PCIDEVICE_<RESOURCE_NAME> and PCIDEVICE_<RESOURCE_NAME>_INFO env vars (upper-cased, "." and "/" → "_") — the fastest in-pod proof that the VF was really allocated.
sourceapiVersion: k8s.cni.cncf.io/v1
kind: NetworkAttachmentDefinition
metadata:
name: sriov-net
namespace: default
annotations:
k8s.v1.cni.cncf.io/resourceName: nvidia.com/mlnx_sriov_netdevice
spec:
config: |
{
"cniVersion": "0.3.1",
"name": "sriov-net",
"type": "sriov",
"vlan": 100,
"spoofchk": "off",
"trust": "on",
"link_state": "enable",
"ipam": {
"type": "whereabouts",
"range": "192.168.2.225/28",
"exclude": [
"192.168.2.229/30",
"192.168.2.236/32"
]
}
}⚠ The annotation key spelling k8s.v1.cni.cncf.io/resourceName is not quoted on the pages fetched for this course; the rule that a NAD resourceName must match an advertised device-plugin resource is.
Documented bare-metal Ethernet example name; the real name is whatever your device plugin resourceList advertised.
2The device-plugin ConfigMap, field by field
The config is a resourceList of pools. Each pool has resourceName (required), resourcePrefix (optional), deviceType (optional), selectors (an object or a list) and additionalInfo (which adds environment variables).[1]
resourcePrefix defaults to intel.com.[1] That single default is why NVIDIA’s own configuration always sets it explicitly: the operator’s sriovDevicePlugin block uses resourcePrefix: nvidia.com with resourceName: hostdev and selectors: {vendors: ["15b3"], isRdma: true}, producing nvidia.com/hostdev.[5]
deviceType takes netDevice (the default), accelerator or auxNetDevice.[1] The netDevice selectors are vendors, devices, drivers, pciAddresses, acpiIndexes, pfNames, rootDevices, linkTypes, ddpProfiles, pKeys, isRdma, needVhostNet and vdpaType.[1] An auxNetDevice pool takes a narrower set that adds auxTypes.[1]
Two of those selectors carry most of the meaning for an NVIDIA fleet. vendors: ["15b3"] is the NVIDIA/Mellanox PCI vendor ID, and isRdma: true restricts the pool to devices that can carry RDMA.[5]
What the pod sees is the other half of the contract. The plugin injects PCIDEVICE_<RESOURCE_NAME> with the comma-separated device IDs and PCIDEVICE_<RESOURCE_NAME>_INFO with JSON holding mount points and metadata; the resource name is upper-cased with . and / replaced by underscores.[1] That is your in-pod proof of which VF you got.
{ "resourceList": [{
"resourcePrefix": "nvidia.com",
"resourceName": "hostdev",
"selectors": { "vendors": ["15b3"], "isRdma": true }
}]}3The SR-IOV CNI delegate and its ranges
The delegate config is small and almost entirely optional. name and type ("sriov") are required, ipam is optional, and deviceID is required - “A valid pci address of an SRIOV NIC’s VF”, for example "0000:03:02.3".[3]
The optional fields are where a hand-written NAD goes wrong, so learn the ranges rather than the list:
| Field | Type | Rule |
|---|---|---|
vlan |
int | “Value must be in the range 0-4094 (0 for disabled, 1-4094 for valid VLAN IDs)”[3] |
vlanQoS |
int | “Value must be in the range 0-7”; “This option requires vlan field to be set to a non-zero value. Otherwise, the error will be returned.”[3] |
vlanProto |
string | default "802.1q"; may be "802.1ad"[3] |
mac |
string | optional administrative MAC[3] |
spoofchk |
string | "on" or "off"[3] |
trust |
string | "on" or "off"[3] |
link_state |
string | auto, enable or disable[3] |
min_tx_rate / max_tx_rate |
int | in Mbps[3] |
logLevel |
string | default info; panic, error, warning, info, debug[3] |
logFile |
string | default stderr[3] |
One documented incompatibility is worth memorising because it produces a pod with an interface and no address: “DHCP IPAM plugin can not be used for VF bound to a dpdk driver (uio/vfio).”[2] If the customer moved a VF to vfio-pci for a VM and left a DHCP IPAM block in the NAD, that is the bug, and lesson 5 covers why the VF was moved in the first place.
- The scheduler compares the pod request against node allocatable. Nothing on this node advertises intel.com/hostdev, so no node fits and the pod is never bound.
- This is silent: there is no CNI error, no container log, no event from Multus — the pod simply stays Pending forever.
4. Verdict — what kubectl shows
FAE angle: the fastest split is which side failed. Pending means the scheduler never found the name — a device-plugin or request problem. ContainerCreating means the name was allocatable and the NAD is wrong. Collect kubectl netop-sosreport --verbose --log-lines 10000 before you change anything: it captures the previous-container logs you are about to destroy.
kubectl describe pod sriov-test | tail -n 5 Warning FailedScheduling … 0/3 nodes are available: 3 Insufficient intel.com/hostdev.
The quoted fragment to look for is "Insufficient <resource name>".
⚠ Wording reconstructed — the exact event sentence is not captured verbatim in this course's sources.
kubectl describe node dell-r760-01 | grep -A20 Allocatable nvidia.com/hostdev: 8 # intel.com/hostdev is not in this list
Extended resources are integer-only, not overcommittable, and cannot be shared between containers.
ls -l /var/lib/kubelet/device-plugins/ kubelet.sock sriovdp.sock
The registration socket path /var/lib/kubelet/device-plugins/kubelet.sock is hardcoded. No plugin socket means the plugin never registered and nothing is advertised at all.
# NicClusterPolicy .spec.sriovDevicePlugin.config
{ "resourceList": [{
"resourcePrefix": "nvidia.com",
"resourceName": "hostdev",
"selectors": { "vendors": ["15b3"], "isRdma": true }
}]}nvidia.com/hostdev · allocatable 8- NVIDIA pod examples request nvidia.com/hostdev: 1 in both requests and limits, with securityContext.capabilities.add: ["IPC_LOCK"].
- The GPUDirect RDMA example requests nvidia.com/hostdev: 1 and nvidia.com/gpu: 1 in the same container, so both hint providers vote for NUMA alignment.
- HostDeviceNetwork carries the same name in its own resourceName field and generates the NAD for you.
FAE angle. Most escalations are a runbook written for one of these four sources being applied to a cluster configured by another. Ask who wrote the ConfigMap before you read any YAML.
Network Operator — Deployment Guide (Kubernetes) · Kubernetes device plugins · Multus how-to · netop-sosreportSame name, two other routes
vfio-pci for VMs. A SriovNetworkNodePolicy with deviceType: vfio-pci, numVfs: 8, nicSelector.vendor "15b3", pfNames [ens1f0] and deliberately isRdma: false. The VF is passed into the guest through the VFIO userspace interface, so the guest needs mlx5_core and the host needs intel_iommu=on iommu=pt (or amd_iommu=on iommu=pt). The resource-name mechanics are identical: the SriovNetwork references the same resourceName and generates the NAD.
DRA SR-IOV driver (Tech Preview). Dynamic Resource Allocation replaces the plain name match with a ResourceClaimTemplate: deviceClassName sriovnetwork.k8snetworkplumbingwg.io plus a CEL expression device.attributes["k8s.cni.cncf.io"].resourceName == "nvidia.com/sriov_resource". Devices are published as ResourceSlice objects carrying PCIe bus ID, NUMA node and vendor. Needs the dynamicResourceAllocation: true feature gate, is vanilla Kubernetes only (not OpenShift), and is not recommended for production.
4The operator: four CRDs and one privileged namespace
The SR-IOV Network Operator exposes four primary CRDs, and each answers a different question.[4]
SriovNetworkNodePolicy- what hardware should this node group present? Its example fields aredeviceType(for examplenetdevice),nicSelector.pfName,nodeSelector,numVfsandresourceName.[4]SriovNetwork- what network do workloads attach to? It generates the NetworkAttachmentDefinition for you.[4]SriovNetworkNodeState- what did the operator actually find? Read-only discovered hardware state.[4]SriovOperatorConfig- global settings.[4]
OVSNetwork and SriovIBNetwork exist alongside them for OVS-offloaded and InfiniBand attachments.[4]
Install is a Helm chart from oci://ghcr.io/k8snetworkplumbingwg/sriov-network-operator-chart, and the namespace must carry pod-security.kubernetes.io/enforce=privileged.[4] The repo states a base requirement of “Kubernetes 1.30+ or OpenShift 4.16+”.[4] In an NVIDIA deployment you normally do not install it separately: the Network Operator chart enables it with --set sriovNetworkOperator.enabled=true, and you verify with kubectl -n nvidia-network-operator get pods.[7]
Two platform-specific adjustments are documented. On OpenShift the config daemon must be kept out of the DOCA driver’s way with a configDaemonNodeSelector patch that includes network.nvidia.com/operator.mofed.wait: "false", and SR-IOV resources use the openshift.io prefix rather than a custom one.[6] In Spectrum-X deployments the operator is passed disablePlugins: [mellanox] plus featureGates: {manageSoftwareBridges: true}, because otherwise its built-in mellanox plugin and the NIC Configuration Operator fight over the same firmware settings.[11]
One honest gap: the repo’s landing page does not state the operator’s node-draining default, and it defers its feature-gate list to separate documents.[4] In Network Operator deployments the Maintenance Operator is the documented drain path, so do not promise a customer standalone drain behaviour you have not read.
5Where numVfs really lives
numVfs appears in two different places and they are not the same knob. In SriovNetworkNodePolicy it is a request the operator applies to a node group.[4] In the NIC Configuration Operator’s NicConfigurationTemplate it is a firmware setting, alongside linkType ("Ethernet" or "Infiniband"), pciPerformanceOptimized, roceOptimized and gpuDirectOptimized.[10] The documentation is blunt about the cost: “A configuration reset triggers a node reboot. Ensure that workloads are drained or that the Maintenance Operator is configured to handle the node maintenance automatically.”[10]
So when a customer says “we set numVfs: 8 and nothing happened”, the answer is a two-part check: what does SriovNetworkNodeState say was discovered, and has the firmware level actually been applied and rebooted.[4][10]
A Dell R760 with one ConnectX-7, PF ens1f0, and four VFs already exposed. You want one pod on an RDMA-capable VF, named nvidia.com/sriov_netdevice.
Step 1 - device plugin ConfigMap. resourceName is required, resourcePrefix is not but must be set or you inherit intel.com.[1]
{ "resourceList": [{
"resourcePrefix": "nvidia.com",
"resourceName": "sriov_netdevice",
"deviceType": "netDevice",
"selectors": { "vendors": ["15b3"], "pfNames": ["ens1f0"], "isRdma": true }
}]}Reasoning: vendors narrows to NVIDIA silicon, pfNames narrows to this PF so the Calico uplink on another PF is never captured, isRdma keeps non-RDMA functions out.[1]
Step 2 - confirm the advertisement. kubectl describe node r760-01 | grep -A20 Allocatable must show nvidia.com/sriov_netdevice: 4. A zero here means the selectors matched nothing and nothing downstream can work.[12]
Step 3 - the NAD. The delegate is sriov; deviceID is supplied at runtime by Multus, so it is not written in the NAD.[2][3]
{"cniVersion":"0.3.1","name":"sriov-network","plugins":[
{"type":"sriov","vlan":101,"ipam":{"type":"whereabouts","range":"192.168.2.225/28"}}]}Reasoning: vlan is inside 0-4094; whereabouts is cluster-wide so two nodes cannot hand out the same address.[3]
Step 4 - the pod. The annotation names the NAD, the resource block names the advertised string, and they must both be the same name the plugin published.[8][5]
metadata:
annotations:
k8s.v1.cni.cncf.io/networks: sriov-network
spec:
containers:
- name: test
resources:
requests: { nvidia.com/sriov_netdevice: "1" }
limits: { nvidia.com/sriov_netdevice: "1" }Step 5 - prove it from inside. kubectl exec -it test -- env | grep PCIDEVICE returns PCIDEVICE_NVIDIA_COM_SRIOV_NETDEVICE with the PCI address of the VF you were given.[1]
Same node, but now the fleet standard is that VLAN 220 carries storage traffic, spoof checking must be off, and the pool must exclude the PF that Calico uses (ens2f0).
{ "resourceList": [{
"resourcePrefix": "________",
"resourceName": "storage_vf",
"selectors": { "vendors": ["____"], "pfNames": ["________"], "isRdma": ____ }
}]}{"cniVersion":"0.3.1","name":"storage-net","plugins":[
{"type":"________","vlan":____,"spoofchk":"____",
"ipam":{"type":"whereabouts","range":"10.20.30.0/24"}}]} resources:
requests: { ____________________: "1" }Fill every blank, then answer two checks without running anything: (a) which single blank, if left at its default, makes the pod Pending forever, and (b) which blank has a documented allowed-value list that "disable" would violate.
A customer on OpenShift 4.20 reports: “we copied your working YAML from the vanilla cluster and the pod never starts. No errors anywhere.”
Produce, without access to their cluster: the one-line hypothesis, the two commands you want run, and the exact edit you expect to make. Acceptance criteria - your hypothesis names the resource-name prefix; your commands include one that reads the node’s Allocatable block and one that reads the pod’s events verbatim; your edit changes exactly one of the three places the name appears, and you can say why the other two must not change.[6][12]
Back on the call
Adding "vlan": 101 next to the QoS value clears the attachment error, and the engineer stops blaming the cards. Before hanging up you walk the four CRDs once - the policy is the request, SriovNetworkNodeState is what the operator actually found on the node - so the next VLAN change happens in one place instead of in a copied file.[4]
At 02:10 the night-shift operator calls. One node out of the twelve has an RDMA plugin in CrashLoopBackOff, and it is the node wearing the newest label on its cable.
Lab
On a ConnectX host in the Dell lab. Steps 2 and 6 change node state - read the rollback before you start.
-
Pre-flight inventory, recorded to a file.
uname -r;lspci -nn | grep -i mellanox;ip -br link show;cat /sys/class/net/<pf>/device/sriov_totalvfs;cat /sys/class/net/<pf>/device/sriov_numvfs;kubectl describe node <node> | grep -A20 Allocatable; and confirm which PF the primary CNI is using so you never select it. Keep this file - it is your rollback target. -
Confirm the PF is not the cluster uplink. If
ens1f0is both the Calico uplink and your intendedpfNamesselector, stop and pick another PF. A working cluster that silently loses RDMA when the CNI reconfigures the interface is the failure this prevents. -
Create VFs.
echo 4 > /sys/class/net/<pf>/device/sriov_numvfsExpected:lspci -nn | grep -i mellanoxgains four Virtual Function lines;ip link show <pf>listsvf 0throughvf 3. If not: the card may not have SR-IOV enabled in firmware, orsriov_totalvfsis 0 - that is a firmware-levelnumVfsquestion and needs the NIC Configuration Operator and a reboot, not a sysfs write.[10] Rollback:echo 0 > /sys/class/net/<pf>/device/sriov_numvfs. Do this before any driver or firmware work, and note that VFs in use by pods will block it - delete the pods first. -
Deploy the device plugin with
resourcePrefix: nvidia.com,resourceName: sriov_netdevice, and selectors{"vendors":["15b3"],"pfNames":["<pf>"],"isRdma":true}.[1][5] Expected: a new socket in/var/lib/kubelet/device-plugins/andnvidia.com/sriov_netdevice: 4in Allocatable. If not: socket present with count 0 means the selectors matched nothing - checkvendorsand the exact PF name. Rollback: delete the DaemonSet and its ConfigMap; the resource disappears from Allocatable within one ListAndWatch update. -
Create the NAD and one pod requesting
nvidia.com/sriov_netdevice: 1, with the annotationk8s.v1.cni.cncf.io/networksnaming the NAD in the same namespace.[8] Expected: the pod reaches Running andkubectl exec -- ip -br linkshowsnet1. If not: Pending means the name; a CNI ADD error means the delegate. Rollback: delete the pod and the NAD. -
Prove which VF you got.
kubectl exec -it <pod> -- env | grep PCIDEVICEExpected:PCIDEVICE_NVIDIA_COM_SRIOV_NETDEVICE=0000:xx:xx.xmatching one of the VFs from step 2.[1] -
Optional, and only with a maintenance window: repeat with
resourcePrefixomitted and confirm the pod from step 4 goes Pending with no CNI error. Rollback: restore the ConfigMap from your pre-flight file and delete the plugin pods so they reload it. -
Full teardown, in order: delete pods, delete NAD, delete device plugin DaemonSet and ConfigMap, then
echo 0 > /sys/class/net/<pf>/device/sriov_numvfs. Re-run the step 0 inventory and diff it against the file you saved.
No NVIDIA hardware needed. Everything here is config validation and prediction, on kind or on any cluster you can throw away.
-
Write three ConfigMaps.
a-default.jsonwithresourceName: hostdevand noresourcePrefix;b-nvidia.jsonidentical but withresourcePrefix: nvidia.com;c-openshift.jsonwithresourcePrefix: openshift.io. Keep the selectors identical in all three:{"vendors":["15b3"],"isRdma":true}. Expected: three files that differ by exactly one line. -
Predict the advertised names. Write them down before checking:
intel.com/hostdev,nvidia.com/hostdev,openshift.io/hostdev.[1][5][6] -
Write three pod specs, each requesting one of those names, plus a fourth that requests
nvidia.com/hostdevwhile the cluster runs config (a). Expected: you can state which pairs schedule on a node that has ConnectX VFs, and which one cannot. -
Validate the JSON rather than the hardware.
python3 -m json.tool < a-default.jsonon each file, then check every SR-IOV CNI field you used against the allowed ranges:vlan0-4094,vlanQoS0-7,vlanProtoin802.1q/802.1ad,link_statein auto/enable/disable.[3] Expected: a clean parse and no out-of-range value. If not: a JSON error inspec.configmeans Multus never registers the NAD at all, and the symptom looks like a missing annotation. -
Annotate a Pending transcript. Take a captured
kubectl describe podfrom a resource-name mismatch and mark, line by line: where the scheduler saysInsufficient <name>, where a CNI error would have appeared if the pod had been scheduled, and the fact that it is absent.[12] Expected: your annotation ends with “no CNI ran, therefore the fault is upstream of scheduling”. -
Break it on purpose. Deliberately set
vlan: 4095in one NAD and record the exact rejection or failure you observe. Note that a range violation and a name mismatch fail at completely different stages.[3]
Retrieval check
10 questions from memory. Answer before looking anything up; misses become flashcards.
Explain it to a Dell SE
Explain to a Dell SE, in five sentences, what has to line up for a pod to get a real ConnectX VF, and which single string is responsible for most of the tickets.
Sources
Facts in this lesson were checked against sriov-network-device-plugin and sriov-cni repositories, sriov-network-operator repository, NVIDIA Network Operator 26.7.0 deployment guide, quick start and OpenShift guide - all re-fetched 2026-09-07. Dates are when each page was fetched.
- GitHub - k8snetworkplumbingwg/sriov-network-device-plugin · fetched 2026-09-07
- GitHub - k8snetworkplumbingwg/sriov-cni · fetched 2026-09-07
- sriov-cni - Configuration Reference · fetched 2026-09-07
- GitHub - k8snetworkplumbingwg/sriov-network-operator · fetched 2026-09-07
- NVIDIA Network Operator v26.7.0 - Deployment Guide with Kubernetes · fetched 2026-09-07
- NVIDIA Network Operator v26.7.0 - Deployment Guide with OpenShift · fetched 2026-09-07
- NVIDIA Network Operator v26.7.0 - Quick Start Guide for Kubernetes · fetched 2026-09-07
- Multus CNI - How to use · fetched 2026-09-07
- NVIDIA Network Operator v23.7.0 - K8s on Bare Metal - Ethernet · fetched 2026-09-07
- NVIDIA Network Operator v26.7.0 - NIC Firmware Configuration · fetched 2026-09-07
- NVIDIA Network Operator v26.7.0 - Spectrum-X Quick Start · fetched 2026-09-07
- Kubernetes - Device Plugins · fetched 2026-09-07
The same idea elsewhere
Other lessons that cover this ground, sometimes from another course's angle.
- RDMA in Kubernetes: the NVIDIA Network OperatorRoCE course · Same ground: nv-ipam, versions and operator
- The Kubernetes network model and where a second CNI fitsElsewhere in this course · Same ground: nv-ipam, Multus and versions
- Network Operator and the NicClusterPolicyElsewhere in this course · Same ground: helm, Multus and misconception