Chapter 12. NVIDIA DPF Operator
12.1. NVIDIA DPF Operator release notes Copy linkLink copied to clipboard!
Use the release notes to learn what is new or changed in the NVIDIA DPF Operator.
12.1.1. Release notes for NVIDIA DPF Operator 26.4.1 Copy linkLink copied to clipboard!
The NVIDIA DPF Operator on OpenShift Container Platform has known limitations for uninstall, secrets, MTU, secure boot, multi-DPU hosts, and HBN, unsupported OVN-Kubernetes features, and issues that can affect Grafana and DTS metrics.
12.1.1.1. DPF Operator v26.4.1-beta.1 Copy linkLink copied to clipboard!
New features and enhancements
- Enhanced observability with DTS integration
- Added comprehensive DPU telemetry monitoring through the DOCA Telemetry Service (DTS) with built-in OpenShift Container Platform Console dashboard integration. DTS metrics are now accessible directly through the OpenShift Container Platform web console without requiring additional tools.
- Improved hosted control planes integration
- The DPF HCP Provisioner Operator provides enhanced lifecycle management for DPU hosted clusters, including automatic CSR approval, kubeconfig injection, and BlueField container image lookup.
- Advanced traffic validation
-
A comprehensive traffic validation framework with pre-configured test pods uses
nicolaka/netshootcontainers to validate end-to-end DPU service chain functionality. - Enhanced troubleshooting capabilities
- Expanded diagnostic tools and troubleshooting procedures cover DPU provisioning, hosted cluster management, networking issues, and comprehensive log collection.
Bug fixes
- Improved BFB image handling
- Fixed issues with BlueField Bootstream File (BFB) image download and verification processes.
- Enhanced worker node detection
- Resolved Node Feature Discovery (NFD) compatibility issues for reliable DPU hardware detection.
- Networking stability improvements
-
Fixed OVN-Kubernetes integration issues that could cause worker nodes to remain in
NotReadystate.
Technology Preview features
The NVIDIA DPF Operator is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
For more information about the support scope of Red Hat Technology Preview features, see Technology Preview Features Support Scope.
Known issues and limitations
- Only x86_64 workers are supported
- Only x86_64 worker nodes are supported in this release. ARM-based DPU workers are not supported.
- DPF Operator uninstall is not supported
-
The DPF Operator does not support an automated uninstall. If you must remove DPF, set
spec.manageDPUServiceTemplatestofalsein theDPFHCPProvisionerConfigresource before you uninstall. This prevents the DPF HCP Provisioner Operator from continuing to manageDPUServiceTemplateresources during the uninstall process. - Secret references are immutable
-
The pull secret and SSH secret references are immutable after creation and cannot be modified. Ensure that each secret contains the correct data before you create it and reference it in the
DPFHCPProvisionercustom resource. - Secondary pod interfaces are not supported
- Secondary pod interfaces (MultiNetwork) are not supported.
- MTU changes are not supported after deployment
- You cannot change the MTU value after deployment.
- Secure boot firmware requirement
- To boot the RHCOS BFB image with secure boot enabled, the DPU firmware must be at version 3.1.0 or later. Use a BFB firmware bundle to upgrade the firmware.
- Multi-DPU hosts are not supported
- Hosts with more than one DPU are not supported.
- Redeploying a DPUDeployment is not supported
-
Redeploying a
DPUDeploymentis not supported in this release. - Deployments cannot target all nodes in a cluster
- Because of a limitation in the resource injector, a deployment can target either the DPU workers or all other nodes, but not both.
- Host-Based Networking (HBN) pods stuck in FailedCreatePodSandBox
-
An HBN daemon set pod might remain in the
FailedCreatePodSandBoxstate. As a workaround, delete and re-create the affected pods. For more information, see OCPBUGS-100251. - HostedCluster upgrade during an in-progress upgrade
-
Changing the
ocpReleaseImageof aHostedClusterwhile an upgrade is already in progress is not supported. - Connectivity loss after a DPU reboot or upgrade
When a DPU reboots, the corresponding DPU worker node loses connectivity and a
NoExecutetaint is added to the host. Most pods are evicted immediately, but some daemon set pods remain and might lose connectivity until you re-create them. For example:Example output
openshift-network-diagnostics network-check-target-lpkp2 0/1 Running- DPU stuck in the NodeEffect or Initializing state
The NVIDIA Maintenance Operator might fail to pause the machine config pool, which leaves the DPU in the
NodeEffectorInitializingstate. As a workaround, pause theworker-dpumachine config pool manually:$ oc patch mcp worker-dpu --type merge -p '{ "spec": {"paused": true}, "metadata": {"annotations": {"maintenance.nvidia.com/mcp-paused": "true"}} }'- Workload pods do not recover after an IPMI reset reboot
- After an IPMI reset reboot, workload pods might fail to recover because of a known kubelet bug (Kubernetes issue 128043) that prevents virtual function (VF) devices from being re-created immediately at startup. This does not break functionality, but it leaves the cluster in an inconsistent state. Standard and IPMI2 reboots recover cleanly. As a workaround, re-create the affected pods manually if needed.
- The SR-IOV device plugin can report fewer virtual functions than configured
-
After a node reboot or DPU redeployment, the SR-IOV device plugin might publish the node’s virtual function (VF) resource count before all VFs are created. The init container unblocks when the first VF appears instead of waiting for all configured VFs, so the reported
openshift.io/bf3_vfscapacity can be lower than expected. As a workaround, restart the SR-IOV device plugin pod on the affected node, after which the full count is reported.
OVN-Kubernetes feature support
The following table lists the support and hardware offload status of OVN-Kubernetes features in this Technology Preview.
| Feature | Supported | Offloaded |
|---|---|---|
| Administrative Network Policies (ANP) | Yes | Yes |
| Egress IP | Yes | No |
| Egress Firewall | Yes | No |
| Egress Quality of Service (QoS) | Yes | No |
| Secondary networks | No | No |
| User Defined Networks (UDN) | No | No |
| Quality of Service (QoS) | No | No |
| Multiple External Gateways (MEG) | No | No |
| OVN-Kubernetes identity | No | No |
| Border Gateway Protocol (BGP) | No | No |
| Multicast | No | No |
| Hybrid Overlay | No | No |
| Local gateway mode | No | No |
| IPFIX or NetFlow sampling | No | No |
Grafana deployment issues
- Grafana shows that the application is not available
Grafana pods might be scheduled on worker nodes that depend on DPU networking, which creates a circular dependency.
Configure Grafana to run on control plane nodes by adding
nodeSelectorandtolerationsto the Grafana custom resource:spec: deployment: spec: template: spec: nodeSelector: node-role.kubernetes.io/control-plane: "" tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule
DTS metrics collection issues
- DTS metrics are not appearing in Prometheus or Grafana
The
ServiceMonitormight not be configured correctly, or DTS pods might not be running.Verify that DTS pods are running:
$ oc get pods -n dpf-operator-system -l app=dtsCheck the
ServiceMonitorconfiguration:$ oc get servicemonitor -n dpf-operator-system $ oc describe servicemonitor <servicemonitor-name> -n dpf-operator-systemVerify that user workload monitoring is enabled:
$ oc get configmap cluster-monitoring-config -n openshift-monitoring -o yamlCheck Prometheus targets to ensure that DTS endpoints are being scraped. Access the Prometheus web console and go to Status
Targets to verify that DTS endpoints are listed and healthy.
12.2. About the NVIDIA DPF Operator Copy linkLink copied to clipboard!
The NVIDIA DOCA Platform Framework (DPF) Operator enables hardware-accelerated networking on OpenShift Container Platform by offloading OVN-Kubernetes data plane operations to NVIDIA BlueField-3 Data Processing Units (DPUs).
The DPF deployment creates a dual-cluster topology consisting of a management cluster running on x86 servers and a hosted DPU cluster running on BlueField-3 DPUs.
The NVIDIA DPF Operator is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.
For more information about the support scope of Red Hat Technology Preview features, see Technology Preview Features Support Scope.
12.2.1. DPF architecture overview Copy linkLink copied to clipboard!
The NVIDIA DOCA Platform Framework (DPF) v26.4.1 deployment on OpenShift Container Platform 4.22 offloads OVN-Kubernetes data plane operations to NVIDIA BlueField-3 DPUs.
In Host Trusted deployments, DPF uses BlueField DPUs as host accelerators, and the host is part of the trusted domain. Administrators can orchestrate both workloads and DPU-accelerated infrastructure by using standard OpenShift Container Platform APIs and custom resource definitions (CRDs).
By offloading critical OpenShift Container Platform networking functions, such as OVN-Kubernetes, to the DPU, the architecture frees host CPU resources for tenant applications. DPF also provides automated lifecycle management so that administrators can provision, configure, and update fleets of DPUs directly from OpenShift Container Platform.
In the current release, the supported DPU services are Host-Based Networking (HBN) with OVN-Kubernetes and the DOCA Telemetry Service (DTS).
The NVIDIA DPF Operator is distinct from the Red Hat DPU Operator. The Red Hat DPU Operator manages supported non-NVIDIA DPU devices. NVIDIA BlueField-3 deployments use the DPF Operator and related components.
12.2.1.1. The topology Copy linkLink copied to clipboard!
The DPF deployment creates a specialized networking infrastructure consisting of two distinct cluster planes that work together to deliver hardware-accelerated networking:
- OpenShift Container Platform management cluster
The management cluster runs on the server’s main x86 CPU cores. It hosts the actual business logic, such as AI workloads or enterprise applications.
The management cluster serves as the primary administrative interface and the host cluster that provisions and manages both the fleet of DPUs and user workloads. In a Host Trusted deployment, the worker nodes in this cluster are the physical servers that house the BlueField DPUs.
The management cluster is responsible for the following functions:
- Running user workloads on x86 host processors.
-
Providing a single interface for defining the required state of the infrastructure by using Kubernetes CRDs such as
DPUSet,DPUDeployment, andDPUService. - Driving the discovery of DPUs, flashing BlueField Bootstream (BFB) images, and configuring host-to-DPU networking.
- Coordinating the deployment of services and network flows to the DPU cluster.
- OpenShift Container Platform DPU hosted cluster
The DPU hosted cluster is a dedicated, secondary Kubernetes control plane for managing the fleet of NVIDIA BlueField DPUs. The DPUs function as the worker nodes of this hosted cluster, separate from the bare-metal hosts they are physically attached to.
The DPU hosted cluster runs the following components:
- OVN-Kubernetes running in DPU mode to offload flows.
- DOCA services such as Host-Based Networking (HBN) for BGP routing, DOCA Telemetry Service (DTS) for monitoring, and Firefly for time synchronization.
- System components including NVIDIA IPAM, Multus, and SR-IOV Device Plugins to manage the DPU hardware resources.
12.2.1.2. Example topology Copy linkLink copied to clipboard!
The following diagram illustrates the physical connectivity for a reference lab environment. It serves as a baseline example to demonstrate the core components and their interactions.
12.2.1.3. Architecture characteristics Copy linkLink copied to clipboard!
- Host-managed DPU lifecycle
- In a Host Trusted deployment, the DPU is managed from the host. This model enables cloud operators to manage BlueField-bound services directly from their standard OpenShift Container Platform control plane. DPF automates the discovery and provisioning of DPUs: the DPF Operator detects worker nodes, creates DPU objects, and deploys the DOCA Management Service (DMS) to install the BFB firmware and configure networking between the host and DPU. This approach reduces manual low-level device configuration by using standard Kubernetes APIs and workflows.
- Infrastructure service offloading
- In Host Trusted mode, infrastructure services such as networking, storage, and security are offloaded from the host CPU to the DPU. This frees host CPU resources for applications. The framework routes data center traffic through dedicated ports on the BlueField DPU.
- Kubernetes-native orchestration
- DPF extends the Kubernetes control plane to the DPUs, enabling administrators to deploy and orchestrate NVIDIA DOCA services and third-party applications directly on the BlueField DPU by using familiar Kubernetes constructs. The architecture supports automated rolling updates, scaling, and rollbacks for services without disrupting ongoing operations.
12.2.2. DPF component placement Copy linkLink copied to clipboard!
The software components and Operators run on the management cluster and the DPU hosted cluster to separate workload management from infrastructure acceleration.
12.2.2.1. Management cluster components Copy linkLink copied to clipboard!
The following Operators and services run within the management cluster:
- NVIDIA DPF Operator
- The core Operator that manages DPU services and configurations within the hosted cluster, including DPU provisioning, networking acceleration, and DOCA service orchestration.
- DPF HCP Provisioner Operator
- Automates the hosted control plane’s cluster lifecycle for the DPU nodes.
- MultiCluster Engine (MCE) and hosted control planes
- Provide the control plane and management framework for the DPU hosted cluster.
- Node Feature Discovery (NFD) Operator
- Discovers and labels hardware features on the nodes, including the presence of DPUs.
- MetalLB Operator
- Provides load balancing services for the management cluster.
- GitOps Operator
- Facilitates ArgoCD-based deployment of applications and configurations.
- cert-manager Operator
- Automates the management, issuance, and renewal of TLS certificates within the cluster.
- NVIDIA Maintenance Operator
- Assists in performing maintenance tasks and gracefully draining DPU worker nodes.
- LVM Storage
- Provides persistent ReadWriteMany (RWX) storage required for various components, such as the etcd database of the hosted cluster.
NodeSRIOVDevicePluginConfig- A DPF-managed CRD that configures SR-IOV device plugin pods on worker nodes. It defines VF allocation ranges for management and workload traffic.
- Bare Metal Operator
- Provisions and adds worker nodes with DPUs to the management cluster.
12.2.3. DPF deployment flow overview Copy linkLink copied to clipboard!
The end-to-end deployment process for the NVIDIA DPF Operator follows a series of high-level steps, from management cluster setup through workload verification.
The deployment flow consists of the following steps:
- Management cluster setup: Install and configure a standard OpenShift Container Platform cluster on x86 servers with control-plane nodes only.
- Management cluster configuration: Configure nodes and cluster-level settings, then install and configure the required Operators on the management cluster.
DPF installation: Deploy the DPF Operator, controllers, DPF resources, and DPU service definitions on the management cluster.
ImportantYou must install the DPF Operator before the DPF HCP Provisioner Operator because that Operator requires DPF custom resource definitions (CRDs) such as
DPUCluster,DPUFlavor,DPUDeployment, andDPFOperatorConfig.-
Hosted cluster creation: The DPF HCP Provisioner Operator automates the creation of a hosted DPU cluster by using hosted control planes. The Operator references the
DPUDeploymentresource during ignition generation. - Worker node scale-out and DPU provisioning: When worker nodes with DPUs are added to the cluster, the DPF Operator flashes the DPUs with a Red Hat Enterprise Linux CoreOS (RHCOS) image and configures them to join the hosted cluster as worker nodes.
- Worker node integration: Approve DPU worker node certificate signing requests (CSRs) and configure security context constraint (SCC) bindings on the hosted cluster.
- Service deployment: After the DPU hosted cluster is operational, data plane DPU services and chains are deployed by DPF.
-
Verification: Validate end-to-end connectivity through the DPU data plane by running
pingandnctraffic tests between workload pods and services.
12.2.4. DPF hardware requirements Copy linkLink copied to clipboard!
A DPF v26.4.1 deployment on OpenShift Container Platform 4.22 requires a workstation with CLI tools, a management cluster, at least two worker servers with NVIDIA BlueField-3 DPUs, dedicated management and DPU network switches, and a shared storage server for BFB images.
12.2.4.1. Workstation Copy linkLink copied to clipboard!
A workstation with the following command-line interface (CLI) tools installed:
-
OpenShift CLI (
oc) is installed. -
Helm CLI (
helm) is installed.
12.2.4.2. Control plane nodes Copy linkLink copied to clipboard!
Three nodes form the control plane of the management cluster.
| Component | Requirement |
|---|---|
| Form factor | Virtual machines or physical servers |
| Memory | 60 GB RAM |
| CPU | 16 vCPUs (Intel or AMD x86_64) |
| Storage | 120 GB NVMe SSD storage, plus an additional 80 GB disk for LVM Storage |
| Networking | 1x 1GbE network interface |
| DPUs | DPUs must not be installed on control plane nodes |
12.2.4.3. Worker nodes Copy linkLink copied to clipboard!
Two physical x86 servers host the NVIDIA BlueField-3 DPUs and act as worker nodes for the management cluster.
| Component | Requirement |
|---|---|
| Memory | 256 GB RAM |
| CPU | 16 cores (Intel or AMD x86_64) |
| Storage | A minimum of 500 GB NVMe SSD storage for the base operating system |
| DPU slot | PCIe Gen 5 x16 slot required. Each server can have multiple DPUs but only one NVIDIA BlueField-3 DPU can be provisioned. |
| BIOS settings | SR-IOV must be enabled. In-Band Manageability Interface must be enabled. |
As part of the installation process, a Linux bridge named br-ex is automatically created on the worker node’s physical management port by using a MachineConfig custom resource to facilitate control-plane traffic from the DPU through the host server.
12.2.4.4. NVIDIA BlueField-3 DPUs Copy linkLink copied to clipboard!
One NVIDIA BlueField-3 DPU is required per worker node.
| Component | Requirement |
|---|---|
| Model | |
| Memory | 32 GB. Dual-port DPUs with 32 GB require an external power connection to the x86 server. |
| Networking | Dual 200GbE ports per DPU. Both ports must be connected to the high-speed switch for ECMP routing. |
| Management | The out-of-band management port is not used in this configuration. |
| Operating system and software | The DPUs are provisioned with a BlueField Bootstream File (BFB) that bundles a Red Hat Enterprise Linux CoreOS (RHCOS) base image and the NVIDIA DOCA software stack. The DOCA software stack includes the DPU firmware (version 32.49.1014). |
12.2.5. DPF network infrastructure requirements Copy linkLink copied to clipboard!
A DPF deployment requires a management switch, a high-speed DPU switch, routable management and VTEP networks with reserved service IPs and a VIP, and a consistent MTU across all network components.
12.2.5.1. Switches Copy linkLink copied to clipboard!
- Management switch
- Provides 1GbE connectivity for the control plane and worker node management interfaces.
- High-speed switch
- An NVIDIA SN3700 or similar switch providing 2x 200GbE connectivity per DPU.
12.2.5.2. Connectivity Copy linkLink copied to clipboard!
- All nodes must have full internet access, both from the host out-of-band and DPU high-speed interfaces.
- The management network and the high-speed DPU network, which is the VTEP CIDR, must be routable to each other in both directions. Verify reachability in each direction before you begin the installation, because connectivity that works in only one direction allows the deployment to proceed partway and then fail.
- A dedicated IP address range, which is the VTEP Classless Inter-Domain Routing (CIDR), must be allocated from the high-speed DPU network for DPU service IPs used by HBN and OVN tunnels.
- A Virtual IP (VIP) from the management subnet must be reserved for the hosted DPU cluster control-plane services. The VIP must have a DNS A record.
12.2.5.3. MTU configuration Copy linkLink copied to clipboard!
The deployment supports any maximum transmission unit (MTU) value, provided it is consistent across all network components, including switches, interfaces, and bridges. Common values are 1500 for standard frames and 9000 for jumbo frames. Whichever value you choose must be supported end-to-end by every component in the network path.
The MTU value is set during deployment and cannot be changed later. Ensure consistency across all environment components. When using VMs for control plane nodes, ensure the hypervisor bridge MTU matches the chosen value.
12.2.6. DPF software requirements Copy linkLink copied to clipboard!
A DPF v26.4.1 deployment requires specific versions of OpenShift Container Platform, the OpenShift CLI (oc), hosted control planes, the NVIDIA DPF Operator, and RHCOS BFB, plus cluster-admin privileges on the management cluster.
| Component | Required version |
|---|---|
| OpenShift Container Platform | 4.22 |
|
OpenShift CLI ( | 4.22 |
| Hosted control planes OpenShift Container Platform cluster | 4.22 |
| NVIDIA DPF Operator | v26.4.1 |
| RHCOS BFB | 4.22 |
The RHCOS BFB entry refers to the base RHCOS BlueField Bootstream (BFB) image, which is available from the OpenShift Container Platform mirror. For example:
Example BFB image URL
https://rhcos.mirror.openshift.com/art/storage/prod/streams/rhel-10.2/builds/10.2.20260715-0/aarch64/rhcos-10.2.20260715-0-nvidiabluefield.aarch64.bfb
The base BFB is layered with the NVIDIA DOCA stack at provisioning time, and the DOCA services run on the DPUs as separately deployed DPUService resources. The following versions are pinned by this deployment:
| Component | Required version |
|---|---|
| NVIDIA DOCA | 3.4.1 |
| Host-Based Networking (HBN) | 3.4.0 |
| DOCA Telemetry Service (DTS) | 1.25.5 |
| OVN-Kubernetes | Delivered by the DPF OVN-Kubernetes Helm chart |
12.2.6.1. Required command-line tools Copy linkLink copied to clipboard!
Install the following tools on the workstation from which you run the deployment commands:
-
oc— the OpenShift Container Platform CLI, version 4.22. -
helm— required to install the DPF Operator and related Helm charts. -
envsubst— substitutes environment variables into the manifest templates used throughout this documentation (theenvsubst < file.yaml | oc apply -f -pattern). Provided by thegettextpackage. -
jq— parses JSON output during verification and troubleshooting.
12.2.6.2. Access requirements Copy linkLink copied to clipboard!
-
cluster-adminprivileges are required for the management cluster.
12.3. Set up the environment for DPF Copy linkLink copied to clipboard!
Before installing the NVIDIA DPF Operator, you must set up the management cluster, configure worker nodes, and install and configure the required Operators.
12.3.1. Set up the management cluster Copy linkLink copied to clipboard!
The management cluster is a standard OpenShift Container Platform 4.22 cluster installed by using the Assisted Installer. This cluster hosts the DPF Operators and the hosted control planes for managing the hosted cluster on DPUs.
Prerequisites
- You have access to the Red Hat Hybrid Cloud Console.
-
You have the OpenShift CLI (
oc) installed.
Procedure
-
Go to the Red Hat Hybrid Cloud Console cluster creation page and create a cluster with control-plane nodes only. Select Data center
Assisted Installer. Optional: Configure jumbo MTU for each control plane node.
- Under Hosts' network configuration in the Assisted Installer wizard, select Static IP, bridges, and bonds.
Set the Static network configurations section per node according to the following template, using the relevant MAC address and interface name for each node:
interfaces: - ipv4: dhcp: true enabled: true mac-address: <xx:xx:xx:xx:xx:xx> mtu: 1500 # Set to 1500 for standard MTU or 9000 for jumbo frames name: <interface-name> state: up type: ethernetNote- You can alternatively configure MTU allocation on the DHCP server that allocates IPs to the control plane nodes.
- If virtual machines are used for control-plane nodes, the MTU must be set on the bridge of the hypervisor used by the VMs.
- When using MTU 9000, ensure the switch ports that connect the cluster’s control-plane nodes are set to handle jumbo frames.
Select the following operators to install with the cluster:
-
Storage
Logical Volume Manager Storage -
Platform Operations & Lifecycle
MultiCluster Engine -
Scheduling
Node Feature Discovery
-
Storage
- Click Add hosts to add hosts to the cluster. Only control plane nodes are required at this stage.
-
After the installation completes, download the
KUBECONFIGfile and save it asmgmt-kubeconfig.
Verification
Set the
KUBECONFIGenvironment variable:$ export KUBECONFIG="$(pwd)/mgmt-kubeconfig"Verify that all nodes are in a
Readystate:$ oc get nodes
12.3.2. Configure worker nodes for DPU operation Copy linkLink copied to clipboard!
You must deploy the dpu-worker-config Helm chart to configure worker nodes with DPUs before adding those nodes to the management cluster. The dpu-worker-config Helm chart creates the MachineConfigPool, dpu-worker-configuration MachineConfig, and other required resources that configure the bridge, OVS services, and IP routing on worker nodes. The MachineConfigPool groups DPU-equipped worker nodes so that the Machine Config Operator can apply DPU-specific configurations to them.
The MachineConfig resource performs several configuration tasks required by DPF:
-
Bridge Configuration: Creates a
br-exbridge interface that enables communication between the DPU and the hosted cluster control plane running on the management cluster. This name must match thedpuNodeOOBBridgeNamevalue in theDPFOperatorConfigresource, or DPU provisioning fails. For more information refer to DPF Operator Prerequisites. - OVS Service Management: Disables OpenShift’s default OVS services on x86 worker nodes. This is required for OVN-Kubernetes DPU Host mode operation, where networking functions are offloaded to the DPU rather than running on the host CPU.
- IP Rules Configuration: Sets routing rules required for pod-to-host control-plane traffic.
Prerequisites
-
You have access to the cluster as a user with the
cluster-adminrole. -
You have installed the OpenShift CLI (
oc). -
The Helm CLI (
helm) is installed on your workstation. -
You have a pull secret file that includes credentials for
registry.redhat.io. Helm reads its registry credentials from this file, which is separate from the container runtime configuration.
Procedure
Set the
OPENSHIFT_PULL_SECRETenvironment variable to the path of your pull secret file:$ export OPENSHIFT_PULL_SECRET="/root/pull-secret.txt"Deploy the
dpu-worker-configHelm chart to create the worker node MachineConfig:$ helm upgrade --install dpu-worker-config \ oci://registry.redhat.io/dpu-kit-for-nvidia/dpu-worker-config-chart \ --version 4.22.0 \ --registry-config "${OPENSHIFT_PULL_SECRET}" \ --namespace dpf-hcp-provisioner-system \ --create-namespace \ --disable-openapi-validation
Verification
Verify that the
dpu-worker-configHelm release is deployed:$ helm list -n dpf-hcp-provisioner-systemVerify that the
MachineConfigPoolwas created automatically:$ oc get mcp worker-dpuExample output
NAME CONFIG UPDATED UPDATING DEGRADED MACHINECOUNT READYMACHINECOUNT UPDATEDMACHINECOUNT DEGRADEDMACHINECOUNT AGE worker-dpu rendered-worker-dpu-b4a44cc606c2ffcf07067d1e943a8758 True False False 0 0 0 0 2mVerify that the
dpu-worker-configurationMachineConfig is created:$ oc get machineconfig dpu-worker-configurationExample output
NAME GENERATEDBYCONTROLLER IGNITIONVERSION AGE dpu-worker-configuration 3.2.0 2m
The Machine Config Operator automatically reboots worker nodes to apply DPU-specific configurations after nodes with the worker-dpu label are added to the cluster.
12.3.3. Create the DPF namespace Copy linkLink copied to clipboard!
You must create a dedicated namespace for the DPF Operator and its components before installing the Operator.
Prerequisites
-
You have access to the cluster as a user with the
cluster-adminrole. -
You have installed the OpenShift CLI (
oc).
Procedure
Create the
dpf-operator-systemnamespace:$ oc create namespace dpf-operator-system
Verification
Verify that the namespace was created:
$ oc get namespace dpf-operator-system
12.3.4. Required Operators Copy linkLink copied to clipboard!
Before you install the DPF Operator, you must install the cert-manager Operator for Red Hat OpenShift, MetalLB Operator, Red Hat OpenShift GitOps, and NVIDIA Maintenance Operator.
The multicluster engine Operator and the Node Feature Discovery Operator can be installed during management cluster creation by using the Assisted Installer. After installation, configure those Operators, MetalLB, GitOps, and the Cluster Network Operator as described in "Configure the required Operators".
12.3.4.1. Install the NVIDIA Maintenance Operator Copy linkLink copied to clipboard!
The NVIDIA Maintenance Operator assists in performing maintenance tasks and gracefully draining DPU worker nodes. You install this operator by using Helm.
Prerequisites
-
You have access to the cluster as a user with the
cluster-adminrole. -
You have installed the OpenShift CLI (
oc). -
You have installed the Helm CLI (
helm).
Procedure
Create a Helm values file named
maintenance-operator-values.yamlwith the following content:operatorConfig: deploy: true maxParallelOperations: 60% operator: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: "node-role.kubernetes.io/master" operator: Exists - matchExpressions: - key: "node-role.kubernetes.io/control-plane" operator: Exists tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoScheduleInstall the Operator by using Helm:
$ helm upgrade --install maintenance-operator oci://ghcr.io/mellanox/maintenance-operator-chart \ --namespace dpf-operator-system \ --create-namespace \ --disable-openapi-validation \ --version 0.3.0 \ --values maintenance-operator-values.yaml \ --wait
Verification
Verify that the Operator pod is running:
$ oc get pods -n dpf-operator-systemExample output
maintenance-operator-585767f779-kps9c 1/1 Running 0 2d23h
12.3.5. Configure the required Operators Copy linkLink copied to clipboard!
After the required Operators are installed, configure Node Feature Discovery, MetalLB, GitOps, and Cluster Network Operator for the DPF environment. This procedure also verifies that the multicluster engine and hosted control planes components are ready.
Prerequisites
-
You have access to the cluster as a user with the
cluster-adminrole. -
You have installed the OpenShift CLI (
oc). - You have installed the cert-manager Operator for Red Hat OpenShift, MetalLB Operator, Red Hat OpenShift GitOps, and NVIDIA Maintenance Operator.
- You have installed the Logical Volume Manager Storage Operator, multicluster engine operator, and the Node Feature Discovery Operator. You can install them by using the Assisted Installer during cluster creation. For manual installation, see Installing multicluster engine operator and ensure that the hosted control planes component is enabled.
Procedure
Define the cluster variables used by Node Feature Discovery:
$ export CLUSTER_NAME="doca-mgmt" $ export BASE_DOMAIN="example.com" $ export HOST_CLUSTER_API="api.${CLUSTER_NAME}.${BASE_DOMAIN}"where:
CLUSTER_NAME- Specifies the management cluster name.
BASE_DOMAIN- Specifies the management cluster base domain.
HOST_CLUSTER_API- Specifies the management cluster API endpoint.
Create a file named
nfd-instance.yamlwith the followingNodeFeatureDiscoveryresource definition:apiVersion: nfd.openshift.io/v1 kind: NodeFeatureDiscovery metadata: name: nfd-instance namespace: openshift-nfd spec: operand: workerEnvs: - name: KUBERNETES_SERVICE_HOST value: $HOST_CLUSTER_API - name: KUBERNETES_SERVICE_PORT value: "6443" workerConfig: configData: | sources: pci: deviceClassWhitelist: - "0200" - "03" - "12" - "0207" deviceLabelFields: - "vendor" - "device" - "class"Apply the file by using
envsubstto substitute the environment variables:$ envsubst < nfd-instance.yaml | oc apply -f -Create a file named
nfd-rule.yamlwith the followingNodeFeatureRuleresource definition to detect worker nodes with DPUs and label them with adpu-enabledlabel:apiVersion: nfd.openshift.io/v1alpha1 kind: NodeFeatureRule metadata: name: dpu-detection-rule namespace: openshift-nfd spec: rules: - labels: dpu-enabled: "" matchFeatures: - feature: pci.device matchExpressions: device: op: In value: - a2d6 - a2dc vendor: op: In value: - 15b3 name: DPU-detection-ruleApply the file:
$ oc apply -f nfd-rule.yamlEnsure that the MetalLB Operator
Subscriptionschedules Operator pods on control-plane nodes. When you install the MetalLB Operator, include the followingspec.configsettings, or patch an existingSubscriptionto add them:apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: metallb-operator namespace: openshift-operators spec: channel: "stable" name: metallb-operator source: redhat-operators sourceNamespace: openshift-marketplace installPlanApproval: Automatic config: tolerations: - key: "node-role.kubernetes.io/control-plane" operator: "Exists" effect: "NoSchedule" affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: "node-role.kubernetes.io/control-plane" operator: "Exists"Create a file named
metallb-config.yamlwith the followingMetalLBresource definition:apiVersion: metallb.io/v1beta1 kind: MetalLB metadata: name: metallb namespace: openshift-operators spec: nodeSelector: node-role.kubernetes.io/control-plane: "" speakerTolerations: - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoScheduleApply the MetalLB resource file:
$ oc apply -f metallb-config.yamlEnsure that the Red Hat OpenShift GitOps
Subscriptionincludes the DPF-required environment variables. When you install the Operator, set the followingspec.config.envvalues, or patch an existingSubscriptionto add them so that Argo CD can manage thedpf-operator-systemnamespace:apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: openshift-gitops-operator namespace: openshift-gitops-operator spec: channel: gitops-1.21 config: env: - name: ARGOCD_CLUSTER_CONFIG_NAMESPACES value: "openshift-gitops,dpf-operator-system" - name: CONTROLLER_CLUSTER_ROLE value: "cluster-admin" - name: SERVER_CLUSTER_ROLE value: "cluster-admin" installPlanApproval: Automatic name: openshift-gitops-operator source: redhat-operators sourceNamespace: openshift-marketplace startingCSV: openshift-gitops-operator.v1.21.3Create a file named
argocd-instance.yamlwith the followingArgoCDresource definition:apiVersion: argoproj.io/v1beta1 kind: ArgoCD metadata: name: argocd namespace: dpf-operator-system spec: nodePlacement: nodeSelector: node-role.kubernetes.io/control-plane: "" tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule server: route: enabled: true controller: {} repo: {} applicationSet: enabled: false resourceExclusions: | - apiGroups: - packages.operators.coreos.com kinds: - PackageManifest sso: provider: dex dex: openShiftOAuth: true notifications: enabled: falseApply the Argo CD file:
$ oc apply -f argocd-instance.yamlWait for the ArgoCD Redis deployment to be ready:
$ oc wait deployment argocd-redis -n dpf-operator-system \ --for=condition=Available --timeout=120sEnable global IP forwarding on the OVN-Kubernetes configuration:
This command enables IP packet forwarding between different networks managed by OVN-Kubernetes.
$ oc patch network.operator.openshift.io cluster --type=merge -p \ '{"spec":{"defaultNetwork":{"ovnKubernetesConfig":{"gatewayConfig":{"ipForwarding":"Global"}}}}}'
Verification
Verify that the
MultiClusterEngineinstance is created:$ oc get multiclusterengine mceExample output
NAME STATUS AGE CURRENTVERSION DESIREDVERSION MESSAGE mce Available 4m58s 2.17.2 2.17.2 All components availableVerify that the hosted control planes component is enabled:
$ oc get multiclusterengine mce -o jsonpath='{.spec.overrides.components[?(@.name=="hypershift")].enabled}{"\n"}'NoteIf the previous command returns
falseor an empty result, hosted control planes is not enabled and DPU provisioning fails.To continue, you must enable the
hypershiftcomponent on theMultiClusterEngineresource. In current multicluster engine Operator versions the component is namedhypershift; earlier versions usehypershift-preview.If the result is empty, no
hypershiftentry exists. Run the following command to add the entry and enable it:$ oc patch mce multiclusterengine --type=json \ -p='[{"op":"add","path":"/spec/overrides/components/-","value":{"name":"hypershift","enabled":true}}]'If the result is
false, an entry exists but is disabled. Edit the resource and set thehypershiftcomponent toenabled: true:$ oc edit multiclusterengine mce
ImportantDo not use
oc patch --type=mergeto enable the component, because a merge patch replaces the entirecomponentsarray and removes the other components. Use the JSONaddpatch when no entry exists, oroc editwhen an entry exists but is disabled.Verify that the
NodeFeatureDiscoveryinstance andNodeFeatureRuleare configured:$ oc get nodefeaturediscovery,nodefeaturerule -n openshift-nfdVerify that the
MetalLBinstance was created:$ oc get metallb -n openshift-operatorsVerify that the Argo CD pods are running:
$ oc get pods -n dpf-operator-system -l app.kubernetes.io/part-of=argocdVerify that IP forwarding is set to
Global:$ oc get network.operator.openshift.io cluster -o jsonpath='{.spec.defaultNetwork.ovnKubernetesConfig.gatewayConfig.ipForwarding}'Example output
Global
12.4. Install and configure the DPF Operator Copy linkLink copied to clipboard!
After setting up the environment, install the NVIDIA DPF Operator and create the required DPF resources and DPU services.
You must install the DPF Operator before the DPF HCP Provisioner Operator because that Operator requires DPF CRDs such as DPUCluster, DPUFlavor, DPUDeployment, and DPFOperatorConfig.
12.4.1. DPF Operator installation environment variables Copy linkLink copied to clipboard!
Set the following required environment variables before you install and configure the DPF Operator on OpenShift Container Platform. The values of these variables are used in multiple DPF Operator installation and configuration procedures.
| Variable | Description | Example value |
|---|---|---|
|
| The name of the management cluster. |
|
|
| The base domain for the management cluster. |
|
|
|
The API server hostname of the management cluster. Derived from |
|
|
| The version tag for the DPF Operator Helm chart. |
|
|
| The port number of the hosted cluster API server. |
|
|
|
The CIDR range for the VTEP (tunnel endpoint) network. Used as the OVN |
|
|
|
The CIDR range of the subnet where the DPU host nodes reside. Used as the OVN |
|
|
|
Number of SR-IOV VFs per physical function. Sets |
|
|
| The OCI chart URL for the OVN-Kubernetes Helm chart. |
|
|
| The version of the OVN-Kubernetes Helm chart. |
|
|
|
The MTU value for OVN-Kubernetes overlay networking. Set to |
|
|
| The download URL for the BlueField Bootstream File image used to provision DPUs. |
|
|
|
The local file name for the BFB image, which is typically the base name of |
|
|
| The name of the hosted cluster running on the DPUs. |
|
|
| The Helm chart registry URL for the DPF Operator. |
|
|
|
The MTU value for the node network interfaces. Use |
|
|
| The pod CIDR for the Flannel network in the hosted cluster. Required for OpenShift Container Platform 4.22 and later. |
|
12.4.2. Install the DPF Operator Copy linkLink copied to clipboard!
You can install the DPF Operator by using Helm to deploy the Operator into the dpf-operator-system namespace on your management cluster.
You must install the DPF Operator before the DPF HCP Provisioner Operator because that Operator requires the following DPF custom resource definitions to be available: DPUCluster, DPUFlavor, DPUDeployment, and DPFOperatorConfig.
Prerequisites
-
You have access to the management cluster as a user with the
cluster-adminrole. -
You have installed the
ocCLI. -
You have installed the
helmCLI. - You have set the DPF Operator environment variables. For details, see "DPF Operator installation environment variables".
Procedure
Add the DPF Helm repository and update the local cache:
$ helm repo add --force-update dpf-repository ${REGISTRY}$ helm repo updateInstall the DPF Operator by using Helm:
$ helm upgrade --install dpf-operator dpf-repository/dpf-operator \ --namespace dpf-operator-system \ --version "${TAG}" \ --set kamajiEtcdDefrag.enabled=false \ --set isOpenshift=true \ --set enableNodeFeatureRules=false \ --wait
Verification
Verify that the Operator controller manager deployment has rolled out successfully:
$ oc rollout status deployment --namespace dpf-operator-system dpf-operator-controller-managerExample output
deployment "dpf-operator-controller-manager" successfully rolled outVerify that all pods in the
dpf-operator-systemnamespace are ready:$ oc wait --for=condition=ready --namespace dpf-operator-system pods --allExample output
pod/argocd-application-controller-0 condition met pod/argocd-dex-server-6dd56c8469-bhsq4 condition met pod/argocd-redis-b4f94bb8d-wr86b condition met pod/argocd-repo-server-96765f997-79k9q condition met pod/argocd-server-648c7ff85f-7frtg condition met pod/dpf-operator-controller-manager-7bf9744c5f-cwrgc condition met pod/maintenance-operator-585767f779-8k2lx condition met
12.4.3. Create the DPFOperatorConfig custom resource Copy linkLink copied to clipboard!
Create a DPFOperatorConfig custom resource to configure the DPF Operator components, including the provisioning controller, static cluster manager, and SR-IOV device plugin controller.
Prerequisites
- You have installed the DPF Operator.
- You have set the DPF Operator environment variables. For details, see "DPF Operator installation environment variables".
Procedure
Create a file named
dpfoperatorconfig.yamlwith the following content:NoteMTU Configuration: Set
NODES_MTUto1500for standard MTU environments or9000for jumbo frame environments. This value must be consistent across:- Assisted Installer host configuration
- DPFOperatorConfig networking section (this step)
- DPUServiceNAD configuration
Choose based on your network infrastructure capabilities.
apiVersion: operator.dpu.nvidia.com/v1alpha1 kind: DPFOperatorConfig metadata: name: dpfoperatorconfig namespace: dpf-operator-system spec: kamajiClusterManager: disable: true multus: disable: true cniInstaller: disable: true networking: controlPlaneMTU: $NODES_MTU # management/OOB MTU (= NODES_MTU: 1500 standard, 9000 jumbo) highSpeedMTU: $NODES_MTU # high-speed fabric MTU (= NODES_MTU; must match controlPlaneMTU) dpuNodeOOBBridgeName: br-ex # OOB bridge for DPU provisioning; br-ex on OpenShift overrides: dpuCNIBinPath: /var/lib/cni/bin/ dpuCNIPath: /run/multus/cni/net.d/ dpuOpenvSwitchSystemSharedLib64Path: /lib64 flannelSkipCNIConfigInstallation: false kubernetesAPIServerPort: $TARGETCLUSTER_API_SERVER_PORT kubernetesAPIServerVIP: $HOST_CLUSTER_API dpuLinkerCachePath: /etc/ld.so.cache dpuOptLibraryPath: /usr/opt provisioningController: enableDynamicBFCFGTemplates: true hostAgentDNSPolicy: Default dmsTimeout: 900 nodeSRIOVDevicePluginController: devicePlugin: defaultResourcePrefix: openshift.io disable: false replicas: 1 staticClusterManager: disable: false dpuServiceController: disableHostNetworkReadyNoExecuteTaints: false flannel: podCIDR: $FLANNEL_POD_CIDRApply the resource file:
$ envsubst < dpfoperatorconfig.yaml | oc apply -f -
Verification
Verify that the provisioning controller manager deployment has rolled out:
$ oc rollout status deployment --namespace dpf-operator-system dpf-provisioning-controller-managerExample output
deployment "dpf-provisioning-controller-manager" successfully rolled outVerify that the DPU service controller manager deployment has rolled out:
$ oc rollout status deployment --namespace dpf-operator-system dpuservice-controller-managerExample output
deployment "dpuservice-controller-manager" successfully rolled outVerify that all Operator deployments in the
dpf-operator-systemnamespace have rolled out:NoteYou might need to run this command more than once, because the deployments become available at different times as the Operator reconciles its resources.
$ oc rollout status deployment --namespace dpf-operator-systemOptional: List the pods in the
dpf-operator-systemnamespace to review their status:$ oc get pods -n dpf-operator-systemExample output
NAME READY STATUS RESTARTS AGE argocd-application-controller-0 1/1 Running 0 64m argocd-dex-server-9dd99cc6c-pkl6j 1/1 Running 0 64m argocd-redis-6749d85f98-mw9rc 1/1 Running 0 64m argocd-repo-server-5fd79d655c-9rl26 1/1 Running 0 64m argocd-server-5cc4f69c45-hzgm9 1/1 Running 0 64m bfb-registry 1/1 Running 0 98s dpf-nodesriovdeviceplugin-controller-7c7bb889f6-xk6nm 1/1 Running 0 107s dpf-operator-controller-manager-6969c6d8bc-4njxd 1/1 Running 0 4m54s dpf-provisioning-controller-manager-54b6bdc57f-69lr7 1/1 Running 0 109s dpf-provisioning-controller-manager-54b6bdc57f-fg9f6 1/1 Running 0 109s dpuservice-controller-manager-5d9c4f6f67-wsdzt 1/1 Running 0 108s maintenance-operator-68c794b549-pp2dp 1/1 Running 0 74m static-cm-controller-manager-745c8fd7d5-n8d2z 1/1 Running 0 110s
12.4.4. Create the NodeSRIOVDevicePluginConfig custom resource Copy linkLink copied to clipboard!
You can create a NodeSRIOVDevicePluginConfig custom resource to define how SR-IOV virtual functions on the management cluster worker nodes are allocated to DPF components.
Prerequisites
- You have installed the DPF Operator.
-
You have created the
DPFOperatorConfigresource.
Procedure
Create a file named
nodesriovdevicepluginconfig.yamlwith the following content:apiVersion: noderesources.dpu.nvidia.com/v1alpha1 kind: NodeSRIOVDevicePluginConfig metadata: name: bf3-vfs namespace: dpf-operator-system spec: devicePluginResources: - name: bf3-p0-vfs-mgmt type: vf ranges: - pfIndex: 0 start: 1 end: 1 - name: bf3_vfs type: vf options: isRdma: true ranges: - pfIndex: 0 start: 2 end: 45 - pfIndex: 1 start: 0 end: 45where:
bf3-p0-vfs-mgmt-
Reserves VF index
1on PF0 for DPU management connectivity. bf3_vfs-
Allocates VF indices
2-45on PF0 and VF indices0-45on PF1 for workload traffic with RDMA enabled. pfIndex-
The
pfIndexvalues refer to the first (0) and second (1) physical functions of the BlueField-3 DPU.
Apply the resource file:
$ oc apply -f nodesriovdevicepluginconfig.yaml
Verification
Verify that the
NodeSRIOVDevicePluginConfigresource is created:$ oc get nodesriovdevicepluginconfig -n dpf-operator-systemExample output
bf3-vfs 30s
12.4.5. Create the DPUFlavor custom resource Copy linkLink copied to clipboard!
You can create a DPUFlavor custom resource to define the DPU configuration, including NVConfig parameters, kernel arguments, hugepages settings, and the OVS initialization script. The DPUFlavor also supports an optional configFiles field for custom DPU configuration files.
The nvconfig section contains BlueField-3 firmware parameters that the DPU agent applies by using mlxconfig during provisioning. If any parameter differs from the current firmware configuration, the provisioning controller triggers a system-level reset so that the changes take effect. The following parameters are required for DPF operation:
| Parameter | Value | Description |
|---|---|---|
|
|
|
Switches the BlueField-3 to DPU mode where the ARM cores are active. A value of |
|
|
| Enables SR-IOV on both physical functions. The host agent creates Virtual Functions (VFs) that carry tenant traffic between the host and the DPU. |
|
| Variable |
Number of VFs per physical function. Set this value by using the |
|
|
|
Sets both ports to Ethernet mode. DPF requires Ethernet. InfiniBand ( |
If BlueField-3 already has the correct values, the DPU agent reports that no action is required and does not trigger a reset.
Prerequisites
- You have installed the DPF Operator.
-
You have created the
DPFOperatorConfigresource. - You have set the DPF Operator environment variables. For details, see "DPF Operator installation environment variables".
Procedure
Create a file named
dpuflavor.yamlfor your MTU configuration and apply it.For Standard MTU (1500):
apiVersion: provisioning.dpu.nvidia.com/v1alpha1 kind: DPUFlavor metadata: name: hbn-ovnk namespace: dpf-operator-system annotations: provisioning.dpu.nvidia.com/skip-bfcfg-size-check: "" spec: grub: kernelParameters: - console=hvc0 - console=ttyAMA0 - earlycon=pl011,0x13010000 - iommu.passthrough=1 - cgroup_no_v1=net_prio,net_cls - hugepagesz=2048kB - hugepages=250 nvconfig: - device: '*' parameters: - PF_BAR2_ENABLE=0 - PER_PF_NUM_SF=1 - PF_TOTAL_SF=20 - PF_SF_BAR_SIZE=10 - NUM_PF_MSIX_VALID=0 - PF_NUM_PF_MSIX_VALID=1 - PF_NUM_PF_MSIX=228 - INTERNAL_CPU_MODEL=1 - INTERNAL_CPU_OFFLOAD_ENGINE=0 - SRIOV_EN=1 - NUM_OF_VFS=$NUM_VFS - LAG_RESOURCE_ALLOCATION=1 - LINK_TYPE_P1=ETH - LINK_TYPE_P2=ETH ovs: rawConfigScript: | #!/bin/bash set -e _ovs-vsctl() { ovs-vsctl --timeout 15 "$@" } restart_ovs=false _ovs-get-other-config() { _ovs-vsctl --if-exists get Open_vSwitch . "other_config:$1" 2>/dev/null | tr -d '"' } _ovs-set-other-config() { if [ "$(_ovs-get-other-config "$1")" != "$2" ]; then _ovs-vsctl set Open_vSwitch . "other_config:$1=$2" restart_ovs=true fi } _ovs-remove-other-config() { if [ -n "$(_ovs-get-other-config "$1")" ]; then _ovs-vsctl remove Open_vSwitch . other_config "$1" restart_ovs=true fi } _ovs-set-other-config doca-init true _ovs-set-other-config dpdk-max-memzones 50000 _ovs-set-other-config hw-offload true _ovs-set-other-config pmd-quiet-idle true _ovs-set-other-config max-idle 20000 _ovs-set-other-config max-revalidator 5000 _ovs-set-other-config doca-congestion-threshold 60 _ovs-set-other-config flow-limit 500000 _ovs-set-other-config hw-offload-ct-unidir-udp-enabled true _ovs-remove-other-config default-datapath-type if [ "$restart_ovs" = true ]; then if systemctl list-unit-files openvswitch-switch.service &>/dev/null; then systemctl restart openvswitch-switch elif systemctl list-unit-files openvswitch.service &>/dev/null; then systemctl restart openvswitch fi fi _ovs-vsctl --may-exist add-br br-sfc _ovs-vsctl set bridge br-sfc datapath_type=netdev _ovs-vsctl set bridge br-sfc fail_mode=secure _ovs-vsctl --if-exists del-br br-hbn _ovs-vsctl --may-exist add-br br-hbn _ovs-vsctl set bridge br-hbn datapath_type=netdev _ovs-vsctl set bridge br-hbn fail_mode=secure _ovs-vsctl --may-exist add-port br-sfc p0 _ovs-vsctl set Interface p0 type=dpdk _ovs-vsctl set Interface p0 mtu_request=9216 _ovs-vsctl set Port p0 external_ids:dpf-type=physical # Activate DOCA for OVNK _ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-datapath-type=netdev # setup ovnkube managed bridge, br-dpu (this corresponds to br-ex on ovnk docs) _ovs-vsctl --may-exist add-br br-dpu _ovs-vsctl br-set-external-id br-dpu bridge-id br-dpu _ovs-vsctl br-set-external-id br-dpu bridge-uplink pbrdputobrovn _ovs-vsctl set bridge br-dpu datapath_type=netdev _ovs-vsctl --may-exist add-port br-dpu pf0hpf _ovs-vsctl set Interface pf0hpf type=dpdk # Create OVS bridge (br-ovn) in between the SC managed bridge and OVNK _ovs-vsctl --may-exist add-br br-ovn _ovs-vsctl set bridge br-ovn datapath_type=netdev _ovs-vsctl --may-exist add-port br-ovn pbrovntobrdpu _ovs-vsctl --may-exist add-port br-dpu pbrdputobrovn # Patch br-ovn and br-dpu together _ovs-vsctl set Interface pbrovntobrdpu type=patch options:peer=pbrdputobrovn _ovs-vsctl set Interface pbrdputobrovn type=patch options:peer=pbrovntobrdpuFor Jumbo frames (MTU 9000):
apiVersion: provisioning.dpu.nvidia.com/v1alpha1 kind: DPUFlavor metadata: name: hbn-ovnk namespace: dpf-operator-system annotations: provisioning.dpu.nvidia.com/skip-bfcfg-size-check: "" spec: grub: kernelParameters: - console=hvc0 - console=ttyAMA0 - earlycon=pl011,0x13010000 - iommu.passthrough=1 - cgroup_no_v1=net_prio,net_cls - hugepagesz=2048kB - hugepages=250 nvconfig: - device: '*' parameters: - PF_BAR2_ENABLE=0 - PER_PF_NUM_SF=1 - PF_TOTAL_SF=20 - PF_SF_BAR_SIZE=10 - NUM_PF_MSIX_VALID=0 - PF_NUM_PF_MSIX_VALID=1 - PF_NUM_PF_MSIX=228 - INTERNAL_CPU_MODEL=1 - INTERNAL_CPU_OFFLOAD_ENGINE=0 - SRIOV_EN=1 - NUM_OF_VFS=$NUM_VFS - LAG_RESOURCE_ALLOCATION=1 - NUM_VF_MSIX=30 - LINK_TYPE_P1=ETH - LINK_TYPE_P2=ETH ovs: rawConfigScript: | #!/bin/bash set -e _ovs-vsctl() { ovs-vsctl --timeout 15 "$@" } restart_ovs=false _ovs-get-other-config() { _ovs-vsctl --if-exists get Open_vSwitch . "other_config:$1" 2>/dev/null | tr -d '"' } _ovs-set-other-config() { if [ "$(_ovs-get-other-config "$1")" != "$2" ]; then _ovs-vsctl set Open_vSwitch . "other_config:$1=$2" restart_ovs=true fi } _ovs-remove-other-config() { if [ -n "$(_ovs-get-other-config "$1")" ]; then _ovs-vsctl remove Open_vSwitch . other_config "$1" restart_ovs=true fi } _ovs-set-other-config doca-init true _ovs-set-other-config dpdk-max-memzones 50000 _ovs-set-other-config hw-offload true _ovs-set-other-config pmd-quiet-idle true _ovs-set-other-config max-idle 20000 _ovs-set-other-config max-revalidator 5000 _ovs-set-other-config doca-congestion-threshold 60 _ovs-set-other-config flow-limit 500000 _ovs-set-other-config hw-offload-ct-unidir-udp-enabled true _ovs-remove-other-config default-datapath-type if [ "$restart_ovs" = true ]; then if systemctl list-unit-files openvswitch-switch.service &>/dev/null; then systemctl restart openvswitch-switch elif systemctl list-unit-files openvswitch.service &>/dev/null; then systemctl restart openvswitch fi fi _ovs-vsctl --may-exist add-br br-sfc _ovs-vsctl set bridge br-sfc datapath_type=netdev _ovs-vsctl set bridge br-sfc fail_mode=secure _ovs-vsctl --if-exists del-br br-hbn _ovs-vsctl --may-exist add-br br-hbn _ovs-vsctl set bridge br-hbn datapath_type=netdev _ovs-vsctl set bridge br-hbn fail_mode=secure _ovs-vsctl --may-exist add-port br-sfc p0 _ovs-vsctl set Interface p0 type=dpdk _ovs-vsctl set Interface p0 mtu_request=9216 _ovs-vsctl set Port p0 external_ids:dpf-type=physical # Activate DOCA for OVNK _ovs-vsctl set Open_vSwitch . external-ids:ovn-bridge-datapath-type=netdev # setup ovnkube managed bridge, br-dpu (this corresponds to br-ex on ovnk docs) _ovs-vsctl --may-exist add-br br-dpu _ovs-vsctl br-set-external-id br-dpu bridge-id br-dpu _ovs-vsctl br-set-external-id br-dpu bridge-uplink pbrdputobrovn _ovs-vsctl set bridge br-dpu datapath_type=netdev _ovs-vsctl set Interface br-dpu mtu_request=9000 _ovs-vsctl --may-exist add-port br-dpu pf0hpf _ovs-vsctl set Interface pf0hpf type=dpdk # Create OVS bridge (br-ovn) in between the SC managed bridge and OVNK _ovs-vsctl --may-exist add-br br-ovn _ovs-vsctl set bridge br-ovn datapath_type=netdev _ovs-vsctl set Interface br-ovn mtu_request=9000 _ovs-vsctl --may-exist add-port br-ovn pbrovntobrdpu _ovs-vsctl --may-exist add-port br-dpu pbrdputobrovn # Patch br-ovn and br-dpu together _ovs-vsctl set Interface pbrovntobrdpu type=patch options:peer=pbrdputobrovn _ovs-vsctl set Interface pbrdputobrovn type=patch options:peer=pbrovntobrdpu
Apply the resource file:
$ envsubst < dpuflavor.yaml | oc apply -f -
Verification
Verify that the
DPUFlavorresource is created:$ oc get dpuflavor -n dpf-operator-system
12.4.6. Create the BFB resource Copy linkLink copied to clipboard!
You can create a BFB custom resource to define the DPU image, known as a BlueField Bootstream File, that is downloaded and placed on shared storage for DPU provisioning.
Prerequisites
- You have installed the DPF Operator.
-
You have created the
DPFOperatorConfigresource. - You have set the DPF Operator environment variables. For details, see "DPF Operator installation environment variables".
Procedure
Create a file named
bfb.yamlwith the following content:apiVersion: provisioning.dpu.nvidia.com/v1alpha1 kind: BFB metadata: name: bf-bundle namespace: dpf-operator-system spec: fileName: $BFB_FILENAME url: $BFB_URL versions: atf: 4.15.0-4-g419fbf393 bsp: 4.15.0.13998 doca: 3.4.1 uefi: 4.15.0-19-g37c6f5adb2Set the
BFB_FILENAMEenvironment variable to the file name of the BFB image, which is the base name ofBFB_URL:$ export BFB_FILENAME=$(basename "$BFB_URL")Apply the resource file:
$ envsubst < bfb.yaml | oc apply -f -
Verification
Verify that the BFB image phase is
Ready:$ oc get bfb -n dpf-operator-system bf-bundleExample output
NAME PHASE AGE bf-bundle Ready 3m
12.4.7. Create the DPUDeployment custom resource Copy linkLink copied to clipboard!
You can create a DPUDeployment custom resource as the main orchestration object that connects DPU services with specific BFB images and DPU flavors. The DPUDeployment defines DPU sets for DPU provisioning and configures service chains to deploy services across DPUs.
Prerequisites
- You have installed the DPF Operator.
-
You have created the
DPFOperatorConfigresource. -
You have created the
NodeSRIOVDevicePluginConfigresource. -
You have created the
DPUFlavorresource. -
You have created the
BFBresource and it is in theReadyphase.
Procedure
Create a file named
dpudeployment.yamlwith the following content:apiVersion: svc.dpu.nvidia.com/v1alpha1 kind: DPUDeployment metadata: name: dpudeployment namespace: dpf-operator-system spec: dpus: nodeEffect: drain: true dpuSetStrategy: type: RollingUpdate bfb: bf-bundle flavor: hbn-ovnk dpuSets: - nameSuffix: "dpuset1" dpuNodeSelector: matchLabels: feature.node.kubernetes.io/dpu-enabled: "" dpuAnnotations: noderesources.dpu.nvidia.com/nodesriovdevicepluginconfig: bf3-vfs services: hbn: serviceTemplate: hbn serviceConfiguration: hbn ovn: serviceTemplate: ovn serviceConfiguration: ovn doca-telemetry-service: serviceTemplate: doca-telemetry-service serviceConfiguration: doca-telemetry-service serviceChains: switches: - ports: - serviceInterface: matchLabels: uplink: p0 - service: name: hbn interface: p0_if - ports: - serviceInterface: matchLabels: uplink: p1 - service: name: hbn interface: p1_if - ports: - serviceInterface: matchLabels: port: ovn - service: name: hbn interface: pf2dpu2_ifApply the resource file:
$ oc apply -f dpudeployment.yaml
Verification
Verify the
DPUDeploymentstate:$ oc get DPUDeployment -n dpf-operator-systemExample output
NAME READY PHASE AGE dpudeployment False Pending 2m32sNoteA
Pendingphase is expected at this stage. TheDPUDeploymenttransitions toReadyafter DPU provisioning is complete and all services are deployed.
12.4.8. Create the HBN DPU service configuration Copy linkLink copied to clipboard!
You can create a DPUServiceConfiguration custom resource for the Host-Based Networking (HBN) DPU service. The HBN service provides BGP-based networking on the DPU with ECMP routing support.
HBN and OVN-Kubernetes are currently the only supported DPU network services. The DOCA Telemetry Service (DTS), which you configure in a later step, is deployed for observability and is not a network service.
The DPUServiceTemplate resources are automatically created and managed by the dpf-hcp-provisioner-operator. You only need to create the DPUServiceConfiguration resources.
Prerequisites
- The DPF Operator is installed.
-
The
DPFOperatorConfigresource is created. - The DPF Operator environment variables are set. For details, see "DPF Operator installation environment variables".
Procedure
Create a file named
hbn.yamlwith the following content:apiVersion: svc.dpu.nvidia.com/v1alpha1 kind: DPUServiceConfiguration metadata: name: hbn namespace: dpf-operator-system spec: deploymentServiceName: "hbn" serviceConfiguration: serviceDaemonSet: annotations: k8s.v1.cni.cncf.io/networks: |- [ {"name": "iprequest", "interface": "ip_lo", "cni-args": {"poolNames": ["loopback"], "poolType": "cidrpool"}}, {"name": "iprequest", "interface": "ip_pf2dpu2", "cni-args": {"poolNames": ["pool1"], "poolType": "cidrpool", "allocateDefaultGateway": true}} ] helmChart: values: configuration: perDPUValuesYAML: | - hostnamePattern: "*" values: bgp_peer_group: hbn startupYAMLJ2: | - header: model: BLUEFIELD nvue-api-version: nvue_v1 rev-id: 1.0 version: HBN 2.4.0 - set: interface: lo: ip: address: {{ ipaddresses.ip_lo.ip }}/32: {} type: loopback p0_if,p1_if: type: swp link: mtu: 9216 pf2dpu2_if: ip: address: {{ ipaddresses.ip_pf2dpu2.cidr }}: {} type: swp link: mtu: 9216 router: bgp: autonomous-system: {{ ( ipaddresses.ip_lo.ip.split(".")[3] | int ) + 65101 }} enable: on graceful-restart: mode: full router-id: {{ ipaddresses.ip_lo.ip }} vrf: default: router: bgp: address-family: ipv4-unicast: enable: on redistribute: connected: enable: on ipv6-unicast: enable: on redistribute: connected: enable: on enable: on neighbor: p0_if: peer-group: {{ config.bgp_peer_group }} type: unnumbered p1_if: peer-group: {{ config.bgp_peer_group }} type: unnumbered path-selection: multipath: aspath-ignore: on peer-group: {{ config.bgp_peer_group }}: remote-as: external interfaces: - name: p0_if network: mybrhbn - name: p1_if network: mybrhbn - name: pf2dpu2_if network: mybrhbnApply the resource file:
$ oc apply -f hbn.yamlExample output
dpuserviceconfiguration.svc.dpu.nvidia.com/hbn created
12.4.9. Create the OVN-Kubernetes DPU service configuration Copy linkLink copied to clipboard!
You can create a DPUServiceConfiguration custom resource for the OVN-Kubernetes DPU service. The OVN-Kubernetes service provides pod networking on the DPU.
Prerequisites
- You have installed the DPF Operator.
-
You have created the
DPFOperatorConfigresource. -
You have created the HBN
DPUServiceConfigurationresource. - You have set the DPF Operator environment variables. For details, see "DPF Operator installation environment variables".
Procedure
Create a file named
ovn-k.yamlwith the following content:apiVersion: svc.dpu.nvidia.com/v1alpha1 kind: DPUServiceConfiguration metadata: name: ovn namespace: dpf-operator-system spec: deploymentServiceName: "ovn" serviceConfiguration: helmChart: values: global: enableOvnKubeIdentity: false k8sAPIServer: https://$HOST_CLUSTER_API:6443 podNetwork: 10.128.0.0/14/23 serviceNetwork: 172.30.0.0/16 hostNetworkNamespace: "openshift-host-network" mtu: $OVN_MTU dpuManifests: kubernetesSecretName: "ovn-dpu" vtepCIDR: $VTEP_CIDR hostCIDR: $DPU_HOST_CIDR ipamPool: "pool1" ipamPoolType: "cidrpool" ipamVTEPIPIndex: 0 ipamPFIPIndex: 1 cniBinDir: "/var/lib/cni/bin/" cniConfDir: "/run/multus/cni/net.d"Apply the resource file:
$ envsubst < ovn-k.yaml | oc apply -f -
Verification
Verify that the HBN and OVN-Kubernetes service configurations are created:
$ oc get dpuserviceconfiguration -n dpf-operator-system
12.4.10. Create the DOCA Telemetry Service DPU service configuration Copy linkLink copied to clipboard!
You can create a DPUServiceConfiguration custom resource for the DOCA Telemetry Service. The DOCA Telemetry Service provides metrics collection from the DPUs by using Prometheus.
The DPUServiceTemplate for DOCA Telemetry Service is automatically created and managed by the dpf-hcp-provisioner-operator controller. The operator uses the correct chart and image versions for the installed DPF version. You only need to create the DPUServiceConfiguration resource.
Prerequisites
- You have installed the DPF Operator.
-
You have created the
DPFOperatorConfigresource. - You have set the DPF Operator environment variables. For details, see "DPF Operator installation environment variables".
Procedure
Create a file named
dts.yamlwith the following content:apiVersion: svc.dpu.nvidia.com/v1alpha1 kind: DPUServiceConfiguration metadata: name: doca-telemetry-service namespace: dpf-operator-system spec: deploymentServiceName: "doca-telemetry-service" serviceConfiguration: configPorts: ports: - name: httpserverport port: 9189 protocol: TCP serviceType: NoneApply the resource file:
$ oc apply -f dts.yaml
Verification
Verify that the DOCA Telemetry Service configuration is created:
$ oc get dpuserviceconfiguration -n dpf-operator-system doca-telemetry-service
12.4.11. Create the OVN-Kubernetes credential request and role bindings Copy linkLink copied to clipboard!
To authenticate with the management cluster API server, create a DPUServiceCredentialRequest custom resource and the associated role bindings to enable the OVN-Kubernetes DPU service on the hosted cluster. The ClusterRoleBinding grants the required permissions for OVN node network operations.
Prerequisites
- You have installed the DPF Operator.
-
You have created the
DPFOperatorConfigresource.
Procedure
Create a file named
dpucredentialreq.yamlwith the following content:apiVersion: svc.dpu.nvidia.com/v1alpha1 kind: DPUServiceCredentialRequest metadata: name: ovn-dpu namespace: dpf-operator-system spec: serviceAccount: name: ovn-kubernetes-node-dpu-service namespace: openshift-ovn-kubernetes duration: 24h type: tokenFile secret: name: ovn-dpu namespace: dpf-operator-system metadata: labels: dpu.nvidia.com/image-pull-secret: "" --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: openshift-ovn-kubernetes-node-limited-dpu-service namespace: openshift-ovn-kubernetes roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: openshift-ovn-kubernetes-node-limited subjects: - kind: ServiceAccount name: ovn-kubernetes-node-dpu-service namespace: openshift-ovn-kubernetes --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: ovn-kubernetes-node-limited-binding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: openshift-ovn-kubernetes-node-limited subjects: - kind: ServiceAccount name: ovn-kubernetes-node-dpu-service namespace: openshift-ovn-kubernetesApply the resource file:
$ oc apply -f dpucredentialreq.yaml
Verification
Verify that the credential request and role bindings are created:
$ oc get dpuservicecredentialrequest -n dpf-operator-system$ oc get clusterrolebinding ovn-kubernetes-node-limited-binding
12.4.12. Create the DPUServiceInterface custom resources Copy linkLink copied to clipboard!
You can create DPUServiceInterface custom resources to define interface objects that are specified in service chains. You must create physical interface resources for the DPU ports and an OVN-Kubernetes interface resource for host workloads.
Prerequisites
- You have installed the DPF Operator.
-
You have created the
DPFOperatorConfigresource.
Procedure
Create a file named
physical-if.yamlwith the following content to define the physical DPU port interfaces:apiVersion: svc.dpu.nvidia.com/v1alpha1 kind: DPUServiceInterface metadata: name: p0 namespace: dpf-operator-system spec: template: spec: template: metadata: labels: uplink: "p0" spec: interfaceType: physical physical: interfaceName: p0 --- apiVersion: svc.dpu.nvidia.com/v1alpha1 kind: DPUServiceInterface metadata: name: p1 namespace: dpf-operator-system spec: template: spec: template: metadata: labels: uplink: "p1" spec: interfaceType: physical physical: interfaceName: p1Apply the physical interface resource file:
$ oc apply -f physical-if.yamlCreate a file named
ovnk-if.yamlwith the following content to define the OVN-Kubernetes interface:apiVersion: svc.dpu.nvidia.com/v1alpha1 kind: DPUServiceInterface metadata: name: ovn namespace: dpf-operator-system spec: template: spec: template: metadata: labels: port: ovn spec: interfaceType: ovnApply the OVN-Kubernetes interface resource file:
$ oc apply -f ovnk-if.yaml
Verification
Verify that all
DPUServiceInterfaceresources are created:$ oc get dpuserviceinterface -n dpf-operator-system
12.4.13. Create the DPUServiceNAD resource Copy linkLink copied to clipboard!
Create a DPUServiceNAD custom resource to define the network attachment available to DPU services on the hosted cluster. The DPUServiceNAD resource maps to an Open vSwitch (OVS) bridge on the DPU and specifies the resource type, IP address management (IPAM) mode, and maximum transmission unit (MTU) configuration:
-
mybrhbnmaps to thebr-hbnbridge, used by the HBN service. IPAM is disabled because IP allocation is handled byDPUServiceIPAM.
Prerequisites
- You have installed the DPF Operator.
-
You have created the
DPFOperatorConfigresource. - You have set the DPF Operator environment variables. For details, see "DPF Operator installation environment variables".
Procedure
Create a file named
dpuservice-nad.yamlwith the following content:apiVersion: svc.dpu.nvidia.com/v1alpha1 kind: DPUServiceNAD metadata: name: mybrhbn namespace: dpf-operator-system spec: resourceType: sf ipam: false bridge: "br-hbn" serviceMTU: $NODES_MTUApply the resource file:
$ envsubst < dpuservice-nad.yaml | oc apply -f -
Verification
Verify that the
DPUServiceNADresource is created:$ oc get dpuservicenad mybrhbn -n dpf-operator-systemExample output
NAME READY AGE mybrhbn True 2m
12.4.14. Create the DPUServiceIPAM resources Copy linkLink copied to clipboard!
You can create DPUServiceIPAM custom resources to configure IP address management for DPU services. Two IPAM pools are required: one for the VTEP network used by the high-speed data plane, and one for loopback addresses used by the HBN service.
Prerequisites
- You have installed the DPF Operator.
-
You have created the
DPFOperatorConfigresource. - You have set the DPF Operator environment variables. For details, see "DPF Operator installation environment variables".
Procedure
Create a file named
dpuservice-ipam.yamlwith the following content:--- apiVersion: svc.dpu.nvidia.com/v1alpha1 kind: DPUServiceIPAM metadata: name: pool1 namespace: dpf-operator-system spec: ipv4Network: network: $VTEP_CIDR gatewayIndex: 3 prefixSize: 29 --- apiVersion: svc.dpu.nvidia.com/v1alpha1 kind: DPUServiceIPAM metadata: name: loopback namespace: dpf-operator-system spec: ipv4Network: network: "11.0.0.0/24" prefixSize: 32Apply the resource file:
$ envsubst < dpuservice-ipam.yaml | oc apply -f -
Verification
Verify that the
DPUServiceIPAMresources are created:$ oc get dpuserviceipam -n dpf-operator-system
12.5. Provision the DPU hosted cluster Copy linkLink copied to clipboard!
The DPF HCP Provisioner Operator automates the creation and lifecycle management of a hosted control plane cluster for DPU nodes.
12.5.1. DPU hosted cluster provisioning with the DPF HCP Provisioner Operator Copy linkLink copied to clipboard!
The DPF HCP Provisioner Operator abstracts hosted control plane complexity for DPF by orchestrating the full lifecycle of hosted clusters for DPU environments. The Operator treats the hosted control plane as a black box and maintains a 1:1:1 relationship: each DPFHCPProvisioner custom resource maps to exactly one DPUCluster and one HostedCluster.
The Operator provides the following capabilities:
- HostedCluster lifecycle management
-
Creates, updates, and deletes
HostedCluster,NodePool, and associated secret resources. - Automatic CSR approval
- Approves Certificate Signing Requests from DPU worker nodes joining the hosted cluster.
- BlueField OpenShift Container Platform layer image lookup
- Matches OpenShift Container Platform release images to corresponding BlueField container images by using container registry tag lookup.
- Kubeconfig provisioning
-
Extracts the hosted cluster admin kubeconfig, stores it in a secret, and sets the
spec.kubeconfigfield of theDPUClustercustom resource to reference that secret, enabling the management cluster to communicate with the DPU hosted cluster. - MetalLB configuration
-
Deploys
IPAddressPoolandL2Advertisementresources forLoadBalancerservice exposure. - Ignition generation
- Generates BlueField-specific ignition configurations from hosted control plane ignition for DPU node provisioning.
- Status translation
-
Mirrors
HostedClusterconditions toDPFHCPProvisionerstatus without exposing hosted control plane internals.
12.5.2. Install the DPF HCP Provisioner Operator Copy linkLink copied to clipboard!
You can install the DPF HCP Provisioner Operator by using a Helm chart. The operator manages the lifecycle of hosted clusters for DPU environments.
Prerequisites
- The Multicluster Engine (MCE) Operator is installed and hosted control planes is enabled.
-
The MetalLB Operator is installed and a
MetalLBinstance is created. - A storage class is available for etcd persistent volumes, such as LVM Storage or an equivalent.
- The DPF Operator is installed and DPF CRDs are available.
-
The Helm CLI (
helm) is installed on your workstation. -
You have a pull secret file that includes credentials for
registry.redhat.io. Helm reads its registry credentials from this file, which is separate from the container runtime configuration.
Procedure
Set the
OPENSHIFT_PULL_SECRETenvironment variable to the path of your pull secret file:$ export OPENSHIFT_PULL_SECRET="/root/pull-secret.txt"Install the operator by using Helm:
$ helm upgrade --install dpf-hcp-provisioner-operator \ oci://registry.redhat.io/dpu-kit-for-nvidia/dpf-hcp-provisioner-chart \ --registry-config "${OPENSHIFT_PULL_SECRET}" \ --version 4.22.0 \ --namespace dpf-hcp-provisioner-system \ --create-namespace \ --set provisionerConfig.manageDPUServiceTemplates=trueExample output
NAME: dpf-hcp-provisioner-operator LAST DEPLOYED: ... NAMESPACE: dpf-hcp-provisioner-system STATUS: deployedNoteThe Helm chart creates a
DPFHCPProvisionerConfigsingleton custom resource nameddefaultthat defines the Operator-wide configuration. This resource controls settings such as the BlueField OpenShift Container Platform layer image repository, MetalLB integration, andDPUServiceTemplatemanagement. To customize these settings, modify theprovisionerConfigsection in your Helmvalues.yamlfile before running thehelm upgrade --installcommand.
Verification
Verify that the Operator pod is running:
$ oc get pods -n dpf-hcp-provisioner-systemExample output
NAME READY STATUS RESTARTS AGE dpf-hcp-provisioner-operator-xxx-yyy 1/1 Running 0 1mVerify that the
DPFHCPProvisionerConfigsingleton resource was created and thatmanageDPUServiceTemplatesis set totrue:$ oc get dpfhcpprovisionerconfigs.provisioning.dpu.hcp.io default -o yamlExample output
apiVersion: provisioning.dpu.hcp.io/v1alpha1 kind: DPFHCPProvisionerConfig metadata: name: default labels: app.kubernetes.io/managed-by: Helm helm.sh/chart: dpf-hcp-provisioner-chart-4.22.0 spec: blueFieldOCPLayerRepo: registry.redhat.io/dpu-kit-for-nvidia/bluefield-ocp-layer-rhel101 disableMetalLB: false2 manageDPUServiceTemplates: true3 where:
blueFieldOCPLayerRepo- The container registry repository for BlueField OpenShift Container Platform layer images. The operator queries this repository for an image tag that matches the OpenShift Container Platform version.
disableMetalLB- Disables MetalLB configuration even when a virtual IP is specified.
manageDPUServiceTemplates-
Controls whether the operator creates and manages the
DPUServiceTemplateresources for OVN-Kubernetes, DTS, and HBN in theDPUClusternamespace. This value must betrueotherwise DPU provisioning fails because the requiredDPUServiceTemplateresources are missing. This field is deprecated and will be removed in a future release, at which pointDPUServiceTemplatemanagement is always enabled.
12.5.3. Hosted cluster provisioning environment variables Copy linkLink copied to clipboard!
The following environment variables are used throughout the hosted cluster provisioning procedures. These environment variables must be set before you create secrets, the DPUCluster resource, or the DPFHCPProvisioner resource.
| Variable | Description | Example value |
|---|---|---|
|
| The name of the hosted DPU cluster. |
|
|
| The OpenShift Container Platform version for the hosted cluster. |
|
|
| The namespace where hosted cluster resources are created. |
|
|
| The base DNS domain for the hosted cluster. |
|
|
|
Optional. The BlueField OpenShift Container Platform layer container image URL. When set, this value is used as |
|
|
| The storage class used for etcd persistent volume claims. |
|
|
|
The OpenShift Container Platform release image for the hosted cluster. Derived from |
|
|
| The name of the Kubernetes secret that contains the pull secret for the hosted cluster. |
|
|
| The file path to the pull secret JSON file on your workstation. |
|
|
| The name of the Kubernetes secret that contains the SSH public key for the hosted cluster. |
|
|
| The file path to the SSH public key file on your workstation. Use ed25519 keys for better security. |
|
|
| The virtual IP address for the hosted cluster API server, allocated from the management cluster subnet. |
|
You must set all environment variables in your terminal session before you proceed.
$ export HOSTED_CLUSTER_NAME="dpf-hosted"
$ export OPENSHIFT_VERSION="4.22.7"
$ export CLUSTERS_NAMESPACE="clusters"
$ export BASE_DOMAIN="example.com"
$ export BLUEFIELD_OCP_IMAGE="<GA-BLUEFIELD-OCP-IMAGE>"
$ export ETCD_STORAGE_CLASS="lvms-vg1"
$ export OCP_RELEASE_IMAGE="quay.io/openshift-release-dev/ocp-release:${OPENSHIFT_VERSION}-multi"
$ export PULL_SECRET_NAME="my-pull-secret"
$ export OPENSHIFT_PULL_SECRET="/root/pull-secret.txt"
$ export SSH_KEY_SECRET_NAME="my-ssh-key"
$ export SSH_KEY="/root/.ssh/id_ed25519.pub"
$ export HOSTED_CLUSTER_VIP="192.168.1.200"
$ export DPU_HOST_CIDR="10.0.110.0/24"
$ export VTEP_CIDR="10.0.120.0/22"
$ export NODES_MTU="1500" # Use 1500 for standard MTU, 9000 for jumbo frames
$ export FLANNEL_POD_CIDR="10.132.0.0/14"
12.5.4. Create secrets for the hosted cluster Copy linkLink copied to clipboard!
You must create a pull secret and an SSH key secret in the clusters namespace before provisioning the hosted cluster. The DPFHCPProvisioner resource references these secrets during hosted cluster creation.
The BlueField OpenShift Container Platform layer image referenced by BLUEFIELD_OCP_IMAGE might require authentication to the Quay or Red Hat registry. Ensure that the pull secret includes credentials for that image registry.
Prerequisites
- You have set the environment variables described in "Hosted cluster provisioning environment variables".
-
You have a valid OpenShift Container Platform pull secret file at the path specified by
OPENSHIFT_PULL_SECRET. -
You have an SSH public key file at the path specified by
SSH_KEY.
Procedure
Create the clusters namespace:
$ oc create namespace $CLUSTERS_NAMESPACECreate the pull secret:
$ oc create secret generic $PULL_SECRET_NAME \ --from-file=.dockerconfigjson=$OPENSHIFT_PULL_SECRET \ --type=Opaque \ -n $CLUSTERS_NAMESPACECreate the SSH key secret:
$ oc create secret generic $SSH_KEY_SECRET_NAME \ --from-file=id_rsa.pub=$SSH_KEY \ --type=Opaque \ -n $CLUSTERS_NAMESPACENoteThe
id_rsa.pubsecret data key is a fixed name that the provisioner expects and it does not require an RSA key. TheSSH_KEYvariable can point to any supported public key file, such as an Ed25519 key.
Verification
Verify that the secrets were created in the clusters namespace:
$ oc get secrets -n $CLUSTERS_NAMESPACEExample output
NAME TYPE DATA AGE my-pull-secret Opaque 1 10s my-ssh-key Opaque 1 5s
12.5.5. Create the DPUCluster custom resource Copy linkLink copied to clipboard!
The DPUCluster resource tells the DPF Operator about the hosted cluster where DPU services will run.
Do not set the spec.kubeconfig field. After you create the hosted cluster, the DPF HCP Provisioner Operator automatically creates the admin kubeconfig secret in the dpf-operator-system namespace and sets the spec.kubeconfig field of this resource to reference it.
Prerequisites
- You have set the environment variables described in "Hosted cluster provisioning environment variables".
- You have installed the DPF Operator.
Procedure
Create a file named
dpucluster.yamlwith the following content:apiVersion: provisioning.dpu.nvidia.com/v1alpha1 kind: DPUCluster metadata: name: $HOSTED_CLUSTER_NAME namespace: dpf-operator-system spec: type: static maxNodes: 10Apply the resource with variable substitution:
$ envsubst < dpucluster.yaml | oc apply -f -
Verification
Verify that the
DPUClusterresource was created:$ oc get dpucluster -n dpf-operator-system
12.5.6. Create the DPFHCPProvisioner custom resource Copy linkLink copied to clipboard!
The DPFHCPProvisioner custom resource triggers the creation of the complete hosted cluster infrastructure. This includes the HostedCluster, the MetalLB IPAddressPool, the L2Advertisement, and kubeconfig injection into the DPUCluster.
Prerequisites
- You have set the environment variables described in "Hosted cluster provisioning environment variables".
- You have installed the DPF HCP Provisioner Operator and it is running.
- You have created the pull secret and SSH key secret in the clusters namespace.
-
You have created the
DPUClusterresource in thedpf-operator-systemnamespace.
Procedure
Create a file named
dpfhcpprovisioner.yamlwith the following content:apiVersion: provisioning.dpu.hcp.io/v1alpha1 kind: DPFHCPProvisioner metadata: name: $HOSTED_CLUSTER_NAME namespace: $CLUSTERS_NAMESPACE spec: baseDomain: $BASE_DOMAIN dpuClusterRef: name: $HOSTED_CLUSTER_NAME namespace: dpf-operator-system dpuDeploymentRef: name: dpudeployment namespace: dpf-operator-system etcdStorageClass: $ETCD_STORAGE_CLASS ocpReleaseImage: $OCP_RELEASE_IMAGE pullSecretRef: name: $PULL_SECRET_NAME sshKeySecretRef: name: $SSH_KEY_SECRET_NAME virtualIP: $HOSTED_CLUSTER_VIPwhere:
baseDomain- Specifies the base DNS domain for the hosted cluster.
dpuClusterRef-
Specifies a reference to the
DPUClusterresource that represents the DPU hosted cluster. dpuDeploymentRef-
Specifies a reference to the
DPUDeploymentresource in thedpf-operator-systemnamespace. etcdStorageClass- Specifies the storage class for etcd persistent volume claims.
ocpReleaseImage- Specifies the OpenShift Container Platform release image for the hosted cluster.
pullSecretRef- Specifies the name of the pull secret in the same namespace.
sshKeySecretRef- Specifies the name of the SSH key secret in the same namespace.
virtualIP- Specifies the virtual IP address for the hosted cluster API server, allocated from the management cluster subnet.
The following optional fields use working defaults and do not need to be specified unless you want to override them:
controlPlaneAvailabilityPolicy-
Specifies the availability policy for the hosted cluster control plane. This optional parameter defaults to
HighlyAvailable. Set it toSingleReplicafor a single-node control plane, in which casevirtualIPis not required. flannelEnabled-
Specifies whether to enable Flannel networking in the hosted cluster. This optional parameter defaults to
true. clusterNetwork-
Specifies the pod network CIDR for the hosted cluster. This optional parameter defaults to
10.128.0.0/14. serviceNetwork-
Specifies the service network CIDR for the hosted cluster. This optional parameter defaults to
172.30.0.0/16. machineNetwork- Specifies the machine network CIDR for the hosted cluster. This optional parameter uses the management cluster network by default.
nodeSelector- Specifies a node selector for scheduling the hosted control plane pods. This optional parameter uses default scheduling by default.
Apply the resource with variable substitution:
$ envsubst < dpfhcpprovisioner.yaml | oc apply -f -
12.5.7. Verify hosted cluster creation Copy linkLink copied to clipboard!
After creating the DPFHCPProvisioner resource, you can monitor its status to verify that the hosted cluster is provisioned and becomes ready. The provisioning process can take up to 30 minutes.
Prerequisites
-
You have created the
DPFHCPProvisionerresource in the clusters namespace.
Procedure
Monitor the
DPFHCPProvisionerstatus:$ oc get dpfhcpprovisioner -n ${CLUSTERS_NAMESPACE}Example output
NAME PHASE READY HOSTEDCLUSTER AGE dpf-hosted Provisioning False dpf-hosted 2mWait for the
DPFHCPProvisionerto reach theReadyphase:$ oc wait dpfhcpprovisioner ${HOSTED_CLUSTER_NAME} -n ${CLUSTERS_NAMESPACE} \ --for=jsonpath='{.status.phase}'=Ready --timeout=30mExample output
dpfhcpprovisioner.provisioning.dpu.hcp.io/dpf-hosted condition met
Verification
Confirm that the
DPUClusteris ready:$ oc get dpucluster ${HOSTED_CLUSTER_NAME} -n dpf-operator-systemA
Readystatus indicates that the operator created the admin kubeconfig secret referenced by theDPUClusterresource and that the hosted cluster API is reachable, which is the prerequisite for DPU worker nodes to join:Confirm that the admin kubeconfig secret referenced by the
DPUClusterwas created in thedpf-operator-systemnamespace:$ oc get secret ${HOSTED_CLUSTER_NAME}-admin-kubeconfig -n dpf-operator-systemExample output
NAME TYPE DATA AGE dpf-hosted-admin-kubeconfig Opaque 1 10m
12.5.8. Verify DPU service reconciliation Copy linkLink copied to clipboard!
After the DPU hosted cluster and DPUCluster are ready, verify that the DPU services, IPAM pools, service interfaces, and service chains created for the DPUDeployment are reconciled.
Prerequisites
-
You have created the DPF custom resources:
DPFOperatorConfig,NodeSRIOVDevicePluginConfig,DPUFlavor,BFB, andDPUDeployment. - You have created the HBN, OVN-Kubernetes, and DTS DPU service resources.
-
The
DPUClusteris ready. -
You have access to the management cluster as a user with the
cluster-adminrole. -
You have installed the
ocCLI.
You might need to run the commands multiple times to ensure that the condition is met, because the DPU services can take time to converge.
Procedure
Verify that the
DPUServiceresources are created and reconciled:$ oc wait --for=condition=ApplicationsReconciled \ --namespace dpf-operator-system dpuservices \ -l svc.dpu.nvidia.com/owned-by-dpudeployment=dpf-operator-system_dpudeploymentVerify that the
DPUServiceIPAMresources are reconciled:$ oc wait --for=condition=DPUIPAMObjectReconciled \ --namespace dpf-operator-system dpuserviceipam --allVerify that the
DPUServiceInterfaceresources are reconciled:$ oc wait --for=condition=ServiceInterfaceSetReconciled \ --namespace dpf-operator-system dpuserviceinterface --allVerify that the
DPUServiceChainresources are reconciled:$ oc wait --for=condition=ServiceChainSetReconciled \ --namespace dpf-operator-system dpuservicechain --all
12.6. Add worker nodes and provision DPUs Copy linkLink copied to clipboard!
After the DPF Operator and the hosted cluster are configured, adjust the OVN-Kubernetes CNI settings, add DPU-equipped worker nodes to the management cluster, and provision the DPUs.
12.6.1. Enable the OVN-Kubernetes resource injector Copy linkLink copied to clipboard!
You can install the OVN-Kubernetes resource injector by using Helm to deploy a mutating admission webhook that automatically injects SR-IOV virtual function resource requests and network attachment annotations into each pod scheduled to a worker node.
Virtual function resource capacity on worker nodes is provided by the NodeSRIOVDevicePluginConfig resource, which replaces the manual SR-IOV device plugin DaemonSet and control plane node patching used in earlier DPF versions.
Prerequisites
-
You have access to the management cluster as a user with the
cluster-adminrole. -
You have installed the
ocCLI. -
You have installed the
helmCLI. - You have set the DPF Operator environment variables. For details, see "DPF Operator installation environment variables".
-
You have created the
NodeSRIOVDevicePluginConfigresource.
Procedure
Install the OVN-Kubernetes resource injector by using Helm:
$ helm upgrade --install -n openshift-ovn-kubernetes ovn-kubernetes \ "$OVN_TEMPLATE_CHART_URL/ovn-kubernetes-chart" \ --version "${OVN_CHART_VERSION}" \ --skip-crds \ --set ovn-kubernetes-resource-injector.enabled=true \ --set ovn-kubernetes-resource-injector.resourceName="openshift.io/bf3_vfs" \ --set ovn-kubernetes-resource-injector.prioritizeOffloading=false \ --set ovn-kubernetes-resource-injector.controllerManager.hostNetwork=true \ --set ovn-kubernetes-resource-injector.controllerManager.webhookPort="19443" \ --set ovn-kubernetes-resource-injector.controllerManager.healthProbeBindAddress=":18081" \ --set ovn-kubernetes-resource-injector.controllerManager.webhook.image.pullPolicy=IfNotPresent \ --set "ovn-kubernetes-resource-injector.controllerManager.webhook.args={--leader-elect,--metrics-bind-address=:29091}" \ --set nodeWithDPUManifests.enabled=false \ --set nodeWithoutDPUManifests.enabled=false \ --set dpuManifests.enabled=false \ --set controlPlaneManifests.enabled=false \ --set commonManifests.enabled=falseExample output
NAME: ovn-kubernetes LAST DEPLOYED: Sun Nov 2 17:10:29 2025 NAMESPACE: openshift-ovn-kubernetes STATUS: deployed REVISION: 1 DESCRIPTION: Install complete TEST SUITE: None
Verification
Verify the resource injector mutating webhook configuration was applied:
$ oc get mutatingwebhookconfiguration | grep ovnExample output
NAME WEBHOOKS AGE ovn-kubernetes-ovn-kubernetes-resource-injector 1 22h
12.6.2. OVN-Kubernetes DPU-Host mode Copy linkLink copied to clipboard!
DPU-Host mode on worker nodes with accelerated OVN-Kubernetes CNI is automatically configured by the DPF provisioning controller.
When the DPFOperatorConfig resource is created and worker nodes with the worker-dpu label are provisioned, the DPF provisioning controller automatically configures the required settings for DPU-Host mode, including the network node identity and hardware offload configuration.
12.6.3. Add worker nodes by using the Bare Metal Operator Copy linkLink copied to clipboard!
You can add DPU-equipped worker nodes to the management cluster by creating BareMetalHost resources that the Bare Metal Operator provisions.
Prerequisites
-
You have access to the management cluster as a user with the
cluster-adminrole. -
You have installed the
ocCLI. - You have installed the Bare Metal Operator on the management cluster.
- Physical worker servers with Redfish-compatible BMC, iDRAC, or iLO access are available.
- Network connectivity exists from the management cluster to the worker BMC interfaces.
- You have the BMC IP address and access credentials for each server.
- You have the MAC address of the management network interface for each server.
- You have the name of the root disk device for each server.
Procedure
Set the following environment variables for the worker node:
$ export BMC_IP=<bmc_ip_address> $ export BMC_USER=<bmc_username> $ export BMC_PASSWORD=<bmc_password> $ export WORKER_NAME=<worker_name> $ export BOOT_MAC=<management_interface_mac> $ export ROOT_DEVICE=<root_device_path>where:
<bmc_ip_address>- Specifies the IP address of the worker node BMC interface.
<bmc_username>- Specifies the username for BMC access.
<bmc_password>- Specifies the password for BMC access.
<worker_name>-
Specifies a name for the worker node, such as
worker-01. <management_interface_mac>-
Specifies the MAC address of the out-of-band management interface, such as
00:00:5E:00:53:01. <root_device_path>-
Specifies the path to the root disk device, such as
/dev/nvme0n1.
Verify BMC connectivity from one of the control plane nodes:
$ ping $BMC_IP$ curl -k https://$BMC_IP/redfish/v1/$ curl -k -u $BMC_USER:$BMC_PASSWORD https://$BMC_IP/redfish/v1/SystemsVerify that the Bare Metal Operator is available:
$ oc get clusteroperator baremetalCreate a file named
provisioning.yamlwith the following content to disable the provisioning network:apiVersion: metal3.io/v1alpha1 kind: Provisioning metadata: name: provisioning-configuration spec: provisioningNetwork: "Disabled" watchAllNamespaces: falseImportantWhen
provisioningNetworkis set toDisabled, servers boot by using Redfish virtual media instead of PXE.Apply the
Provisioningresource:$ oc apply -f provisioning.yamlCreate a file named
bmc-secret.yamlwith the following content to store the BMC credentials:apiVersion: v1 kind: Secret metadata: name: ${WORKER_NAME}-bmc-secret namespace: openshift-machine-api type: Opaque stringData: username: ${BMC_USER} password: ${BMC_PASSWORD}Apply the BMC credentials secret:
$ envsubst < bmc-secret.yaml | oc apply -f -Create a file named
baremetalhost.yaml. TheuserDatasecret determines the node type:For a DPU-equipped worker node, reference the
worker-dpu-user-data-managedsecret:apiVersion: metal3.io/v1alpha1 kind: BareMetalHost metadata: name: $WORKER_NAME namespace: openshift-machine-api spec: online: true bootMACAddress: $BOOT_MAC rootDeviceHints: deviceName: $ROOT_DEVICE bmc: address: redfish-virtualmedia+https://$BMC_IP credentialsName: $WORKER_NAME-bmc-secret disableCertificateVerification: true customDeploy: method: install_coreos userData: name: worker-dpu-user-data-managed namespace: openshift-machine-apiFor a regular worker node without a DPU, reference the
worker-user-data-managedsecret instead:apiVersion: metal3.io/v1alpha1 kind: BareMetalHost metadata: name: $WORKER_NAME namespace: openshift-machine-api spec: online: true bootMACAddress: $BOOT_MAC rootDeviceHints: deviceName: $ROOT_DEVICE bmc: address: redfish-virtualmedia+https://$BMC_IP credentialsName: $WORKER_NAME-bmc-secret disableCertificateVerification: true customDeploy: method: install_coreos userData: name: worker-user-data-managed namespace: openshift-machine-apiImportantAdding a regular worker node without a DPU is a Technology Preview feature.
Apply the
BareMetalHostresource:$ envsubst < baremetalhost.yaml | oc apply -f -
Verification
Monitor the provisioning progress:
$ oc get bmh -n openshift-machine-api -wExample output
NAME STATE CONSUMER ONLINE ERROR AGE worker-01 registering true 10s worker-01 inspecting true 15s worker-01 preparing true 20s worker-01 available true 30s worker-01 provisioning true 1m worker-01 provisioned true 10m
12.6.4. Approve worker node CSRs Copy linkLink copied to clipboard!
You must approve the pending certificate signing requests (CSRs) for worker nodes that join the management cluster.
Worker nodes provisioned by using a BareMetalHost resource do not have an associated Machine object, so the default OpenShift machine approver does not automatically approve their certificate signing requests (CSRs). You must manually approve the kube-apiserver-client-kubelet CSR from the node-bootstrapper service account and the kubelet-serving CSR from the node for each worker node.
Prerequisites
-
You have access to the management cluster as a user with the
cluster-adminrole. -
You have installed the
ocCLI. - Worker nodes are booted and attempting to join the management cluster.
Procedure
Watch for pending CSRs:
$ oc get csr -wApprove all pending CSRs:
$ oc get csr -o go-template='{{range .items}}{{if not .status}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}' | xargs oc adm certificate approveExample output
certificatesigningrequest.certificates.k8s.io/csr-27bgq approved certificatesigningrequest.certificates.k8s.io/csr-69g65 approved certificatesigningrequest.certificates.k8s.io/csr-7r862 approved certificatesigningrequest.certificates.k8s.io/csr-f5vk7 approvedRepeat this step until no pending CSRs remain. Each node typically generates multiple CSRs.
Verify that the worker nodes joined the cluster:
$ oc get nodesExample output
NAME STATUS ROLES AGE VERSION host-worker1 NotReady worker 68s v1.35.6 host-worker2 NotReady worker 75s v1.35.6 master-0 Ready control-plane,master,worker 4d22h v1.35.6 master-1 Ready control-plane,master,worker 4d21h v1.35.6 master-2 Ready control-plane,master,worker 4d22h v1.35.6NoteThe worker nodes show a status of
NotReadyuntil the DPU provisioning process is fully completed and all OVN-Kubernetes CNI components on the host and the DPU are running. Do not proceed to the next steps until all pending CSRs are approved.
12.6.5. Verify DPU provisioning Copy linkLink copied to clipboard!
After the worker nodes join the management cluster, the DPUSet controller automatically detects nodes with the feature.node.kubernetes.io/dpu-enabled label, which the Node Feature Discovery Operator applies to DPU-equipped nodes. The controller then creates a DPU object for each node and starts the provisioning process. You can monitor the provisioning stages to verify progress.
Prerequisites
-
You have access to the management cluster as a user with the
cluster-adminrole. -
You have installed the
ocCLI. - The worker node CSRs are approved and the nodes have joined the management cluster.
Procedure
Watch for
DPUobject creation:$ oc get dpu -n dpf-operator-system -wExample output
NAME READY OPERATIONAL PHASE AGE <node-name>-<dpu-id> Unknown Node Effect 25s <node-name>-<dpu-id> Unknown Initialize Interface 26s <node-name>-<dpu-id> Unknown Config FW Parameters 28s <node-name>-<dpu-id> Unknown Prepare BFB 28s <node-name>-<dpu-id> Unknown OS Installing 5m28s <node-name>-<dpu-id> Unknown DPU Config 15m <node-name>-<dpu-id> Unknown Rebooting 26m <node-name>-<dpu-id> Unknown Host Network Configuration 27m <node-name>-<dpu-id> False DPU Cluster Config 64m <node-name>-<dpu-id> Unknown Node Effect Removal 71m <node-name>-<dpu-id> True True Ready 71mThe
DPUobjects progress through the following provisioning stages:Initializing-
The
DPUobject is created. OS Installing- The BFB installation is in progress.
Rebooting- The host and DPU are resetting.
DPU Cluster Config- The DPU Kubernetes node join procedure is in progress. Manual CSR approval is required during this stage.
Host Network Configuration- Networking configuration adjustments are applied on the host.
Ready- The DPU is successfully provisioned and ready to use.
Error- Provisioning failed. Check events and conditions for details.
ImportantWhen the provisioning stage reaches
DPU Cluster Config, proceed to "Configure authorization for the hosted cluster" and "Approve DPU node CSRs" to complete the DPU node join process.Monitor detailed provisioning progress:
$ oc -n dpf-operator-system exec deploy/dpf-operator-controller-manager -- /dpfctl describe dpudeploymentsOptional: View detailed status for a specific
DPUobject:In the following command, replace
<dpu_name>with the name of theDPUresource:$ oc describe dpu -n dpf-operator-system <dpu_name>Optional: Follow the provisioning controller logs for a specific DPU:
In the following command, replace
<dpu_name>with the name of theDPUresource:$ oc logs -n dpf-operator-system -l dpu.nvidia.com/component=dpf-provisioning-controller-manager --tail=-1 -f | grep <dpu_name>
12.6.6. Configure authorization for the hosted cluster Copy linkLink copied to clipboard!
DPF services running on DPU nodes require privileged access to host networking and devices. You must create a ClusterRoleBinding on the hosted cluster that grants the privileged security context constraint (SCC) to all service accounts in the dpf-operator-system namespace.
Prerequisites
-
You have access to the hosted cluster as a user with the
cluster-adminrole. -
You have installed the
ocCLI. - The hosted cluster kubeconfig file is available.
-
DPU provisioning has reached the
DPU Cluster Configstage.
Procedure
Get the hosted cluster kubeconfig:
$ oc get secret $HOSTED_CLUSTER_NAME-admin-kubeconfig -n $CLUSTERS_NAMESPACE -o jsonpath='{.data.kubeconfig}' | base64 -d > $HOSTED_CLUSTER_NAME.kubeconfigSwitch to the hosted cluster context:
$ export KUBECONFIG=$HOSTED_CLUSTER_NAME.kubeconfigCreate a file named
dpu-cluster-scc.yamlwith the following content:apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: dpf-system-scc-privileged labels: app.kubernetes.io/component: rbac app.kubernetes.io/part-of: dpu-services roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:openshift:scc:privileged subjects: - kind: Group apiGroup: rbac.authorization.k8s.io name: system:serviceaccounts:dpf-operator-systemApply the resource file on the hosted cluster:
$ oc apply -f dpu-cluster-scc.yaml
12.6.7. Approve hosted cluster CSRs for DPU provisioning Copy linkLink copied to clipboard!
You must approve the pending certificate signing requests (CSRs) for DPU nodes on the hosted cluster so that the DPU nodes can join the hosted cluster and complete provisioning.
When you use the DPF HCP Provisioner Operator, DPU CSR approval is handled automatically. Manual approval is provided as a fallback if automatic approval is not functioning.
Prerequisites
-
You have access to the hosted cluster as a user with the
cluster-adminrole. -
You have installed the
ocCLI. -
You have set the
KUBECONFIGenvironment variable to the hosted cluster kubeconfig file. -
DPU provisioning has reached the
DPU Cluster Configstage.
Procedure
Watch for pending CSRs from the DPU nodes:
$ oc get csr -wThe DPU node name typically follows the pattern
<host_worker_node_name>-<dpu_serial_number>.Approve all pending CSRs:
$ oc get csr -o go-template='{{range .items}}{{if not .status}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}' | xargs oc adm certificate approveExample output
certificatesigningrequest.certificates.k8s.io/csr-6jx22 approved certificatesigningrequest.certificates.k8s.io/csr-tb6nd approvedRepeat this step until no pending CSRs remain.
Verification
Verify that the DPU nodes joined the hosted cluster and are in a
Readystate:$ oc get nodesExample output
NAME STATUS ROLES AGE VERSION host-worker1-mt0000000001 Ready worker 2m48s v1.35.6 host-worker2-mt0000000002 Ready worker 2m45s v1.35.6NoteAfter the DPU nodes join the hosted cluster, the DPU provisioning process continues to the remaining stages.
12.6.8. Verify full system readiness Copy linkLink copied to clipboard!
After the DPU provisioning process completes, you can verify that all worker nodes, SR-IOV virtual functions, and DPU services are operational on the management cluster.
Prerequisites
-
You have access to the management cluster as a user with the
cluster-adminrole. -
You have installed the
ocCLI. - DPU provisioning has completed.
Procedure
Switch back to the management cluster context:
$ export KUBECONFIG="$(pwd)/mgmt-kubeconfig"Verify that all worker nodes are in a
Readystate:$ oc get nodeExample output
NAME STATUS ROLES AGE VERSION host-worker1 Ready worker 57m v1.35.6 host-worker2 Ready worker 57m v1.35.6 master-0 Ready control-plane,master,worker 4d23h v1.35.6 master-1 Ready control-plane,master,worker 4d22h v1.35.6 master-2 Ready control-plane,master,worker 4d23h v1.35.6Verify that SR-IOV virtual functions are registered as Kubernetes node resources on the worker nodes:
$ oc get nodes -l 'node-role.kubernetes.io/worker,!node-role.kubernetes.io/control-plane' -o json | \ jq '.items[] | {name: .metadata.name, capacity: .status.capacity."openshift.io/bf3_vfs", allocatable: .status.allocatable."openshift.io/bf3_vfs"}'Example output
{ "name": "host-worker1", "capacity": "90", "allocatable": "90" } { "name": "host-worker2", "capacity": "90", "allocatable": "90" }Verify that all DPU services are in a
Successphase:$ oc get dpuservices -n dpf-operator-systemExample output
NAME READY PHASE AGE doca-telemetry-service-7s8pb True Success 42m flannel True Success 26h hbn-gffmv True Success 25m kube-state-metrics-rbac True Success 4h10m node-problem-detector True Success 4h10m nvidia-k8s-ipam-node True Success 4h10m ovn-f49zx True Success 17m ovs-cni True Success 26h servicechainset-rbac-and-crds True Success 138m sfc-controller True Success 26h sriov-device-plugin True Success 26hOptional: View detailed DPU service status:
$ oc -n dpf-operator-system exec deploy/dpf-operator-controller-manager -- /dpfctl describe all --show-resources=dpuservice --grouping=false
12.7. Validate traffic and configure telemetry Copy linkLink copied to clipboard!
After provisioning the DPUs and verifying system readiness, validate end-to-end traffic flow and configure DPU telemetry observability.
12.7.1. Deploy traffic test pods and services Copy linkLink copied to clipboard!
You can deploy traffic test pods and services across the management cluster to validate end-to-end connectivity through the DPU data plane. The test workloads include a server pod on a control plane node and worker pods on DPU-enabled nodes, with both standard and host-network configurations.
These test workloads use the nicolaka/netshoot container image, a community networking-troubleshooting image that is not officially supported by Red Hat or NVIDIA. Use it only for connectivity validation and testing, not in production workloads.
Prerequisites
- You have installed the DPF Operator and provisioned the DPU hosted cluster.
- At least one DPU-enabled worker node is available.
-
You have access to the management cluster as a user with the
cluster-adminrole.
Procedure
Create a file named
traffic-pods.yamlwith the following content:# 1. Namespace --- apiVersion: v1 kind: Namespace metadata: name: workload # 2. SCC RoleBinding (grants 'default' ServiceAccount in 'workload' NS access to 'privileged' SCC) --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: privileged-scc-default-sa namespace: workload subjects: - kind: ServiceAccount name: default namespace: workload roleRef: kind: ClusterRole name: system:openshift:scc:privileged apiGroup: rbac.authorization.k8s.io # 3. Deployments and Services # Deployment: traffic-test-master --- apiVersion: apps/v1 kind: Deployment metadata: name: traffic-test-master namespace: workload labels: app: traffic-test-master spec: replicas: 1 selector: matchLabels: app: traffic-test-master template: metadata: labels: app: traffic-test-master spec: topologySpreadConstraints: - maxSkew: 1 topologyKey: kubernetes.io/hostname whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app: traffic-test-master nodeSelector: node-role.kubernetes.io/control-plane: "" tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoSchedule containers: - name: nginx securityContext: privileged: true capabilities: add: - NET_ADMIN image: nicolaka/netshoot command: ["nc", "-kl", "5000"] ports: - containerPort: 5000 name: tcp-server resources: requests: cpu: 1 memory: 1Gi limits: cpu: 1 memory: 1Gi --- # Service: traffic-test-master apiVersion: v1 kind: Service metadata: name: traffic-test-master namespace: workload labels: app: traffic-test-master spec: selector: app: traffic-test-master ports: - protocol: TCP port: 5000 targetPort: 5000 --- # Service: traffic-test-master-nodeport apiVersion: v1 kind: Service metadata: name: traffic-test-master-nodeport namespace: workload labels: app: traffic-test-master spec: type: NodePort selector: app: traffic-test-master ports: - protocol: TCP port: 5000 targetPort: 5000 --- # Deployment: traffic-test-worker apiVersion: apps/v1 kind: Deployment metadata: name: traffic-test-worker namespace: workload labels: app: traffic-test-worker spec: replicas: 1 selector: matchLabels: app: traffic-test-worker template: metadata: labels: app: traffic-test-worker spec: topologySpreadConstraints: - maxSkew: 1 topologyKey: kubernetes.io/hostname whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app: traffic-test-worker nodeSelector: feature.node.kubernetes.io/dpu-enabled: "" containers: - name: nginx securityContext: privileged: true capabilities: add: - NET_ADMIN image: nicolaka/netshoot command: ["nc", "-kl", "5000"] ports: - containerPort: 5000 name: tcp-server resources: requests: cpu: 16 memory: 6Gi limits: cpu: 16 memory: 6Gi --- # Service: traffic-test-worker apiVersion: v1 kind: Service metadata: name: traffic-test-worker namespace: workload labels: app: traffic-test-worker spec: selector: app: traffic-test-worker ports: - protocol: TCP port: 5000 targetPort: 5000 --- # Service: traffic-test-worker-nodeport apiVersion: v1 kind: Service metadata: name: traffic-test-worker-nodeport namespace: workload labels: app: traffic-test-worker spec: type: NodePort selector: app: traffic-test-worker ports: - protocol: TCP port: 5000 targetPort: 5000 --- # Deployment: traffic-test-worker-hostnetwork apiVersion: apps/v1 kind: Deployment metadata: name: traffic-test-worker-hostnetwork namespace: workload labels: app: traffic-test-worker-hostnetwork spec: replicas: 1 selector: matchLabels: app: traffic-test-worker-hostnetwork template: metadata: labels: app: traffic-test-worker-hostnetwork spec: topologySpreadConstraints: - maxSkew: 1 topologyKey: kubernetes.io/hostname whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app: traffic-test-worker-hostnetwork nodeSelector: feature.node.kubernetes.io/dpu-enabled: "" hostNetwork: true containers: - name: nginx securityContext: privileged: true capabilities: add: - NET_ADMIN image: nicolaka/netshoot command: ["nc", "-kl", "5000"] ports: - containerPort: 5000 name: tcp-server resources: requests: cpu: 1 memory: 1Gi limits: cpu: 1 memory: 1Gi --- # Service: traffic-test-worker-hostnetwork apiVersion: v1 kind: Service metadata: name: traffic-test-worker-hostnetwork namespace: workload labels: app: traffic-test-worker-hostnetwork spec: selector: app: traffic-test-worker-hostnetwork ports: - protocol: TCP port: 5000 targetPort: 5000 --- # Service: traffic-test-worker-hostnetwork-nodeport apiVersion: v1 kind: Service metadata: name: traffic-test-worker-hostnetwork-nodeport namespace: workload labels: app: traffic-test-worker-hostnetwork spec: type: NodePort selector: app: traffic-test-worker-hostnetwork ports: - protocol: TCP port: 5000 targetPort: 5000The manifest creates the following resources:
-
A
workloadnamespace for the test pods. -
A
RoleBindingresource that grants thedefaultservice account in theworkloadnamespace access to theprivilegedsecurity context constraint. -
A
traffic-test-masterdeployment andClusterIPandNodePortservices on a control plane node. -
A
traffic-test-workerdeployment andClusterIPandNodePortservices on DPU-enabled worker nodes. A
traffic-test-worker-hostnetworkdeployment that uses host networking on DPU-enabled worker nodes, withClusterIPandNodePortservices.NoteThe worker deployments set
replicas: 1for a single DPU worker node. Set the replica count of thetraffic-test-workerandtraffic-test-worker-hostnetworkdeployments to the number of DPU-enabled worker nodes so that thetopologySpreadConstraintsplace one pod on each node.
-
A
Apply the manifest:
$ oc apply -f traffic-pods.yaml
Verification
Verify that the test pods are running:
$ oc get pods -n workload -o wideExample output
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES traffic-test-master-7448bb5cc-mdftd 1/1 Running 0 2m10s 10.129.0.145 master-2 <none> <none> traffic-test-worker-776486fb68-krz54 1/1 Running 0 2m10s 10.128.2.9 host-worker1 <none> <none> traffic-test-worker-776486fb68-lz8vf 1/1 Running 0 2m10s 10.131.0.9 host-worker2 <none> <none> traffic-test-worker-hostnetwork-596d569d99-cjpns 1/1 Running 0 2m10s 10.0.110.11 host-worker1 <none> <none> traffic-test-worker-hostnetwork-596d569d99-x6m7r 1/1 Running 0 2m10s 10.0.110.12 host-worker2 <none> <none>Confirm that the
traffic-test-masterpod is on a control plane node and that thetraffic-test-workerpods are distributed across different DPU-enabled worker nodes.Verify that the services are created:
$ oc get svc -n workloadExample output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE traffic-test-master ClusterIP 172.30.102.123 <none> 5000/TCP 13m traffic-test-master-nodeport NodePort 172.30.98.22 <none> 5000:31368/TCP 13m traffic-test-worker ClusterIP 172.30.187.147 <none> 5000/TCP 13m traffic-test-worker-hostnetwork ClusterIP 172.30.122.242 <none> 5000/TCP 13m traffic-test-worker-hostnetwork-nodeport NodePort 172.30.122.214 <none> 5000:30209/TCP 13m traffic-test-worker-nodeport NodePort 172.30.108.72 <none> 5000:32570/TCP 13m
12.7.2. Run traffic validation tests Copy linkLink copied to clipboard!
You can run connectivity tests between the traffic test pods and services to verify that the DPU services and service chains are configured correctly. A successful test confirms that end-to-end traffic flows through the DPU data plane as expected.
Prerequisites
-
The traffic test pods and services are deployed in the
workloadnamespace and all pods are in aRunningstate. -
You have access to the management cluster as a user with the
cluster-adminrole.
Procedure
Run a ping connectivity test between pods on different worker nodes.
In the following example, replace
<worker_pod_name>with the name of atraffic-test-workerpod and replace<target_pod_ip>with the IP address of atraffic-test-workerpod on a different worker node:$ oc -n workload exec -it <worker_pod_name> -- ping -c 4 <target_pod_ip>Example output
PING 10.131.0.9 (10.131.0.9) 56(84) bytes of data. 64 bytes from 10.131.0.9: icmp_seq=1 ttl=62 time=1.61 ms 64 bytes from 10.131.0.9: icmp_seq=2 ttl=62 time=0.876 ms 64 bytes from 10.131.0.9: icmp_seq=3 ttl=62 time=0.510 ms 64 bytes from 10.131.0.9: icmp_seq=4 ttl=62 time=0.421 ms --- 10.131.0.9 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3028ms rtt min/avg/max/mdev = 0.421/0.853/1.606/0.466 msVerify that all 4 packets are received with 0% packet loss.
Run a service connectivity test from a worker pod to a service on a control plane node.
In the following example, replace
<worker_pod_name>with the name of atraffic-test-workerpod and replace<service_cluster_ip>with the cluster IP address of thetraffic-test-masterservice:$ oc -n workload exec -it <worker_pod_name> -- nc -vz <service_cluster_ip> 5000A
succeededmessage confirms that the service is reachable through the DPU-accelerated network.Run a service connectivity test from a worker pod to another worker pod.
In the following example, replace
<worker_pod_name>with the name of atraffic-test-workerpod and replace<service_cluster_ip>with the cluster IP address of thetraffic-test-workerservice:$ oc -n workload exec -it <worker_pod_name> -- nc -vz <service_cluster_ip> 5000A
succeededmessage confirms end-to-end connectivity through the DPU-accelerated service chain between worker pods.Optional: Run an external service connectivity test.
In the following example, replace
<worker_pod_name>with the name of atraffic-test-workerpod, replace<node_ip>with the IP address of a cluster node, and replace<nodeport>with the NodePort for one of the services:$ oc -n workload exec -it <worker_pod_name> -- nc -vz <node_ip> <nodeport>A
succeededmessage confirms that NodePort services are reachable through the DPU networking stack.
12.7.3. DPU telemetry observability with DOCA Telemetry Service Copy linkLink copied to clipboard!
The DOCA Telemetry Service (DTS) exposes DPU hardware telemetry, such as PCIe link speed, uplink throughput, packets, errors, and NIC channel activity, as Prometheus metrics. You can view these metrics by using the OpenShift Container Platform web console or a Grafana dashboard.
In a standard DPF installation, the DTS deployment objects are applied automatically during the postinstallation step. Apply them manually only when you are adding DTS to an existing cluster.
Neither the DPF Operator nor the DTS DPUService installs Grafana on OpenShift Container Platform. Red Hat does not offer a certified Grafana Operator. The community Grafana Operator from OperatorHub is the standard way to run Grafana on OpenShift Container Platform.
DTS runs on every DPU in the hosted cluster and collects counters from sysfs and ethtool providers. OpenShift Container Platform includes a built-in Prometheus instance, so you do not need to deploy a separate monitoring stack to scrape DTS metrics.
12.7.3.1. How DPF exposes DTS metrics to the management cluster Copy linkLink copied to clipboard!
DTS runs on the DPU hosted cluster, but Prometheus runs on the management cluster. DPF bridges this gap with a built-in port-mirroring mechanism.
When a DPUService resource declares a port in its configPorts field, DPF performs the following actions:
-
Publishes the service port as a
NodePorton the DPU hosted cluster. -
Creates a mirror
Serviceon the management cluster, labeled withdpu.nvidia.com/exposed-port-for-dpucluster.
The management-cluster Prometheus then scrapes the mirror service. This mechanism requires no additional configuration beyond the standard DTS deployment objects.
12.7.3.2. DTS deployment objects Copy linkLink copied to clipboard!
DTS is deployed through three standard DPF resources:
DPUServiceTemplate-
Defines the Helm chart for the DOCA Telemetry Service, the DTS container image, and the metrics port. The
configMapData.prometheus.portfield is set to9189. DPUServiceConfiguration-
Declares the service port
httpserverport: 9189underconfigPorts. This declaration triggers the management-cluster port-mirroring mechanism described previously. DPUDeployment-
References the template and configuration so that DTS is rolled out to the DPUs as a
DaemonSeton the DPU hosted cluster. DTS defaults to thesysfsandethtoolproviders.
12.7.4. Enable user workload monitoring for DTS Copy linkLink copied to clipboard!
OpenShift Container Platform includes Prometheus, but by default it only monitors OpenShift Container Platform platform components. You must enable user workload monitoring so that Prometheus can scrape user namespaces where DPF and DTS run, such as dpf-operator-system.
Prerequisites
- A DPF cluster is deployed with at least one provisioned DPU.
-
You have access to the management cluster as a user with the
cluster-adminrole.
Procedure
Create a
ConfigMapto enable user workload monitoring in theopenshift-monitoringnamespace:apiVersion: v1 kind: ConfigMap metadata: name: cluster-monitoring-config namespace: openshift-monitoring data: config.yaml: | enableUserWorkload: trueNoteIf the
cluster-monitoring-configConfigMapalready exists with other settings, edit it instead of replacing it, and add only theenableUserWorkload: trueline to the existingconfig.yamldata:$ oc -n openshift-monitoring edit configmap cluster-monitoring-configApply the
ConfigMap:$ oc apply -f cluster-monitoring-config.yaml
Verification
Verify that the user workload monitoring pods are running in the
openshift-user-workload-monitoringnamespace:$ oc -n openshift-user-workload-monitoring get podsExample output
NAME READY STATUS RESTARTS AGE prometheus-operator-... 1/1 Running 0 ... prometheus-user-workload-0 ... Running 0 ... thanos-ruler-user-workload-0 ... Running 0 ...Confirm that pods named
prometheus-user-workload,thanos-ruler-user-workload, andprometheus-operatorare all in aRunningstate.
12.7.5. Configure the DTS ServiceMonitor Copy linkLink copied to clipboard!
Create a ServiceMonitor resource to instruct the user workload monitoring Prometheus instance to scrape the DOCA Telemetry Service (DTS) metrics endpoint. The ServiceMonitor selects the mirrored DTS service in the dpf-operator-system namespace and scrapes its /metrics path on the httpserverport every 30 seconds.
Prerequisites
- User workload monitoring is enabled in OpenShift Container Platform.
The DTS
DPUServiceConfigurationandDPUDeploymentresources are applied.For details, see "DPU telemetry observability with DTS".
-
You have access to the management cluster as a user with the
cluster-adminrole.
Procedure
Create a file named
dts-servicemonitor.yamlwith the following content:apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: doca-telemetry-service-monitor namespace: dpf-operator-system spec: selector: matchExpressions: - key: dpu.nvidia.com/dpuservice-name operator: Exists endpoints: - port: httpserverport interval: 30s path: /metrics relabelings: - sourceLabels: - __meta_kubernetes_service_label_dpu_nvidia_com_dpuservice_name regex: doca-telemetry-service.* action: keep namespaceSelector: matchNames: - dpf-operator-systemApply the
ServiceMonitor:$ oc apply -f dts-servicemonitor.yaml
Verification
Verify that the
ServiceMonitoris created in thedpf-operator-systemnamespace:$ oc -n dpf-operator-system get servicemonitor doca-telemetry-service-monitorExample output
NAME AGE doca-telemetry-service-monitor ...
12.7.6. Install the DTS console dashboard Copy linkLink copied to clipboard!
You can install a DTS dashboard that integrates directly into the OpenShift Container Platform web console. This dashboard provides visibility of DPU telemetry metrics without requiring Grafana or additional tools.
Prerequisites
- User workload monitoring is enabled in OpenShift Container Platform.
-
The DTS
ServiceMonitoris configured and collecting metrics. -
You have access to the management cluster as a user with the
cluster-adminrole.
Procedure
Create a file named
dts-console-dashboard.yamlwith the following content to define a console dashboardConfigMapin theopenshift-config-managednamespace:apiVersion: v1 kind: ConfigMap metadata: name: dpf-dts-console-dashboard namespace: openshift-config-managed labels: console.openshift.io/dashboard: "true" data: doca-dpu-telemetry-dts.json: | { "title": "DOCA DPU Telemetry (DTS)", "uid": "doca-dpu-telemetry-dts-console", "editable": false, "schemaVersion": 16, "tags": ["dpf", "dpu", "dts", "telemetry"], "timezone": "browser", "time": {"from": "now-1h", "to": "now"}, "refresh": "30s", "templating": {"list": []}, "rows": [ { "title": "PCIe / Link", "showTitle": true, "height": "250px", "panels": [ { "type": "graph", "title": "PCIe Link Speed (GT/s)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true}, "yaxes": [{"format": "none", "show": true}, {"format": "none", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "current_link_speed", "legendFormat": "{{source}} {{hca}}"} ] }, { "type": "graph", "title": "PCIe Link Width (lanes)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true}, "yaxes": [{"format": "none", "show": true}, {"format": "none", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "current_link_width", "legendFormat": "{{source}} {{hca}}"} ] } ] }, { "title": "Uplink Throughput (p0/p1)", "showTitle": true, "height": "250px", "panels": [ { "type": "graph", "title": "Uplink RX (bits/s)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "values": true, "avg": true, "max": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "bps", "show": true}, {"format": "bps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_rx_bytes\"}[5m])) * 8", "legendFormat": "{{source}}"} ] }, { "type": "graph", "title": "Uplink TX (bits/s)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "values": true, "avg": true, "max": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "bps", "show": true}, {"format": "bps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_tx_bytes\"}[5m])) * 8", "legendFormat": "{{source}}"} ] } ] }, { "title": "Uplink Packets & Errors", "showTitle": true, "height": "250px", "panels": [ { "type": "graph", "title": "Uplink packets/s (rx + tx)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "pps", "show": true}, {"format": "pps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_rx_packets\"}[5m]))", "legendFormat": "{{source}} rx"}, {"refId": "B", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_tx_packets\"}[5m]))", "legendFormat": "{{source}} tx"} ] }, { "type": "graph", "title": "Uplink errors & drops/s", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "cps", "show": true}, {"format": "cps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_rx_errors\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_tx_errors\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_rx_dropped\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_tx_dropped\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_rx_crc_errors\"}[5m]))", "legendFormat": "{{source}}"} ] } ] }, { "title": "NIC Channel Activity", "showTitle": true, "height": "250px", "panels": [ { "type": "graph", "title": "NIC channel poll/s", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "cps", "show": true}, {"format": "cps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate(ch_poll[5m]))", "legendFormat": "{{source}}"} ] }, { "type": "graph", "title": "NIC channel events/s", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "cps", "show": true}, {"format": "cps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate(ch_events[5m]))", "legendFormat": "{{source}}"} ] } ] } ] }Apply the console dashboard:
$ oc apply -f dts-console-dashboard.yaml
Verification
Verify that the dashboard
ConfigMapis created:$ oc -n openshift-config-managed get configmap dpf-dts-console-dashboardExample output
NAME DATA AGE dpf-dts-console-dashboard 1 ...Access the dashboard in the OpenShift Container Platform web console:
-
Navigate to Observe
Dashboards. In the Dashboard dropdown menu, select DOCA DPU Telemetry (DTS).
The dashboard displays PCIe link speed and width, uplink throughput, packets per second, errors and drops per second, and NIC channel activity, with each DPU as its own line.
-
Navigate to Observe
The DTS console dashboard renders against the platform Thanos or user workload monitoring Prometheus instance. No Grafana dependency is required for basic DPU telemetry viewing.
12.7.7. Install Grafana for DTS metrics visualization Copy linkLink copied to clipboard!
You can install the Grafana Operator and a Grafana instance to provide enhanced visualization for DPU telemetry metrics, including per-DPU filtering and customizable dashboards. You can also deploy a dashboard ConfigMap that adds DTS metrics to the OpenShift Container Platform web console.
Prerequisites
- You have enabled user workload monitoring in OpenShift Container Platform.
-
You have configured the DTS
ServiceMonitorand it is collecting metrics. -
You have access to the management cluster as a user with the
cluster-adminrole. -
You have installed the
ocCLI. -
You have installed the
helmCLI.
Procedure
Install the Grafana Operator by using Helm:
$ helm upgrade -i grafana-operator oci://ghcr.io/grafana/helm-charts/grafana-operator \ --version 5.24.0 \ --namespace grafana-operator \ --create-namespaceExample output
Pulled: ghcr.io/grafana/helm-charts/grafana-operator:5.24.0 Digest: sha256:4f69cdaecfed2cc61d4e5f4a8e7142795e9b00997e4bcbd37a8c154a225a2f1f Release "grafana-operator" has been upgraded. Happy Helming! NAME: grafana-operator LAST DEPLOYED: Tue Aug 4 08:51:36 2026 NAMESPACE: grafana-operator STATUS: deployed REVISION: 2 TEST SUITE: NoneGrant OpenShift Route permissions to the Grafana Operator:
The community Grafana Operator requires additional RBAC permissions to manage OpenShift Container Platform routes. Create a file named
grafana-operator-route-rbac.yamlwith the following content:apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: grafana-operator-route-manager rules: - apiGroups: - route.openshift.io resources: - routes - routes/custom-host verbs: - create - delete - get - list - patch - update - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: grafana-operator-route-manager roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: grafana-operator-route-manager subjects: - kind: ServiceAccount name: grafana-operator namespace: grafana-operatorApply the file:
$ oc apply -f grafana-operator-route-rbac.yamlExample output
clusterrole.rbac.authorization.k8s.io/grafana-operator-route-manager created clusterrolebinding.rbac.authorization.k8s.io/grafana-operator-route-manager createdCreate Grafana RBAC for Prometheus access:
Create a
ServiceAccountwith a long-lived token and bind it to thecluster-monitoring-viewClusterRoleso Grafana can query the platform Prometheus:apiVersion: v1 kind: ServiceAccount metadata: name: grafana-prometheus-reader namespace: dpf-operator-system --- apiVersion: v1 kind: Secret metadata: name: grafana-prometheus-reader-token namespace: dpf-operator-system annotations: kubernetes.io/service-account.name: grafana-prometheus-reader type: kubernetes.io/service-account-token --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: grafana-prometheus-reader-cluster-monitoring roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-monitoring-view subjects: - kind: ServiceAccount name: grafana-prometheus-reader namespace: dpf-operator-systemApply the YAML:
$ oc apply -f grafana-rbac.yamlDeploy the Grafana instance with control-plane scheduling:
apiVersion: grafana.integreatly.org/v1beta1 kind: Grafana metadata: name: dpf-grafana namespace: dpf-operator-system labels: dashboards: "dpf-grafana" spec: route: spec: port: targetPort: grafana tls: termination: edge config: log: mode: "console" level: "info" auth.anonymous: enabled: "true" org_role: "Viewer" security: admin_user: "admin" admin_password: "admin" deployment: spec: template: spec: nodeSelector: node-role.kubernetes.io/control-plane: "" tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule - key: node-role.kubernetes.io/control-plane operator: Exists effect: NoScheduleApply the YAML:
$ oc apply -f grafana-cr.yamlWarningThe default credentials (
admin/admin) are suitable for lab environments only. Change theadmin_passwordfor non-lab deployments.Configure the Prometheus datasource:
apiVersion: grafana.integreatly.org/v1beta1 kind: GrafanaDatasource metadata: name: prometheus namespace: dpf-operator-system spec: instanceSelector: matchLabels: dashboards: "dpf-grafana" valuesFrom: - targetPath: "secureJsonData.httpHeaderValue1" valueFrom: secretKeyRef: name: grafana-prometheus-reader-token key: token datasource: name: prometheus type: prometheus uid: prometheus access: proxy url: https://thanos-querier.openshift-monitoring.svc.cluster.local:9091 isDefault: true jsonData: tlsSkipVerify: true httpHeaderName1: "Authorization" timeInterval: "30s" secureJsonData: httpHeaderValue1: "Bearer ${token}"Apply the YAML:
$ oc apply -f grafana-datasource.yamlDeploy the DTS console dashboard for OpenShift Container Platform web console integration:
apiVersion: v1 kind: ConfigMap metadata: name: dpf-dts-console-dashboard namespace: openshift-config-managed labels: console.openshift.io/dashboard: "true" data: doca-dpu-telemetry-dts.json: | { "title": "DOCA DPU Telemetry (DTS)", "uid": "doca-dpu-telemetry-dts-console", "editable": false, "schemaVersion": 16, "tags": ["dpf", "dpu", "dts", "telemetry"], "timezone": "browser", "time": {"from": "now-1h", "to": "now"}, "refresh": "30s", "templating": {"list": []}, "rows": [ { "title": "PCIe / Link", "showTitle": true, "height": "250px", "panels": [ { "type": "graph", "title": "PCIe Link Speed (GT/s)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true}, "yaxes": [{"format": "none", "show": true}, {"format": "none", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "current_link_speed", "legendFormat": "{{source}} {{hca}}"} ] }, { "type": "graph", "title": "PCIe Link Width (lanes)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true}, "yaxes": [{"format": "none", "show": true}, {"format": "none", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "current_link_width", "legendFormat": "{{source}} {{hca}}"} ] } ] }, { "title": "Uplink Throughput (p0/p1)", "showTitle": true, "height": "250px", "panels": [ { "type": "graph", "title": "Uplink RX (bits/s)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "values": true, "avg": true, "max": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "bps", "show": true}, {"format": "bps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_rx_bytes\"}[5m])) * 8", "legendFormat": "{{source}}"} ] }, { "type": "graph", "title": "Uplink TX (bits/s)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "values": true, "avg": true, "max": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "bps", "show": true}, {"format": "bps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_tx_bytes\"}[5m])) * 8", "legendFormat": "{{source}}"} ] } ] }, { "title": "Uplink Packets & Errors", "showTitle": true, "height": "250px", "panels": [ { "type": "graph", "title": "Uplink packets/s (rx + tx)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "pps", "show": true}, {"format": "pps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_rx_packets\"}[5m]))", "legendFormat": "{{source}} rx"}, {"refId": "B", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_tx_packets\"}[5m]))", "legendFormat": "{{source}} tx"} ] }, { "type": "graph", "title": "Uplink errors & drops/s", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "cps", "show": true}, {"format": "cps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_rx_errors\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_tx_errors\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_rx_dropped\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_tx_dropped\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_rx_crc_errors\"}[5m]))", "legendFormat": "{{source}}"} ] } ] }, { "title": "NIC Channel Activity", "showTitle": true, "height": "250px", "panels": [ { "type": "graph", "title": "NIC channel poll/s", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "cps", "show": true}, {"format": "cps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate(ch_poll[5m]))", "legendFormat": "{{source}}"} ] }, { "type": "graph", "title": "NIC channel events/s", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "cps", "show": true}, {"format": "cps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate(ch_events[5m]))", "legendFormat": "{{source}}"} ] } ] } ] }Apply the YAML:
$ oc apply -f dts-console-dashboard.yamlDeploy the complete DTS Grafana dashboard:
apiVersion: v1 kind: ConfigMap metadata: name: dpf-dts-grafana-dashboard namespace: dpf-operator-system labels: app.kubernetes.io/part-of: dpf data: doca-dpu-telemetry-dts.json: | { "title": "DOCA DPU Telemetry (DTS)", "uid": "doca-dpu-telemetry-dts", "tags": ["dpf", "dpu", "dts", "telemetry"], "timezone": "browser", "schemaVersion": 39, "editable": true, "time": {"from": "now-1h", "to": "now"}, "refresh": "30s", "templating": { "list": [ { "name": "source", "label": "DPU (source)", "type": "query", "datasource": {"type": "prometheus", "uid": "prometheus"}, "query": "label_values(current_link_speed, source)", "refresh": 2, "includeAll": true, "multi": true, "current": {"text": "All", "value": "$__all"}, "sort": 1 } ] }, "panels": [ { "type": "stat", "title": "PCIe Link Speed (GT/s)", "datasource": {"type": "prometheus", "uid": "prometheus"}, "gridPos": {"h": 4, "w": 6, "x": 0, "y": 0}, "fieldConfig": {"defaults": {"unit": "none"}, "overrides": []}, "options": {"reduceOptions": {"calcs": ["lastNotNull"]}, "colorMode": "value", "graphMode": "none"}, "targets": [ {"refId": "A", "datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "current_link_speed{source=~\"$source\"}", "legendFormat": "{{source}} {{hca}}"} ] }, { "type": "stat", "title": "PCIe Link Width (lanes)", "datasource": {"type": "prometheus", "uid": "prometheus"}, "gridPos": {"h": 4, "w": 6, "x": 6, "y": 0}, "fieldConfig": {"defaults": {"unit": "none"}, "overrides": []}, "options": {"reduceOptions": {"calcs": ["lastNotNull"]}, "colorMode": "value", "graphMode": "none"}, "targets": [ {"refId": "A", "datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "current_link_width{source=~\"$source\"}", "legendFormat": "{{source}} {{hca}}"} ] }, { "type": "stat", "title": "Max PCIe Link Speed (GT/s)", "datasource": {"type": "prometheus", "uid": "prometheus"}, "gridPos": {"h": 4, "w": 6, "x": 12, "y": 0}, "fieldConfig": {"defaults": {"unit": "none"}, "overrides": []}, "options": {"reduceOptions": {"calcs": ["lastNotNull"]}, "colorMode": "value", "graphMode": "none"}, "targets": [ {"refId": "A", "datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "max_link_speed{source=~\"$source\"}", "legendFormat": "{{source}} {{hca}}"} ] }, { "type": "stat", "title": "Max PCIe Link Width (lanes)", "datasource": {"type": "prometheus", "uid": "prometheus"}, "gridPos": {"h": 4, "w": 6, "x": 18, "y": 0}, "fieldConfig": {"defaults": {"unit": "none"}, "overrides": []}, "options": {"reduceOptions": {"calcs": ["lastNotNull"]}, "colorMode": "value", "graphMode": "none"}, "targets": [ {"refId": "A", "datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "max_link_width{source=~\"$source\"}", "legendFormat": "{{source}} {{hca}}"} ] }, { "type": "timeseries", "title": "Uplink RX throughput (p0/p1)", "datasource": {"type": "prometheus", "uid": "prometheus"}, "gridPos": {"h": 8, "w": 12, "x": 0, "y": 4}, "fieldConfig": {"defaults": {"unit": "bps", "custom": {"drawStyle": "line", "fillOpacity": 10}}, "overrides": []}, "options": {"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["mean", "max"]}, "tooltip": {"mode": "multi"}}, "targets": [ {"refId": "A", "datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_rx_bytes\", source=~\"$source\"}[5m])) * 8", "legendFormat": "{{source}}"} ] }, { "type": "timeseries", "title": "Uplink TX throughput (p0/p1)", "datasource": {"type": "prometheus", "uid": "prometheus"}, "gridPos": {"h": 8, "w": 12, "x": 12, "y": 4}, "fieldConfig": {"defaults": {"unit": "bps", "custom": {"drawStyle": "line", "fillOpacity": 10}}, "overrides": []}, "options": {"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["mean", "max"]}, "tooltip": {"mode": "multi"}}, "targets": [ {"refId": "A", "datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_tx_bytes\", source=~\"$source\"}[5m])) * 8", "legendFormat": "{{source}}"} ] }, { "type": "timeseries", "title": "Uplink packets/s (p0/p1 rx+tx)", "datasource": {"type": "prometheus", "uid": "prometheus"}, "gridPos": {"h": 8, "w": 12, "x": 0, "y": 12}, "fieldConfig": {"defaults": {"unit": "pps", "custom": {"drawStyle": "line", "fillOpacity": 10}}, "overrides": []}, "options": {"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["mean", "max"]}, "tooltip": {"mode": "multi"}}, "targets": [ {"refId": "A", "datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_rx_packets\", source=~\"$source\"}[5m]))", "legendFormat": "{{source}} rx"}, {"refId": "B", "datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_tx_packets\", source=~\"$source\"}[5m]))", "legendFormat": "{{source}} tx"} ] }, { "type": "timeseries", "title": "Uplink errors & drops/s (p0/p1)", "datasource": {"type": "prometheus", "uid": "prometheus"}, "gridPos": {"h": 8, "w": 12, "x": 12, "y": 12}, "fieldConfig": {"defaults": {"unit": "cps", "custom": {"drawStyle": "line", "fillOpacity": 10}}, "overrides": []}, "options": {"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["max"]}, "tooltip": {"mode": "multi"}}, "targets": [ {"refId": "A", "datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_rx_errors\", source=~\"$source\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_tx_errors\", source=~\"$source\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_rx_dropped\", source=~\"$source\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_tx_dropped\", source=~\"$source\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_rx_crc_errors\", source=~\"$source\"}[5m]))", "legendFormat": "{{source}}"} ] }, { "type": "timeseries", "title": "NIC channel poll/s", "datasource": {"type": "prometheus", "uid": "prometheus"}, "gridPos": {"h": 8, "w": 12, "x": 0, "y": 20}, "fieldConfig": {"defaults": {"unit": "cps", "custom": {"drawStyle": "line", "fillOpacity": 10}}, "overrides": []}, "options": {"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["mean", "max"]}, "tooltip": {"mode": "multi"}}, "targets": [ {"refId": "A", "datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "rate(ch_poll{source=~\"$source\"}[5m])", "legendFormat": "{{source}} {{device_name}}"} ] }, { "type": "timeseries", "title": "NIC channel events/s", "datasource": {"type": "prometheus", "uid": "prometheus"}, "gridPos": {"h": 8, "w": 12, "x": 12, "y": 20}, "fieldConfig": {"defaults": {"unit": "cps", "custom": {"drawStyle": "line", "fillOpacity": 10}}, "overrides": []}, "options": {"legend": {"displayMode": "table", "placement": "bottom", "calcs": ["mean", "max"]}, "tooltip": {"mode": "multi"}}, "targets": [ {"refId": "A", "datasource": {"type": "prometheus", "uid": "prometheus"}, "expr": "rate(ch_events{source=~\"$source\"}[5m])", "legendFormat": "{{source}} {{device_name}}"} ] } ] } --- apiVersion: grafana.integreatly.org/v1beta1 kind: GrafanaDashboard metadata: name: doca-dpu-telemetry-dts namespace: dpf-operator-system spec: instanceSelector: matchLabels: dashboards: "dpf-grafana" configMapRef: name: dpf-dts-grafana-dashboard key: doca-dpu-telemetry-dts.jsonApply the YAML:
$ oc apply -f dts-grafana-dashboard.yaml
Verification
Verify that the Grafana Operator is running:
$ oc get pods -n grafana-operatorExample output
NAME READY STATUS RESTARTS AGE grafana-operator-66d8c8c7b-xyz12 1/1 Running 0 5m42sVerify that the Grafana instance is running:
$ oc get grafana -n dpf-operator-systemExample output
NAME AGE dpf-grafana 3m15sVerify that the Grafana pod is running on a control plane node:
$ oc get pods -n dpf-operator-system -l app.kubernetes.io/name=grafana -o wideExample output
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES grafana-deployment-7c8b9d-xyz12 1/1 Running 0 2m38s 10.128.0.45 master-node-1 <none> <none>Verify the Grafana route exists:
$ oc get route -n dpf-operator-systemExample output
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD dpf-grafana-route dpf-grafana-route-dpf-operator-system.apps.cluster.example.com dpf-grafana grafana edge NoneVerify that the console dashboard ConfigMap exists:
$ oc get configmap dpf-dts-console-dashboard -n openshift-config-managedAccess the Grafana web interface:
Get the Grafana URL:
$ echo "https://$(oc -n dpf-operator-system get route dpf-grafana-route -o jsonpath='{.spec.host}')"Open the returned URL in a web browser. Use anonymous access (read-only) or sign in with the default credentials (
admin/admin) for editing capabilities.Navigate to the DTS dashboard:
- In Grafana, go to Dashboards and open DOCA DPU Telemetry (DTS).
- Use the DPU (source) dropdown menu to focus on a specific DPU or select All.
- Adjust the time range by using the time-range control on the dashboard toolbar. The dashboard refreshes every 30 seconds.
-
Optional: In the OpenShift Container Platform web console, go to Observe
Dashboards and open DOCA DPU Telemetry (DTS) to view the console-integrated dashboard. Review the following metrics:
- PCIe status: current and maximum link speed and width
-
Throughput: receive (RX) and transmit (TX) data rates for uplink ports
p0andp1 - Packet rates: packets-per-second statistics with RX and TX breakdown
- Error monitoring: combined error, drop, and CRC error rates
12.7.8. View DTS metrics and dashboards Copy linkLink copied to clipboard!
After you configure the DTS ServiceMonitor, you can view DPU telemetry metrics by using the OpenShift Container Platform web console, PromQL queries, or Grafana dashboards.
Prerequisites
-
You have configured the DTS
ServiceMonitor. -
You have access to the management cluster as a user with the
cluster-adminrole. -
You have installed the
ocCLI. - Optional: You have installed Grafana for DTS metrics visualization.
Procedure
Verify that the DTS
DPUServiceis ready on the management cluster. The object name carries a generated suffix, so select it by its stable label:$ oc -n dpf-operator-system get dpuservice \ -l svc.dpu.nvidia.com/dpudeployment-service=doca-telemetry-serviceExample output
NAME READY PHASE AGE doca-telemetry-service-89p28 True Success ...A status of
READY: TrueandPHASE: Successconfirms that DTS is deployed and running.Deploy the DTS console dashboard for the OpenShift Container Platform web console:
The console dashboard provides in-console visibility of DPU performance without requiring Grafana:
apiVersion: v1 kind: ConfigMap metadata: name: dpf-dts-console-dashboard namespace: openshift-config-managed labels: console.openshift.io/dashboard: "true" data: doca-dpu-telemetry-dts.json: | { "title": "DOCA DPU Telemetry (DTS)", "uid": "doca-dpu-telemetry-dts-console", "editable": false, "schemaVersion": 16, "tags": ["dpf", "dpu", "dts", "telemetry"], "timezone": "browser", "time": {"from": "now-1h", "to": "now"}, "refresh": "30s", "templating": {"list": []}, "rows": [ { "title": "PCIe / Link", "showTitle": true, "height": "250px", "panels": [ { "type": "graph", "title": "PCIe Link Speed (GT/s)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true}, "yaxes": [{"format": "none", "show": true}, {"format": "none", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "current_link_speed", "legendFormat": "{{source}} {{hca}}"} ] }, { "type": "graph", "title": "PCIe Link Width (lanes)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true}, "yaxes": [{"format": "none", "show": true}, {"format": "none", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "current_link_width", "legendFormat": "{{source}} {{hca}}"} ] } ] }, { "title": "Uplink Throughput (p0/p1)", "showTitle": true, "height": "250px", "panels": [ { "type": "graph", "title": "Uplink RX (bits/s)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "values": true, "avg": true, "max": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "bps", "show": true}, {"format": "bps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_rx_bytes\"}[5m])) * 8", "legendFormat": "{{source}}"} ] }, { "type": "graph", "title": "Uplink TX (bits/s)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "values": true, "avg": true, "max": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "bps", "show": true}, {"format": "bps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_tx_bytes\"}[5m])) * 8", "legendFormat": "{{source}}"} ] } ] }, { "title": "Uplink Packets & Errors", "showTitle": true, "height": "250px", "panels": [ { "type": "graph", "title": "Uplink packets/s (rx + tx)", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "pps", "show": true}, {"format": "pps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_rx_packets\"}[5m]))", "legendFormat": "{{source}} rx"}, {"refId": "B", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_tx_packets\"}[5m]))", "legendFormat": "{{source}} tx"} ] }, { "type": "graph", "title": "Uplink errors & drops/s", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "cps", "show": true}, {"format": "cps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate({__name__=~\"p[01]_eth_rx_errors\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_tx_errors\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_rx_dropped\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_tx_dropped\"}[5m])) + sum by(source)(rate({__name__=~\"p[01]_eth_rx_crc_errors\"}[5m]))", "legendFormat": "{{source}}"} ] } ] }, { "title": "NIC Channel Activity", "showTitle": true, "height": "250px", "panels": [ { "type": "graph", "title": "NIC channel poll/s", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "cps", "show": true}, {"format": "cps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate(ch_poll[5m]))", "legendFormat": "{{source}}"} ] }, { "type": "graph", "title": "NIC channel events/s", "span": 6, "datasource": "prometheus", "nullPointMode": "null", "legend": {"show": true, "alignAsTable": true, "rightSide": true}, "yaxes": [{"format": "cps", "show": true}, {"format": "cps", "show": false}], "targets": [ {"refId": "A", "format": "time_series", "intervalFactor": 2, "expr": "sum by(source)(rate(ch_events[5m]))", "legendFormat": "{{source}}"} ] } ] } ] }Create a file named
dts-console-dashboard.yamlwith the preceding content and apply it:$ oc apply -f dts-console-dashboard.yamlView metrics in the OpenShift Container Platform web console.
NoteThe OpenShift Container Platform web console reads from the cluster Prometheus instance through Thanos and user workload monitoring. Grafana is not required for basic metric viewing.
To run an ad hoc query, go to Observe
Metrics in the web console, enter a DTS PromQLquery, and click Run queries.Example query to validate DTS metrics:
current_link_speed{job=~"doca-telemetry-service.*"}You should get one series per DPU. Hover over a line to see its labels. Note the
sourcelabel, which is the DPU node name that identifies each DPU.Expand Table 12.10. DTS PromQL queries Query Description current_link_speed{job=~"doca-telemetry-service.*"}Returns the current PCIe link speed for each DPU. Each series includes a
sourcelabel that identifies the DPU node name.rate(p0_eth_rx_bytes{job=~"doca-telemetry-service.*"}[5m]) * 8Calculates the uplink receive throughput in bits per second over a 5-minute window.
rate(ch_poll{job=~"doca-telemetry-service.*"}[5m])Calculates the NIC channel polling activity rate over a 5-minute window.
To view the console dashboard, go to Observe
Dashboards, then in the Dashboard dropdown menu, select DOCA DPU Telemetry (DTS). The dashboard displays PCIe link speed and width, uplink throughput, packets per second, errors and drops per second, and NIC channel activity, with each DPU as its own line. Optional: View metrics in Grafana.
Grafana provides richer dashboards with per-DPU dropdown filters and customizable panels. After you install the Grafana Operator and Grafana instance, retrieve the route URL:
$ echo "https://$(oc -n dpf-operator-system get route dpf-grafana-route -o jsonpath='{.spec.host}')"Open the outputted URL in a browser. Anonymous access provides read-only viewer permissions. To edit dashboards, click Sign in and use
admin/adminas the default credentials set in the Grafana custom resource.ImportantChange the default Grafana credentials for non-lab clusters.
In Grafana, go to Dashboards and open DOCA DPU Telemetry (DTS). Use the DPU (source) dropdown menu to focus on a specific DPU or select All. Adjust the time range by using the time-range control on the dashboard toolbar. The dashboard refreshes every 30 seconds.
Optional: Review DPF framework dashboards in Grafana.
The DPF Operator installs framework dashboards that track DPU lifecycle and control-plane health separately from the DTS hardware telemetry dashboard. These dashboards are loaded into Grafana automatically through
GrafanaDashboardresources created fromConfigMaps.Expand Table 12.11. DPF framework dashboards Dashboard Description DOCA Platform DPU Fleet Health
Fleet-wide DPU health, provisioning state, and version distribution.
DOCA Platform DPU Health Detail
Per-DPU status, conditions, and history timelines.
DOCA Platform Framework State
Inventory and readiness of every DPF resource type.
DOCA Platform Framework Performance
Time for DPF resources to reach their conditions, including reconcile and provisioning timings.
Controller Runtime
DPF controller internals: CPU and memory usage, reconcile rates, queues, and errors.
12.8. Troubleshoot DPF Copy linkLink copied to clipboard!
You can diagnose and resolve common NVIDIA DPF Operator issues with DPU provisioning, hosted cluster readiness, networking, and collect diagnostic logs for support. These procedures complement the official NVIDIA debugging tools and guides.
12.8.1. DPU provisioning does not start Copy linkLink copied to clipboard!
If DPU provisioning does not start immediately after you add worker nodes to the management cluster, verify that certificate signing requests (CSRs), controller pods, Node Feature Discovery (NFD) labels, and DPF resource objects are in the correct state.
- Verify that all worker CSRs are approved
Run the following command to list the CSR status on the management cluster:
$ oc get csrEnsure that all CSRs for the worker nodes show an
Approvedstatus.- Verify that all DPF controller pods are running
Run the following command to check the status of the DPF Operator pods:
$ oc get pod -n dpf-operator-systemEnsure that all pods are in a
Runningstate.- Verify that worker nodes are labeled for DPU provisioning by NFD
Run the following command to confirm that the
dpu-enabledlabel is present on the worker nodes:$ oc get nodes -l feature.node.kubernetes.io/dpu-enabled=""The output lists the worker nodes that NFD has labeled for DPU provisioning. For example:
Example output
NAME STATUS ROLES AGE VERSION host-worker1 NotReady worker,worker-dpu 62s v1.35.6 host-worker2 NotReady worker,worker-dpu 66s v1.35.6- Check BFB object status
Run the following command to verify that the BlueField Bootstream File (BFB) image is downloaded and ready:
$ oc describe bfb -n dpf-operator-system bf-bundleCheck the
status.conditionsfield for download progress and any error messages.- Verify that the BFB image URL is reachable
If the BFB download fails, run the following command to confirm that the image URL is reachable, replacing
$BFB_URLwith the image URL:$ curl -I $BFB_URLEnsure that the response returns a
200 OKstatus code. If the download fails, verify network connectivity to the image registry, check for firewall or proxy restrictions, and ensure that sufficient disk space is available on the node.- Monitor DPU provisioning progress
Run the following command to watch the DPU objects progress through provisioning:
$ oc get dpu -n dpf-operator-system -wWait for each DPU to progress from
PendingtoProvisioningtoReady.- Verify that the DPU hardware is detected on the worker node
Open a debug shell on the worker node:
$ oc debug node/<worker-node-name>Inside the debug shell, run the following commands to confirm that a BlueField device is present:
sh-5.1# chroot /hostsh-5.1# lspci | grep -i mellanoxIf the DPU is not listed, verify that it is properly seated in the PCIe slot and that it is not disabled in the server BIOS.
- Verify DPU firmware and software compatibility
Inside the debug shell, run the following command to check the DPU firmware version:
sh-5.1# mlxfwmanager --queryConfirm that the BlueField firmware and DOCA software versions on the DPU are compatible with the DPF Operator version that you deployed.
- Check
DPUDeploymentobject status Inspect the
DPUDeploymentobject for information about the following resources:- BFB object state
-
DPUServiceTemplateobjects state -
DPUServiceConfigurationobjects state
Run the following command to view the full
DPUDeploymentstatus:$ oc get dpudeployments -n dpf-operator-system dpudeployment -o yamlAlternatively, run the following
dpfctlcommand for a summarized view:$ oc -n dpf-operator-system exec deploy/dpf-operator-controller-manager -- /dpfctl describe dpudeployments
12.8.2. DPU objects remain in the DPU Cluster Config state Copy linkLink copied to clipboard!
If DPU objects remain in a DPU Cluster Config state and do not progress, the hosted cluster might have pending certificate signing requests (CSRs) that must be approved.
- Check for pending CSRs in the hosted cluster
Switch to the hosted cluster context and check for any pending CSRs:
$ export KUBECONFIG=<path_to_hosted_cluster_kubeconfig>$ oc get csrReview the output and approve any CSRs that show a
Pendingstatus.
12.8.3. Management cluster nodes do not become ready Copy linkLink copied to clipboard!
If management cluster nodes do not reach a Ready state after DPU provisioning completes, the OVN-Kubernetes CNI pods might not be running correctly on the management cluster or the hosted cluster.
- Check OVN-Kubernetes pods on the management cluster
Switch to the management cluster context and verify that all OVN-Kubernetes pods are running on the x86_64 worker nodes and control plane nodes:
$ export KUBECONFIG=<path_to_management_cluster_kubeconfig>$ oc get pods -n openshift-ovn-kubernetes -o wide- Check OVN-Kubernetes pods on the hosted cluster
Switch to the hosted cluster context and verify that all OVN-Kubernetes pods are running on the DPU workers:
$ export KUBECONFIG=<path_to_hosted_cluster_kubeconfig>$ oc get pods -n openshift-ovn-kubernetes -o wideEnsure that all pods in the
openshift-ovn-kubernetesnamespace are in aRunningstate on both clusters.
12.8.4. DPU provisioning fails with BMC certificate errors Copy linkLink copied to clipboard!
If DPU provisioning fails with certificate errors when you add worker nodes by using the Bare Metal Operator, the baseboard management controller (BMC) certificates might be untrusted or expired, or the BareMetalHost credentials might be incorrect.
- Verify BMC certificate validity
Run the following command to inspect the BMC TLS certificate, replacing
<bmc_ip>with the BMC IP address and<bmc_hostname>with the BMC hostname:$ openssl s_client -connect <bmc_ip>:443 -servername <bmc_hostname>Update the certificates in the BMC configuration if they are expired or untrusted.
- Verify BareMetalHost BMC credentials
-
Ensure that the
BareMetalHostresource references the correct BMC secret and connection details, including the Redfish address and credentials for the worker server.
12.8.5. Worker node CSR approval fails Copy linkLink copied to clipboard!
If certificate signing request (CSR) approval for worker nodes fails, network connectivity between the management cluster and the DPU or hosted cluster path might be incomplete.
- Check Host-Based Networking pods on worker nodes
Run the following command to verify that HBN pods are running:
$ oc get pods -n openshift-hbn -o wide- Verify DPU management network connectivity
From a management cluster node, ping the DPU management IP address:
$ ping <dpu_management_ip>- Verify the
br-exbridge on worker nodes -
Confirm that the
br-exbridge that the workerMachineConfigresource creates is present and that required firewall rules allow traffic on the DPU management and high-speed networks.
12.8.6. DPU nodes remain NotReady in the hosted cluster Copy linkLink copied to clipboard!
If DPU nodes remain in a NotReady state in the hosted cluster, DPU provisioning might be incomplete, or the DPU firmware and DOCA software versions might be incompatible with the DPF Operator version.
- Check DPU and DPU service status on the management cluster
Run the following commands:
$ oc get dpu -n dpf-operator-system$ oc get dpuservice -n dpf-operator-system- Verify node status in the hosted cluster
Switch to the hosted cluster kubeconfig and list the nodes:
$ export KUBECONFIG=<path_to_hosted_cluster_kubeconfig>$ oc get nodes- Check DPF Operator and related pod logs
On the management cluster, inspect logs from DPF-related pods for provisioning or networking errors:
$ oc logs -n dpf-operator-system <dpu_related_pod_name>- Verify firmware and software compatibility
- Confirm that the BlueField firmware and DOCA software versions on the DPU are compatible with the DPF Operator version that you deployed.
12.8.7. Troubleshoot hosted cluster issues Copy linkLink copied to clipboard!
You can diagnose and resolve DPU hosted cluster issues, including CSR approval failures, kubeconfig access problems, and worker node join failures.
Prerequisites
- The DPF HCP Provisioner is installed and configured.
- DPU provisioning has completed on the management cluster.
- You have access to kubeconfig files for both the management cluster and the hosted cluster.
Procedure
Verify that the hosted cluster is accessible by running the following commands:
$ export KUBECONFIG=/path/to/hosted-cluster.kubeconfig$ oc cluster-infoIf the hosted cluster API server is not accessible, check the hosted control planes status on the management cluster.
Switch to the management cluster context and verify that the hosted control plane components are running:
$ export KUBECONFIG=/path/to/management-cluster.kubeconfig$ oc get pods -n clusters-$HOSTED_CLUSTER_NAMEVerify that the
etcd,kube-apiserver,kube-controller-manager, andkube-schedulerpods are all in aRunningstate.Check the DPF HCP Provisioner status for any error conditions:
$ oc get dpfhcpprovisioner -n dpf-operator-system -o yamlReview the
status.conditionsfield for any conditions that indicate a failure.Return to the hosted cluster context and check for pending CSRs:
$ export KUBECONFIG=/path/to/hosted-cluster.kubeconfig$ oc get csr --sort-by=.metadata.creationTimestampExample output
NAME AGE SIGNERNAME REQUESTOR CONDITION csr-abc12 30s kubernetes.io/kubelet-serving system:node:dpu-worker1 Pending csr-def34 25s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:abc123 PendingApprove any pending CSRs. To approve a single CSR, run the following command, replacing
<csr-name>with the CSR name:$ oc adm certificate approve <csr-name>To approve all pending CSRs in a single command, run:
$ oc get csr -o name | xargs oc adm certificate approveVerify that the DPU workers are joining the hosted cluster:
$ oc get nodesExample output
NAME STATUS ROLES AGE VERSION dpu-worker1 Ready worker 5m v1.35.6 dpu-worker2 Ready worker 5m v1.35.6If nodes are not joining, check whether the bootstrap token is still valid by running the following command on the hosted cluster:
$ oc get secrets -n kube-system | grep bootstrap-tokenBootstrap tokens have a limited lifetime. The DPF HCP Provisioner should create new tokens automatically. If tokens are expired and not being renewed, check the provisioner logs for errors.
Check the kubelet logs on the DPU for authentication or certificate errors. Switch to the management cluster context and open a debug shell on the DPU-enabled worker node:
$ export KUBECONFIG=/path/to/management-cluster.kubeconfig$ oc debug node/<dpu-enabled-worker-node>Inside the debug shell, run the following commands to stream the kubelet logs:
sh-5.1# chroot /hostsh-5.1# journalctl -u kubelet -fLook for authentication errors or certificate-related failures in the log output.
Verify that OVN-Kubernetes is running correctly on the hosted cluster. Switch to the hosted cluster context and run the following command:
$ export KUBECONFIG=/path/to/hosted-cluster.kubeconfig$ oc get pods -n openshift-ovn-kubernetes -o wideEnsure that OVN-Kubernetes pods are running on the DPU ARM cores.
Troubleshooting
CSR approval failures: Verify that the DPF HCP Provisioner has the required RBAC permissions to approve CSRs, check the provisioner logs for certificate-related errors, and ensure that the cluster CA is configured correctly.
Node join failures: Verify that the bootstrap kubeconfig was correctly generated by the provisioner, check network connectivity between the DPUs and the hosted control plane API server, and ensure that the kubelet configuration includes the correct API server endpoint.
Control plane access issues: Verify that the hosted cluster virtual IP address is configured and accessible, check the LoadBalancer service status for the hosted API server, and ensure that MetalLB is correctly configured and announcing the VIP.
Network connectivity problems: Verify the VTEP network configuration between DPUs, check that the DPU high-speed network interfaces are operational, and ensure that the required ports are open for inter-DPU communication.
12.8.8. Troubleshoot DPF networking issues Copy linkLink copied to clipboard!
You can diagnose and resolve DPF networking issues, including OVN-Kubernetes configuration problems, MTU mismatches, and connectivity failures.
Prerequisites
- DPU provisioning completed successfully.
- The hosted cluster is accessible with DPU worker nodes joined.
- You have access to both management and hosted cluster contexts.
Procedure
Verify OVN-Kubernetes pod status on the management cluster:
$ export KUBECONFIG=/path/to/management-cluster.kubeconfig$ oc get pods -n openshift-ovn-kubernetes -o wideCheck that the following pods are running:
-
ovnkube-control-plane-*pods are running on control plane nodes only. -
ovnkube-node-*pods are running on all nodes. -
ovs-node-*pods are running on all nodes.
-
Check OVN-Kubernetes configuration on the hosted cluster:
$ export KUBECONFIG=/path/to/hosted-cluster.kubeconfig$ oc get pods -n openshift-ovn-kubernetes -o wideVerify that OVN-Kubernetes pods are running on DPU ARM cores, not on host x86 CPUs.
Verify the network MTU configuration:
$ oc get network.operator.openshift.io cluster -o yaml | grep -A 5 defaultNetworkCheck the following MTU values:
- Standard networks: MTU 1400 for pods, 1500 for nodes.
- Jumbo frame networks: MTU 8940 for pods, 9000 for nodes.
Test basic pod-to-pod connectivity:
$ export KUBECONFIG=/path/to/hosted-cluster.kubeconfig$ oc run test-pod-1 --image=nicolaka/netshoot --rm -it -- /bin/bashFrom another terminal, run:
$ oc run test-pod-2 --image=nicolaka/netshoot --rm -it -- /bin/bashTest connectivity between the pods by using cluster IP addresses.
Check VTEP network configuration:
$ export KUBECONFIG=/path/to/management-cluster.kubeconfig$ oc debug node/<dpu-enabled-worker-node>In the debug shell, run:
$ chroot /host$ ip addr show | grep $VTEP_CIDRVerify that VTEP interfaces are configured with the correct IP addresses from the
VTEP_CIDRrange.Test VTEP connectivity:
$ ping -c 4 <other-dpu-vtep-ip>If the ping fails, check routing and firewall rules between DPU nodes.
Verify OVN database connectivity:
$ export KUBECONFIG=/path/to/hosted-cluster.kubeconfig$ oc exec -n openshift-ovn-kubernetes <ovnkube-node-pod> -- ovn-nbctl showThe output should display the OVN logical network topology.
Check OVN-Kubernetes log errors:
$ oc logs -n openshift-ovn-kubernetes <ovnkube-node-pod> -c ovn-controllerLook for the following error types:
- Database connectivity issues
- Port binding failures
- Flow programming errors
Verify service mesh connectivity:
$ export KUBECONFIG=/path/to/hosted-cluster.kubeconfig$ oc create service clusterip test-svc --tcp=80:80$ oc run test-client --image=nicolaka/netshoot --rm -it -- nc -vz test-svc 80A successful connection indicates that service traffic is flowing through the DPU data plane.
Check the SR-IOV network device plugin:
$ export KUBECONFIG=/path/to/management-cluster.kubeconfig$ oc get sriovnetworknodepolicy -n openshift-sriov-network-operatorVerify that SR-IOV policies are correctly applied to DPU-enabled worker nodes.
Troubleshooting
OVN-Kubernetes pod failures
Check that the OVN Helm chart version is compatible with your OpenShift Container Platform version. Verify that the CNI configuration matches the DPU acceleration requirements. Ensure that OVN databases are accessible from the DPU worker nodes.
MTU mismatch issues
Verify that all network components use consistent MTU values. Check that the physical network infrastructure supports the configured MTU. Update MTU values if the network environment has changed.
VTEP connectivity problems
Verify that the VTEP CIDR does not conflict with existing network ranges. Check that routing is configured between DPU nodes. Ensure that firewalls allow VTEP traffic on the required ports.
Service connectivity failures
Verify that kube-proxy is correctly configured on DPU nodes. Check that iptables rules are correctly programmed. Ensure that DPU acceleration is correctly handling service traffic.
SR-IOV configuration issues
Verify that the SR-IOV Operator is compatible with the DPU firmware. Check that the VF count matches the configured value. Ensure that VFs are correctly allocated to the correct namespaces.
12.8.9. DPF diagnostic commands and log collection Copy linkLink copied to clipboard!
You can run diagnostic commands and collect logs to investigate DPF component status, DPU provisioning failures, and hosted cluster issues when troubleshooting or opening support cases.
12.8.9.1. Quick status overview commands Copy linkLink copied to clipboard!
The following commands provide a quick overview of DPF component status:
DPF resource status
$ oc get dpudeployment,dpuservicetemplate,dpuserviceconfiguration,bfb,dpu -n dpf-operator-system
DPF Operator pod status
$ oc get pods -n dpf-operator-system -l app.kubernetes.io/part-of=dpf-operator
DPU-enabled worker node status
$ oc get nodes -l feature.node.kubernetes.io/dpu-enabled="" \
-o custom-columns=NAME:.metadata.name,STATUS:.status.conditions[?(@.type=="Ready")].status,AGE:.metadata.creationTimestamp
Hosted cluster status (if using HCP Provisioner)
$ oc get hostedcluster -n clusters-$HOSTED_CLUSTER_NAME
+
$ oc get nodepool -n clusters-$HOSTED_CLUSTER_NAME
12.8.9.2. Detailed diagnostic commands Copy linkLink copied to clipboard!
DPU provisioning status
$ oc describe dpu -n dpf-operator-system
+
$ oc describe bfb -n dpf-operator-system bf-bundle
DPF Operator configuration
$ oc get dpfoperatorconfig -n dpf-operator-system -o yaml
Service template and configuration status
$ oc describe dpuservicetemplate -n dpf-operator-system
+
$ oc describe dpuserviceconfiguration -n dpf-operator-system
DPU service status
$ oc get dpuservice -n dpf-operator-system -o wide
+
$ oc describe dpuservice -n dpf-operator-system
Node Feature Discovery status
$ oc get nodefeaturerule -n openshift-nfd
+
$ oc describe node <worker-node> | grep -A 20 "Labels:"
12.8.9.3. Log collection commands Copy linkLink copied to clipboard!
DPF Operator logs
$ oc logs -n dpf-operator-system -l app.kubernetes.io/name=dpf-operator --tail=200 > dpf-operator.log
HCP Provisioner logs (if using hosted clusters)
$ oc logs -n dpf-operator-system -l app.kubernetes.io/name=dpfhcp-provisioner-operator --tail=200 > dpfhcp-provisioner.log
Worker node kubelet logs
$ oc debug node/<dpu-worker-node>
+ In the debug shell, run:
+
$ chroot /host
+
$ journalctl -u kubelet --since "1 hour ago" > kubelet.log
OVN-Kubernetes logs
$ oc logs -n openshift-ovn-kubernetes -l app=ovnkube-node --tail=100 > ovn-kubernetes.log
SR-IOV Network Operator logs
$ oc logs -n openshift-sriov-network-operator -l app=sriov-network-operator --tail=100 > sriov-operator.log
Node Feature Discovery logs
$ oc logs -n openshift-nfd -l app=nfd-worker --tail=100 > nfd.log
12.8.9.4. System information collection Copy linkLink copied to clipboard!
Hardware information
$ oc debug node/<dpu-worker-node>
+ In the debug shell, run:
+
$ lspci | grep -i mellanox
+
$ lshw -class network
+
$ dmidecode -t system
DPU firmware information
$ mlxfwmanager --query
+
$ mst status
Network interface information
$ ip addr show
+
$ ip route show
+
$ ethtool -i <interface>
12.8.9.5. Performance monitoring commands Copy linkLink copied to clipboard!
DPU service metrics
$ oc exec -n dpf-operator-system <dts-service-pod> -- \
curl -s localhost:9189/metrics | grep -E "(current_link_speed|p[01]_eth_)"
Container resource usage
$ oc adm top pods -n dpf-operator-system --containers
+
$ oc adm top nodes -l feature.node.kubernetes.io/dpu-enabled=""
12.8.9.6. Support information package Copy linkLink copied to clipboard!
When opening a support case, collect the following information:
Environment information
- OpenShift Container Platform cluster version and build
- DPF Operator version and configuration
- Hardware specifications (server model, DPU model, firmware versions)
- Network topology and configuration
Configuration files
-
DPF Operator configuration (
dpfoperatorconfig) - Service templates and configurations
- Network policies and configurations
- Environment variables used during installation
Log files
- DPF Operator logs (past 24 hours)
- Worker node system logs (past 4 hours)
- Kubernetes event logs related to DPF resources
- Application logs for affected services
12.8.9.7. Common log analysis patterns Copy linkLink copied to clipboard!
Look for the following patterns in logs when troubleshooting:
DPU provisioning issues:
-
Error downloading BFB image -
Failed to detect DPU hardware -
Provisioning timeout exceeded
Networking issues:
-
OVN database connection failed -
Failed to program flows -
Interface binding failed
Service deployment issues:
-
Image pull failed -
Insufficient resources -
ConfigMap not found
Authentication issues:
-
Certificate signing request denied -
Unauthorized access to API server -
Token validation failed