From 9365e3404fd5e3b8b9ac0932d7a4e5ef9258b7d7 Mon Sep 17 00:00:00 2001 From: mattrowe-opennebula Date: Tue, 30 Jun 2026 14:24:18 +0200 Subject: [PATCH 01/38] F OpenNebula/one#7518: Hosts and Clusters restructure --- .../deploy_opennebula_onprem_with_poc_iso.md | 2 +- .../cloud_architecture_design.md | 8 ++++---- .../networking_system/nvidia_bluefield_dpu.md | 9 +++++++++ .../one_fabricmanager.md | 2 +- .../pci_passthrough_sriov/_index.md | 9 +++++++++ .../pci_passthrough_sriov/amd_gpu.md | 9 +++++++++ .../host_configuration.md | 9 +++++++++ .../network_interfaces.md | 9 +++++++++ .../nvidia_gpu_passthrough.md | 0 .../pci_passthrough_sriov/overview.md | 9 +++++++++ .../pci_passthrough.md | 0 .../vgpu.md | 2 +- .../hypervisor_configuration/lxc_driver.md | 2 +- .../windows_best_practice.md | 2 +- .../release_notes/platform_notes.md | 20 +++++++++---------- .../ai_ready_k8s.md | 2 +- .../deployment/cd_on-premises.md | 2 +- .../ai_factory_blueprints/overview.md | 2 +- 18 files changed, 76 insertions(+), 22 deletions(-) create mode 100644 content/product/cluster_configuration/networking_system/nvidia_bluefield_dpu.md rename content/product/cluster_configuration/{hosts_and_clusters => networking_system}/one_fabricmanager.md (97%) create mode 100644 content/product/cluster_configuration/pci_passthrough_sriov/_index.md create mode 100644 content/product/cluster_configuration/pci_passthrough_sriov/amd_gpu.md create mode 100644 content/product/cluster_configuration/pci_passthrough_sriov/host_configuration.md create mode 100644 content/product/cluster_configuration/pci_passthrough_sriov/network_interfaces.md rename content/product/cluster_configuration/{hosts_and_clusters => pci_passthrough_sriov}/nvidia_gpu_passthrough.md (100%) create mode 100644 content/product/cluster_configuration/pci_passthrough_sriov/overview.md rename content/product/cluster_configuration/{hosts_and_clusters => pci_passthrough_sriov}/pci_passthrough.md (100%) rename content/product/cluster_configuration/{hosts_and_clusters => pci_passthrough_sriov}/vgpu.md (99%) diff --git a/content/getting_started/try_opennebula/opennebula_sandbox_deployment/deploy_opennebula_onprem_with_poc_iso.md b/content/getting_started/try_opennebula/opennebula_sandbox_deployment/deploy_opennebula_onprem_with_poc_iso.md index d2e224aa7..f3de4e483 100644 --- a/content/getting_started/try_opennebula/opennebula_sandbox_deployment/deploy_opennebula_onprem_with_poc_iso.md +++ b/content/getting_started/try_opennebula/opennebula_sandbox_deployment/deploy_opennebula_onprem_with_poc_iso.md @@ -496,7 +496,7 @@ The filesystem `/` now will be 10GiB bigger with no loss of service. ## GPU Configuration -If the OpenNebula evaluation involves GPU management, GPU should be configured in pass-through mode. For the detailed process check [this guide from the official documentation]({{% relref "/product/cluster_configuration/hosts_and_clusters/nvidia_gpu_passthrough" %}}). Overall, a GPU configuration in OpenNebula consists from 2 main stages: +If the OpenNebula evaluation involves GPU management, GPU should be configured in pass-through mode. For the detailed process check [this guide from the official documentation]({{% relref "/product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough" %}}). Overall, a GPU configuration in OpenNebula consists from 2 main stages: - Host preparation and driver configuration - OpenNebula settings for PCI pass-through devices diff --git a/content/getting_started/understand_opennebula/cloud_architecture_and_design/cloud_architecture_design.md b/content/getting_started/understand_opennebula/cloud_architecture_and_design/cloud_architecture_design.md index 321558010..cee8858ee 100644 --- a/content/getting_started/understand_opennebula/cloud_architecture_and_design/cloud_architecture_design.md +++ b/content/getting_started/understand_opennebula/cloud_architecture_and_design/cloud_architecture_design.md @@ -65,10 +65,10 @@ After selecting the hypervisor(s) for your cloud, you are ready to **add the vir Now you should have an OpenNebula cloud up and running with at least one virtualization node. The next step is to configure OpenNebula to work with your infrastructure. OpenNebula directly manages the hypervisor, networking and storage platforms; and you may need additional configuration: -- **Networking setup** with [802.1Q VLANs]({{% relref "../../../product/cluster_configuration/networking_system/vlan#hm-vlan" %}}), [Open vSwitch]({{% relref "../../../product/cluster_configuration/networking_system/openvswitch#openvswitch" %}}) or [VXLAN]({{% relref "../../../product/cluster_configuration/networking_system/vxlan#vxlan" %}}). -- **Storage setup** with [NFS/NAS datastore]({{% relref "../../../product/cluster_configuration/storage_system/nas_ds#nas-ds" %}}), [Local Storage datastore]({{% relref "../../../product/cluster_configuration/storage_system/local_ds#local-ds" %}}), [SAN datastore]({{% relref "../../../product/cluster_configuration/lvm" %}}), [Ceph]({{% relref "../../../product/cluster_configuration/storage_system/ceph_ds#ceph-ds" %}}), [Dev]({{% relref "../../../product/cluster_configuration/storage_system/dev_ds#dev-ds" %}}), or [iSCSI]({{% relref "../../../product/cluster_configuration/san_storage/iscsi_ds#iscsi-ds" %}}) datastore. -- **Host setup** with the configuration options for the [KVM hosts]({{% relref "../../../product/operation_references/hypervisor_configuration/kvm_driver#kvmg" %}}), [LXC hosts]({{% relref "../../../product/operation_references/hypervisor_configuration/lxc_driver#lxdmg" %}}), [Monitoring subsystem]({{% relref "../../../product/cloud_system_administration/resource_monitoring" %}}), [Virtual Machine HA]({{% relref "../../../product/control_plane_configuration/high_availability/vm_ha#ftguide" %}}) or [PCI Passthrough]({{% relref "../../../product/cluster_configuration/hosts_and_clusters/pci_passthrough#kvm-pci-passthrough" %}}). -- **Authentication setup**, OpenNebula includes by default an internal **user/password authentication system**, but it can also use an external authentication driver such as [SSH]({{% relref "../../../product/cloud_system_administration/authentication_configuration/ssh#ssh-auth" %}}), [x509]({{% relref "../../../product/cloud_system_administration/authentication_configuration/x509#x509-auth" %}}), [LDAP]({{% relref "../../../product/cloud_system_administration/authentication_configuration/ldap#ldap" %}}) or [Active Directory]({{% relref "../../../product/cloud_system_administration/authentication_configuration/ldap#ldap" %}}). +- **Networking setup** with [802.1Q VLANs]({{% relref "product/cluster_configuration/networking_system/vlan#hm-vlan" %}}), [Open vSwitch]({{% relref "product/cluster_configuration/networking_system/openvswitch#openvswitch" %}}) or [VXLAN]({{% relref "../../../product/cluster_configuration/networking_system/vxlan#vxlan" %}}). +- **Storage setup** with [NFS/NAS datastore]({{% relref "product/cluster_configuration/storage_system/nas_ds#nas-ds" %}}), [Local Storage datastore]({{% relref "product/cluster_configuration/storage_system/local_ds#local-ds" %}}), [SAN datastore]({{% relref "../../../product/cluster_configuration/lvm" %}}), [Ceph]({{% relref "product/cluster_configuration/storage_system/ceph_ds#ceph-ds" %}}), [Dev]({{% relref "product/cluster_configuration/storage_system/dev_ds#dev-ds" %}}), or [iSCSI]({{% relref "product/cluster_configuration/san_storage/iscsi_ds#iscsi-ds" %}}) datastore. +- **Host setup** with the configuration options for the [KVM hosts]({{% relref "product/operation_references/hypervisor_configuration/kvm_driver#kvmg" %}}), [LXC hosts]({{% relref "product/operation_references/hypervisor_configuration/lxc_driver#lxdmg" %}}), [Monitoring subsystem]({{% relref "product/cloud_system_administration/resource_monitoring" %}}), [Virtual Machine HA]({{% relref "../../../product/control_plane_configuration/high_availability/vm_ha#ftguide" %}}) or [PCI Passthrough]({{% relref "product/cluster_configuration/pci_passthrough_sriov/pci_passthrough#kvm-pci-passthrough" %}}). +- **Authentication setup**, OpenNebula includes by default an internal **user/password authentication system**, but it can also use an external authentication driver such as [SSH]({{% relref "product/cloud_system_administration/authentication_configuration/ssh#ssh-auth" %}}), [x509]({{% relref "product/cloud_system_administration/authentication_configuration/x509#x509-auth" %}}), [LDAP]({{% relref "product/cloud_system_administration/authentication_configuration/ldap#ldap" %}}) or [Active Directory]({{% relref "product/cloud_system_administration/authentication_configuration/ldap#ldap" %}}). ### 3.4. Configure Cloud Services diff --git a/content/product/cluster_configuration/networking_system/nvidia_bluefield_dpu.md b/content/product/cluster_configuration/networking_system/nvidia_bluefield_dpu.md new file mode 100644 index 000000000..b5c512b05 --- /dev/null +++ b/content/product/cluster_configuration/networking_system/nvidia_bluefield_dpu.md @@ -0,0 +1,9 @@ +--- +title: "NVIDIA BlueField DPU (AE)" +linkTitle: "NVIDIA BlueField DPU (AE)" +date: "2026-06-30" +categories: ["networking"] +pageintoc: "64" +tags: ["networking", "hpc", "ai", "nvidia", "spectrum-x", "evpn"] +weight: "8" +--- \ No newline at end of file diff --git a/content/product/cluster_configuration/hosts_and_clusters/one_fabricmanager.md b/content/product/cluster_configuration/networking_system/one_fabricmanager.md similarity index 97% rename from content/product/cluster_configuration/hosts_and_clusters/one_fabricmanager.md rename to content/product/cluster_configuration/networking_system/one_fabricmanager.md index fe87f52bd..029609d99 100644 --- a/content/product/cluster_configuration/hosts_and_clusters/one_fabricmanager.md +++ b/content/product/cluster_configuration/networking_system/one_fabricmanager.md @@ -59,7 +59,7 @@ To begin the installation and configuration, verify these prerequisites: * KVM Node Package: ensures that the `opennebula-kvm-node` EE package is installed on every KVM host that contains NVSwitch devices. This package contains the `opennebula-fabricmanager` service. -* NVSwitch PCI passthrough Setup: the NVSwitch devices must be prepared for PCI passthrough using the vfio-pci driver. Configure these devices at OpenNebula deployment time using one-deploy; check [here]({{% relref "/product/cluster_configuration/hosts_and_clusters/pci_passthrough#vfio-device-binding" %}}) for instructions. If this is not done during deployment, it is possible to manually configure the NVSwitches to use the virtio-pci driver by following the "Hypervisor Configuration" section from [NVIDIA GPU Passthrough]({{% relref "./nvidia_gpu_passthrough" %}}). +* NVSwitch PCI passthrough Setup: the NVSwitch devices must be prepared for PCI passthrough using the vfio-pci driver. Configure these devices at OpenNebula deployment time using one-deploy; check [here]({{% relref "product/cluster_configuration/pci_passthrough_sriov/pci_passthrough#vfio-device-binding" %}}) for instructions. If this is not done during deployment, it is possible to manually configure the NVSwitches to use the virtio-pci driver by following the "Hypervisor Configuration" section from [NVIDIA GPU Passthrough]({{% relref "nvidia_gpu_passthrough" %}}). Once you have validated the prerequisites, start OpenNebula FabricManager service: the `opennebula-fabricmanager` service on the host is disabled by default, as it is designed to be started and stopped on demand or managed by you as the OpenNebula administrator. diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/_index.md b/content/product/cluster_configuration/pci_passthrough_sriov/_index.md new file mode 100644 index 000000000..cfb92749d --- /dev/null +++ b/content/product/cluster_configuration/pci_passthrough_sriov/_index.md @@ -0,0 +1,9 @@ +--- +title: "PCI Passthrough and SR-IOV" +date: "2026-06-30" +description: "Enable VMs to access PCI devices directly, including GPUs, high-performance network adapters and storage controllers." +categories: +pageintoc: "58" +tags: +weight: "2" +--- \ No newline at end of file diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/amd_gpu.md b/content/product/cluster_configuration/pci_passthrough_sriov/amd_gpu.md new file mode 100644 index 000000000..f08aec08e --- /dev/null +++ b/content/product/cluster_configuration/pci_passthrough_sriov/amd_gpu.md @@ -0,0 +1,9 @@ +--- +title: "AMD GPU" +date: "2026-06-30" +description: +categories: +pageintoc: "58" +tags: ['AI','NVIDIA'] +weight: "2" +--- \ No newline at end of file diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/host_configuration.md b/content/product/cluster_configuration/pci_passthrough_sriov/host_configuration.md new file mode 100644 index 000000000..391079a43 --- /dev/null +++ b/content/product/cluster_configuration/pci_passthrough_sriov/host_configuration.md @@ -0,0 +1,9 @@ +--- +title: "Host Configuration" +date: "2026-06-30" +description: +categories: +pageintoc: "58" +tags: ['AI','NVIDIA'] +weight: "2" +--- \ No newline at end of file diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/network_interfaces.md b/content/product/cluster_configuration/pci_passthrough_sriov/network_interfaces.md new file mode 100644 index 000000000..2b83b467e --- /dev/null +++ b/content/product/cluster_configuration/pci_passthrough_sriov/network_interfaces.md @@ -0,0 +1,9 @@ +--- +title: "Network Interfaces" +date: "2026-06-30" +description: +categories: +pageintoc: "58" +tags: ['AI','NVIDIA'] +weight: "3" +--- \ No newline at end of file diff --git a/content/product/cluster_configuration/hosts_and_clusters/nvidia_gpu_passthrough.md b/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough.md similarity index 100% rename from content/product/cluster_configuration/hosts_and_clusters/nvidia_gpu_passthrough.md rename to content/product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough.md diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/overview.md b/content/product/cluster_configuration/pci_passthrough_sriov/overview.md new file mode 100644 index 000000000..2d1930178 --- /dev/null +++ b/content/product/cluster_configuration/pci_passthrough_sriov/overview.md @@ -0,0 +1,9 @@ +--- +title: "Overview" +date: "2026-06-30" +description: +categories: +pageintoc: "52" +tags: +weight: "1" +--- \ No newline at end of file diff --git a/content/product/cluster_configuration/hosts_and_clusters/pci_passthrough.md b/content/product/cluster_configuration/pci_passthrough_sriov/pci_passthrough.md similarity index 100% rename from content/product/cluster_configuration/hosts_and_clusters/pci_passthrough.md rename to content/product/cluster_configuration/pci_passthrough_sriov/pci_passthrough.md diff --git a/content/product/cluster_configuration/hosts_and_clusters/vgpu.md b/content/product/cluster_configuration/pci_passthrough_sriov/vgpu.md similarity index 99% rename from content/product/cluster_configuration/hosts_and_clusters/vgpu.md rename to content/product/cluster_configuration/pci_passthrough_sriov/vgpu.md index cc1f60f45..39a2d2d8b 100644 --- a/content/product/cluster_configuration/hosts_and_clusters/vgpu.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/vgpu.md @@ -6,7 +6,7 @@ description: categories: pageintoc: "57" tags: ['AI','NVIDIA'] -weight: "6" +weight: "4" --- diff --git a/content/product/operation_references/hypervisor_configuration/lxc_driver.md b/content/product/operation_references/hypervisor_configuration/lxc_driver.md index 8f3608ebf..ce7142d79 100644 --- a/content/product/operation_references/hypervisor_configuration/lxc_driver.md +++ b/content/product/operation_references/hypervisor_configuration/lxc_driver.md @@ -73,7 +73,7 @@ Some of the VM actions available in the OpenNebula API are not implemented yet f ### PCI Passthrough -You can perform NIC PCI Passthrough on containers. For this you simply need the [PCI NICs to be monitored in the LXC hosts]({{% relref "../../cluster_configuration/hosts_and_clusters/pci_passthrough.md#driver-configuration" %}}). The configuration file for the PCI device detection is `/var/lib/one/remotes/etc/im/lxc-probes.d/pci.conf`. Once monitoring is successful, you can [use this PCI NIC]({{% relref "../../cluster_configuration/hosts_and_clusters/pci_passthrough.md#usage" %}}) +You can perform NIC PCI Passthrough on containers. For this you simply need the [PCI NICs to be monitored in the LXC hosts]({{% relref "../../cluster_configuration/pci_passthrough_sriov/pci_passthrough.md#driver-configuration" %}}). The configuration file for the PCI device detection is `/var/lib/one/remotes/etc/im/lxc-probes.d/pci.conf`. Once monitoring is successful, you can [use this PCI NIC]({{% relref "../../cluster_configuration/pci_passthrough_sriov/pci_passthrough.md#usage" %}}) by declaring in it on the VM Template or hot plugging it. Example PCI device monitoring diff --git a/content/product/virtual_machines_operation/guest_operating_systems/windows_best_practice.md b/content/product/virtual_machines_operation/guest_operating_systems/windows_best_practice.md index 15d812d53..1ab9ed646 100644 --- a/content/product/virtual_machines_operation/guest_operating_systems/windows_best_practice.md +++ b/content/product/virtual_machines_operation/guest_operating_systems/windows_best_practice.md @@ -133,7 +133,7 @@ Under the Inputs section select a Tablet type on USB bus, then click Add. This w Defining a Virtio model display device at a higher resolution can be useful here as well; this can allow higher resolutions in the desktop. -If you are using non-networking PCI Passthrough devices, this is the place to add them too, such as GPUs. See the [PCI Passthrough Guide]({{% relref "../../cluster_configuration/hosts_and_clusters/pci_passthrough#kvm-pci-passthrough" %}}). +If you are using non-networking PCI Passthrough devices, this is the place to add them too, such as GPUs. See the [PCI Passthrough Guide]({{% relref "../../cluster_configuration/pci_passthrough_sriov/pci_passthrough#kvm-pci-passthrough" %}}). #### Tags diff --git a/content/software/release_information/release_notes/platform_notes.md b/content/software/release_information/release_notes/platform_notes.md index 0392013bc..914860f57 100644 --- a/content/software/release_information/release_notes/platform_notes.md +++ b/content/software/release_information/release_notes/platform_notes.md @@ -73,22 +73,22 @@ More information: [one-apps wiki](https://github.com/OpenNebula/one-apps/wiki) | **Component** | **Version** | **More information** | |---------------------|--------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------| -| 8021q kernel module | Version included in the Linux distribution | [802.1Q VLAN]({{% relref "../../../product/cluster_configuration/networking_system/vlan#hm-vlan" %}}) | -| Open vSwitch | Version included in the Linux distribution | [Open vSwitch]({{% relref "../../../product/cluster_configuration/networking_system/openvswitch#openvswitch" %}}) | -| iproute2 | Version included in the Linux distribution | [VXLAN]({{% relref "../../../product/cluster_configuration/networking_system/vxlan#vxlan" %}}) | -| Spectrum-X | N/A | [Spectrum-X documentation]({{% relref "../../../product/cluster_configuration/networking_system/spectrumx" %}}) | -| InfiniBand | N/A | [PCI Passthrough]({{% relref "product/cluster_configuration/hosts_and_clusters/pci_passthrough/" %}}) | +| 8021q kernel module | Version included in the Linux distribution | [802.1Q VLAN]({{% relref "product/cluster_configuration/networking_system/vlan#hm-vlan" %}}) | +| Open vSwitch | Version included in the Linux distribution | [Open vSwitch]({{% relref "product/cluster_configuration/networking_system/openvswitch#openvswitch" %}}) | +| iproute2 | Version included in the Linux distribution | [VXLAN]({{% relref "product/cluster_configuration/networking_system/vxlan#vxlan" %}}) | +| Spectrum-X | N/A | [Spectrum-X documentation]({{% relref "product/cluster_configuration/networking_system/spectrumx" %}}) | +| InfiniBand | N/A | [PCI Passthrough]({{% relref "product/cluster_configuration/pci_passthrough_sriov/pci_passthrough/" %}}) | ### Storage Infrastructure | **Component** | **Version** | **More information** | |-----------|--------------------------------------------|--------------------------------------------------------------------------------------------------------------| -| iSCSI | Version included in the Linux distribution | [LVM Drivers]({{% relref "../../../product/cluster_configuration/lvm" %}}) | -| LVM2 | Version included in the Linux distribution | [LVM Drivers]({{% relref "../../../product/cluster_configuration/lvm" %}}) | -| Ceph | Reef v18.2.x
Squid v19.2.x | [The Ceph Datastore]({{% relref "../../../product/cluster_configuration/storage_system/ceph_ds#ceph-ds" %}}) | -| NetApp | ONTAP 9.16.1P1. | [NetApp ONTAP Drivers]({{% relref "../../../product/cluster_configuration/san_storage/netapp" %}}) | +| iSCSI | Version included in the Linux distribution | [LVM Drivers]({{% relref "product/cluster_configuration/lvm" %}}) | +| LVM2 | Version included in the Linux distribution | [LVM Drivers]({{% relref "product/cluster_configuration/lvm" %}}) | +| Ceph | Reef v18.2.x
Squid v19.2.x | [The Ceph Datastore]({{% relref "product/cluster_configuration/storage_system/ceph_ds#ceph-ds" %}}) | +| NetApp | ONTAP 9.16.1P1. | [NetApp ONTAP Drivers]({{% relref "product/cluster_configuration/san_storage/netapp" %}}) | | Everpure | 6.7.2 | [Everpure SAN Datastore]({{% relref "product/cluster_configuration/san_storage/everpure" %}}) | -| LVM-thin | NetApp ONTAP 9.16.1P1 | [LVM Thin]({{% relref "../../../product/cluster_configuration/lvm" %}}) | +| LVM-thin | NetApp ONTAP 9.16.1P1 | [LVM Thin]({{% relref "product/cluster_configuration/lvm" %}}) | ### Accelerated Infrastructure diff --git a/content/solutions/ai_factory_blueprints/containerized_ai_execution/ai_ready_k8s.md b/content/solutions/ai_factory_blueprints/containerized_ai_execution/ai_ready_k8s.md index 98176d9d4..38ea9fe98 100644 --- a/content/solutions/ai_factory_blueprints/containerized_ai_execution/ai_ready_k8s.md +++ b/content/solutions/ai_factory_blueprints/containerized_ai_execution/ai_ready_k8s.md @@ -286,7 +286,7 @@ The CAPI appliance takes some minutes to be in “Ready” status. Once the appl EOF ``` - The number of GPU devices mounted in each worker node depends on the definition of the `PCI` attribute in the worker nodes template (note that the attributes of this map could change depending on the GPU model). In our case, we are deploying 2 worker nodes, with 1 GPU attached to each one. In case you only have available a single GPU card, change the number or `WORKER_MACHINE_COUNT` to 1. More information on [NVIDIA GPU Passthrough]({{% relref "product/cluster_configuration/hosts_and_clusters/nvidia_gpu_passthrough.md#pci-device-passthrough" %}}) section. In this example, we will attach a single NVIDIA GPU card to each worker nodes. + The number of GPU devices mounted in each worker node depends on the definition of the `PCI` attribute in the worker nodes template (note that the attributes of this map could change depending on the GPU model). In our case, we are deploying 2 worker nodes, with 1 GPU attached to each one. In case you only have available a single GPU card, change the number or `WORKER_MACHINE_COUNT` to 1. More information on [NVIDIA GPU Passthrough]({{% relref "product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough.md#pci-device-passthrough" %}}) section. In this example, we will attach a single NVIDIA GPU card to each worker nodes. 5. Once the `values.yaml` file is available, you can proceed to deploy the workload Cluster with Helm. First, add the helm chart repo for CAPONE and apply the helm chart referencing the values file: diff --git a/content/solutions/ai_factory_blueprints/deployment/cd_on-premises.md b/content/solutions/ai_factory_blueprints/deployment/cd_on-premises.md index 21b485412..1c9998b4f 100644 --- a/content/solutions/ai_factory_blueprints/deployment/cd_on-premises.md +++ b/content/solutions/ai_factory_blueprints/deployment/cd_on-premises.md @@ -41,7 +41,7 @@ If IOMMU is not active, add the appropriate parameter to the kernel's boot comma * For Intel CPUs: `intel_iommu=on` * For AMD CPUs: `amd_iommu=on` -For a detailed guide on how to perform this kernel configuration, refer to the [NVIDIA GPU Passthrough documentation]({{% relref "product/cluster_configuration/hosts_and_clusters/nvidia_gpu_passthrough.md" %}}). +For a detailed guide on how to perform this kernel configuration, refer to the [NVIDIA GPU Passthrough documentation]({{% relref "product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough.md" %}}). ### Hypervisor Preparation diff --git a/content/solutions/ai_factory_blueprints/overview.md b/content/solutions/ai_factory_blueprints/overview.md index 63f54b69c..518d757f0 100644 --- a/content/solutions/ai_factory_blueprints/overview.md +++ b/content/solutions/ai_factory_blueprints/overview.md @@ -23,7 +23,7 @@ The purpose of the AI Factory collection is to provide a step-by-step process fo Configuring, deploying and validating a high-performance AI infrastructure using OpenNebula involves these steps: -1. Familiarize yourself with **Architecture and Specifications**. We recommend consulting the [guide on GPU PCI-passthrough]({{% relref "product/cluster_configuration/hosts_and_clusters/nvidia_gpu_passthrough" %}}) for details relating to your GPU hardware and IOMMU. +1. Familiarize yourself with **Architecture and Specifications**. We recommend consulting the [guide on GPU PCI-passthrough]({{% relref "product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough" %}}) for details relating to your GPU hardware and IOMMU.
2. Deploy and configure your AI Factory with one of these alternatives: From 78da126799e72ceabec44fd53cd3e7e280a16f33 Mon Sep 17 00:00:00 2001 From: mattrowe-opennebula Date: Fri, 10 Jul 2026 11:54:51 +0200 Subject: [PATCH 02/38] F OpenNebula/one#7518: Content transfer --- .../hosts_and_clusters/cluster_guide.md | 2 +- .../hosts_and_clusters/hosts.md | 2 +- .../hosts_and_clusters/numa.md | 6 +- .../networking_system/bridged.md | 2 +- .../networking_system/infiniband.md | 122 ++++ .../networking_system/nvidia_bluefield_dpu.md | 6 +- .../networking_system/openvswitch.md | 2 +- .../networking_system/vlan.md | 2 +- .../networking_system/vxlan.md | 2 +- .../{amd_gpu.md => amd_gpu_passthrough.md} | 9 +- .../axelera_gpu_passthrough.md | 10 + .../host_configuration.md | 434 ++++++++++++- .../network_interfaces.md | 253 +++++++- .../nvidia_gpu_passthrough.md | 603 +++++++++++++----- .../nvidia_grace_platform.md | 267 ++++++++ .../pci_passthrough_sriov/nvidia_vswitch.md | 10 + .../one_fabricmanager.md | 2 +- .../pci_passthrough_sriov/overview.md | 69 +- .../pci_passthrough_sriov/pci_passthrough.md | 2 +- .../pci_passthrough_sriov/vgpu.md | 1 + 20 files changed, 1619 insertions(+), 187 deletions(-) create mode 100644 content/product/cluster_configuration/networking_system/infiniband.md rename content/product/cluster_configuration/pci_passthrough_sriov/{amd_gpu.md => amd_gpu_passthrough.md} (50%) create mode 100644 content/product/cluster_configuration/pci_passthrough_sriov/axelera_gpu_passthrough.md create mode 100644 content/product/cluster_configuration/pci_passthrough_sriov/nvidia_grace_platform.md create mode 100644 content/product/cluster_configuration/pci_passthrough_sriov/nvidia_vswitch.md rename content/product/cluster_configuration/{networking_system => pci_passthrough_sriov}/one_fabricmanager.md (99%) diff --git a/content/product/cluster_configuration/hosts_and_clusters/cluster_guide.md b/content/product/cluster_configuration/hosts_and_clusters/cluster_guide.md index b057089e0..c60ea7f86 100644 --- a/content/product/cluster_configuration/hosts_and_clusters/cluster_guide.md +++ b/content/product/cluster_configuration/hosts_and_clusters/cluster_guide.md @@ -1,5 +1,5 @@ --- -title: "Clusters" +title: "Cluster Management" date: "2025-02-17" description: categories: diff --git a/content/product/cluster_configuration/hosts_and_clusters/hosts.md b/content/product/cluster_configuration/hosts_and_clusters/hosts.md index 5dd5f6251..847e2ca50 100644 --- a/content/product/cluster_configuration/hosts_and_clusters/hosts.md +++ b/content/product/cluster_configuration/hosts_and_clusters/hosts.md @@ -1,5 +1,5 @@ --- -title: "Hosts" +title: "Host Management" date: "2025-02-17" description: categories: diff --git a/content/product/cluster_configuration/hosts_and_clusters/numa.md b/content/product/cluster_configuration/hosts_and_clusters/numa.md index 6d6531cea..893f26661 100644 --- a/content/product/cluster_configuration/hosts_and_clusters/numa.md +++ b/content/product/cluster_configuration/hosts_and_clusters/numa.md @@ -16,9 +16,9 @@ weight: "4" In this guide you’ll learn to set up OpenNebula to control how VM resources are mapped onto the hypervisor ones. These settings will help you to fine tune the performance of VMs. We will use the following concepts: -* **Cores, Threads, and Sockets**. A computer processor is connected to the motherboard through a *socket*. A processor can pack one or more *cores*, each one implements a separate processing unit that shares some cache levels, memory, and I/O ports. CPU cores’ performance can be improved by the use of hardware *multi-threading* (SMT) that permits multiple execution flows to run simultaneously on a single core. -* **NUMA**. Multi-processor servers are usually arranged in nodes or cells. Each *NUMA node* holds a fraction of the overall system memory. In this configuration, a processor accesses memory and I/O ports local to its node faster than those of non-local ones. -* **Hugepages**. Systems with big physical memory also use a large number of virtual memory pages. This big number makes the use of virtual-to-physical translation caches inefficient. Hugepages reduces the number of virtual pages in the system and optimizes the virtual memory subsystem. +* **Cores, Threads, and Sockets**: A computer processor is connected to the motherboard through a *socket*. A processor can pack one or more *cores*, each one implements a separate processing unit that shares some cache levels, memory, and I/O ports. CPU cores’ performance can be improved by the use of hardware *multi-threading* (SMT) that permits multiple execution flows to run simultaneously on a single core. +* **NUMA**: Multi-processor servers are usually arranged in nodes or cells. Each *NUMA node* holds a fraction of the overall system memory. In this configuration, a processor accesses memory and I/O ports local to its node faster than those of non-local ones. +* **Hugepages**: Systems with big physical memory also use a large number of virtual memory pages. This big number makes the use of virtual-to-physical translation caches inefficient. Hugepages reduces the number of virtual pages in the system and optimizes the virtual memory subsystem. In OpenNebula the virtual topology of a VM is defined by the number of sockets, cores, and threads. We assume that a NUMA node or cell is equivalent to a socket and they will be used interchangeably in this guide. diff --git a/content/product/cluster_configuration/networking_system/bridged.md b/content/product/cluster_configuration/networking_system/bridged.md index 827877092..343c9faf9 100644 --- a/content/product/cluster_configuration/networking_system/bridged.md +++ b/content/product/cluster_configuration/networking_system/bridged.md @@ -5,7 +5,7 @@ description: categories: pageintoc: "62" tags: -weight: "4" +weight: "3" --- diff --git a/content/product/cluster_configuration/networking_system/infiniband.md b/content/product/cluster_configuration/networking_system/infiniband.md new file mode 100644 index 000000000..30eaa5dd5 --- /dev/null +++ b/content/product/cluster_configuration/networking_system/infiniband.md @@ -0,0 +1,122 @@ +--- +title: "InfiniBand" +date: "2026-07-10" +categories: ["networking"] +pageintoc: "64" +tags: ["networking"] +weight: "7" +--- + +InfiniBand is a high-performance networking technology designed for environments where extremely low latency, high throughput, and efficient CPU utilization are critical. It is widely used in High Performance Computing (HPC), AI training and inference clusters, and other data-intensive workloads that require significantly higher performance than conventional Ethernet networks. InfiniBand achieves this through technologies such as Remote Direct Memory Access (RDMA), allowing applications to exchange data directly between systems with minimal CPU involvement. + +OpenNebula supports deployment on infrastructure equipped with InfiniBand fabrics, enabling virtualized and bare-metal workloads to take advantage of high-speed interconnects. Depending on the workload requirements, InfiniBand can be used in several different ways: + +* As an IP network using IP over InfiniBand (IPoIB). +* By exposing InfiniBand adapters directly to Virtual Machines using PCI Passthrough or SR-IOV Virtual Functions (VFs). +* For storage and cluster communication over high-speed fabrics. +* For applications that use RDMA directly. + +## Typical Use Cases + +InfiniBand is most commonly deployed for workloads such as: + +* AI and machine learning training clusters +* High Performance Computing (HPC) +* Scientific simulations +* High-performance distributed storage +* MPI-based parallel applications +* GPU clusters requiring low-latency node-to-node communication + +These environments benefit from InfiniBand's low latency, high bandwidth, and efficient RDMA transport. + +## Deployment Models + +OpenNebula does not implement a dedicated InfiniBand networking driver. Instead, InfiniBand is integrated using the standard Linux networking stack and OpenNebula's existing networking and PCI device management capabilities. + +## IP over InfiniBand (IPoIB) + +The simplest deployment method is IP over InfiniBand (IPoIB), where the InfiniBand fabric behaves as a conventional IP network. + +Once the host operating system has configured the InfiniBand interfaces, they appear as standard Linux network interfaces and can be used throughout OpenNebula just like Ethernet interfaces. + +Typical uses include: + +* Front-end and back-end Cluster communication +* Storage traffic +* Virtual Network bridges +* VXLAN or VLAN transport over the InfiniBand fabric (where supported by the underlying infrastructure) + +From OpenNebula's perspective, no special configuration is required beyond using the appropriate bridge or physical interface when defining Virtual Networks. + +## PCI Passthrough + +Applications that require native InfiniBand capabilities or RDMA typically require direct access to the InfiniBand Host Channel Adapter (HCA). + +OpenNebula supports assigning InfiniBand adapters directly to Virtual Machines using PCI Passthrough. This provides the guest operating system with direct hardware access, allowing it to install the appropriate InfiniBand drivers and use the adapter as if running on bare metal. + +Configuration follows the standard PCI Passthrough workflow described in the PCI Passthrough documentation. + +## SR-IOV Virtual Functions + +Many modern InfiniBand adapters support Single Root I/O Virtualization (SR-IOV), allowing multiple Virtual Functions (VFs) to be created from a single physical adapter. + +OpenNebula can schedule and assign these Virtual Functions directly to Virtual Machines, providing: + +* Near-native networking performance +* RDMA support +* Lower overhead than emulated virtual NICs +* Efficient sharing of high-performance network adapters + +When using SR-IOV network devices, OpenNebula can configure attributes such as: + +* MAC address +* VLAN ID +* Spoof checking +* Trust mode + +depending on whether the adapter operates in Legacy or Switchdev mode. + +## Host Requirements + +Before deploying workloads using InfiniBand, ensure that each host is correctly configured by the operating system. + +Typical requirements include: + +* Supported InfiniBand Host Channel Adapters (HCAs) +* Vendor drivers and firmware +* RDMA software stack (for example, RDMA Core or vendor-provided drivers) +* A functioning InfiniBand fabric +* An operational Subnet Manager (such as OpenSM), which is required for InfiniBand fabrics to function correctly +* Appropriate kernel modules and IPoIB configuration if using IP networking over InfiniBand + +OpenNebula assumes that the InfiniBand infrastructure has already been configured and validated by the operating system. + +## Guest Requirements + +If Virtual Machines require native InfiniBand functionality, the guest operating system must include: + +* InfiniBand drivers +* RDMA libraries (when required) +* Appropriate user-space software for the intended workload + +Guests using PCI Passthrough or SR-IOV interact directly with the assigned hardware and are responsible for managing the device. + +Considerations + +When planning an InfiniBand deployment, consider the following: + +PCI Passthrough and SR-IOV provide the highest performance but may reduce Virtual Machine mobility, including live migration support, depending on the hardware and deployment configuration. + +IPoIB offers excellent compatibility with existing networking tools but does not expose all RDMA capabilities to applications. +Applications must be specifically designed or configured to use RDMA in order to benefit from InfiniBand's lowest latency communication. + +Network configuration, firmware management, and Subnet Manager deployment remain the responsibility of the underlying operating system and network infrastructure. + +## Related Documentation + +* PCI Passthrough +* Virtual Networks +* Linux Bridge Networks +* Open vSwitch Networks +* NVIDIA Spectrum-X +* Bare Metal Provisioning (when using InfiniBand-enabled hosts) \ No newline at end of file diff --git a/content/product/cluster_configuration/networking_system/nvidia_bluefield_dpu.md b/content/product/cluster_configuration/networking_system/nvidia_bluefield_dpu.md index b5c512b05..a1b936ac8 100644 --- a/content/product/cluster_configuration/networking_system/nvidia_bluefield_dpu.md +++ b/content/product/cluster_configuration/networking_system/nvidia_bluefield_dpu.md @@ -5,5 +5,7 @@ date: "2026-06-30" categories: ["networking"] pageintoc: "64" tags: ["networking", "hpc", "ai", "nvidia", "spectrum-x", "evpn"] -weight: "8" ---- \ No newline at end of file +weight: "9" +--- + +Work in progress. \ No newline at end of file diff --git a/content/product/cluster_configuration/networking_system/openvswitch.md b/content/product/cluster_configuration/networking_system/openvswitch.md index 257f1df62..83bbd78f6 100644 --- a/content/product/cluster_configuration/networking_system/openvswitch.md +++ b/content/product/cluster_configuration/networking_system/openvswitch.md @@ -6,7 +6,7 @@ description: categories: pageintoc: "65" tags: -weight: "7" +weight: "6" --- diff --git a/content/product/cluster_configuration/networking_system/vlan.md b/content/product/cluster_configuration/networking_system/vlan.md index f98dff442..778b15210 100644 --- a/content/product/cluster_configuration/networking_system/vlan.md +++ b/content/product/cluster_configuration/networking_system/vlan.md @@ -6,7 +6,7 @@ description: categories: pageintoc: "63" tags: -weight: "5" +weight: "4" --- diff --git a/content/product/cluster_configuration/networking_system/vxlan.md b/content/product/cluster_configuration/networking_system/vxlan.md index b1eff7f8b..c07f7507a 100644 --- a/content/product/cluster_configuration/networking_system/vxlan.md +++ b/content/product/cluster_configuration/networking_system/vxlan.md @@ -6,7 +6,7 @@ description: categories: pageintoc: "64" tags: -weight: "6" +weight: "5" --- diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/amd_gpu.md b/content/product/cluster_configuration/pci_passthrough_sriov/amd_gpu_passthrough.md similarity index 50% rename from content/product/cluster_configuration/pci_passthrough_sriov/amd_gpu.md rename to content/product/cluster_configuration/pci_passthrough_sriov/amd_gpu_passthrough.md index f08aec08e..3d4ecce17 100644 --- a/content/product/cluster_configuration/pci_passthrough_sriov/amd_gpu.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/amd_gpu_passthrough.md @@ -1,9 +1,12 @@ --- -title: "AMD GPU" +title: "AMD GPU Passthrough" +linkTitle: "AMD GPUs" date: "2026-06-30" description: categories: pageintoc: "58" tags: ['AI','NVIDIA'] -weight: "2" ---- \ No newline at end of file +weight: "6" +--- + +Work in progress. \ No newline at end of file diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/axelera_gpu_passthrough.md b/content/product/cluster_configuration/pci_passthrough_sriov/axelera_gpu_passthrough.md new file mode 100644 index 000000000..c3ad65ae3 --- /dev/null +++ b/content/product/cluster_configuration/pci_passthrough_sriov/axelera_gpu_passthrough.md @@ -0,0 +1,10 @@ +--- +title: "Axelera GPU Passthrough" +linkTitle: "Axelera GPUs" +date: "2025-10-16" +description: +categories: +pageintoc: "58" +tags: ['AI','NVIDIA'] +weight: "7" +--- \ No newline at end of file diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/host_configuration.md b/content/product/cluster_configuration/pci_passthrough_sriov/host_configuration.md index 391079a43..c076c5a92 100644 --- a/content/product/cluster_configuration/pci_passthrough_sriov/host_configuration.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/host_configuration.md @@ -6,4 +6,436 @@ categories: pageintoc: "58" tags: ['AI','NVIDIA'] weight: "2" ---- \ No newline at end of file +--- + +This guide describes the common host configuration required to enable PCI passthrough in OpenNebula. These requirements apply independently of the type of PCI device being assigned to virtual machines. Device-specific configuration is covered in the corresponding guides. +The guide assumes a Linux host running the OpenNebula KVM hypervisor. While the examples use common Linux utilities and a GRUB-based bootloader, equivalent procedures can be used with other Linux distributions and bootloaders. + +## Prerequisites + +Before configuring PCI passthrough, verify that the host satisfies the following requirements: +* Hardware-assisted virtualization enabled in the system firmware. +* An IOMMU implementation supported by the processor: + * Intel VT-d + * AMD-Vi + * Arm SMMUv3 +* OpenNebula host packages installed, including KVM, QEMU, and libvirt support. + +--- + +## Step 1. Verify Virtualization Support + +Before enabling PCI passthrough, verify that the processor supports hardware virtualization. + +Display the processor capabilities: + +```shell +lscpu +``` + +Look for the **Virtualization** field: + +```default +Virtualization: VT-x +``` + +or + +```default +Virtualization: AMD-V +``` + +On ARM systems, verify that virtualization extensions are available according to the platform documentation. + +## Step 2. Enable the IOMMU + +PCI passthrough requires the Input-Output Memory Management Unit (IOMMU) to isolate DMA accesses performed by assigned devices. + +### Enable the IOMMU in the Firmware + +Access your system's BIOS or UEFI setup and enable the corresponding IOMMU option. Typical firmware options include: + +* Intel VT-d +* AMD IOMMU +* Arm SMMU + +Save the changes and reboot the system. + +### Enable the IOMMU in the Kernel + +{{< tabpane text=true right=false >}} +{{% tab header="**Arch**:" disabled=true /%}} +{{% tab header="Intel"%}} +```shell +intel_iommu=on iommu=pt +``` +{{% /tab %}} +{{% tab header="AMD"%}} +```shell +amd_iommu=on iommu=pt +``` +{{% /tab %}} +{{% tab header="ARM"%}} +Most Arm platforms enable the SMMU automatically. Refer to the platform documentation if additional kernel parameters are required. + +After modifying the kernel command line, regenerate the bootloader configuration using the appropriate command for your Linux distribution and reboot the host. +{{% /tab %}} +{{< /tabpane >}} + +### Verification + +Display the kernel command line: + +```shell +cat /proc/cmdline +``` + +Verify that the IOMMU has been initialized: + +```shell +dmesg | grep -Ei "iommu|dmar|smmu" +``` + +Typical output: + +```default +DMAR: IOMMU enabled +``` + +or: + +```default +AMD-Vi: Initialized +``` + +or: + +```default +arm-smmu-v3 ... +``` + +## Step 3. Configure VFIO Device Binding + +PCI devices assigned to virtual machines must be managed by a VFIO driver instead of their native host driver. OpenNebula supports any mechanism that binds devices to VFIO. The recommended approach is to use the **driverctl** utility, which provides persistent per-device driver overrides using the Linux kernel `driver_override` interface. + +For Linux Containers, the PCI device driver shouldn’t be changed. Skip this section entirely if using passthrough in Linux Containers. + +{{< alert title="Note" type="primary" >}}This step is not needed for NVIDIA GPUs in MIG or vGPU mode. In these cases you can continue to [Step 4](#step-4-configure-huge-pages-optional).{{< /alert >}} + +### Install driverctl + +Install the driverctl package using your Linux distribution package manager. + +### Load the VFIO Modules + +Load the required kernel modules: + +```shell +modprobe vfio +modprobe vfio-pci +``` + +To load them automatically after reboot, create: + +```default +/etc/modules-load.d/vfio.conf +``` + +With contents: + +```default +vfio +vfio-pci +``` + +### Identify the PCI Device + +List the available PCI devices: + +```shell +lspci -nn +``` + +Example output: + +```default +43:00.0 3D controller: NVIDIA Corporation GH100 ... +43:00.1 Audio device: NVIDIA Corporation ... +``` + +Display the current driver: + +```shell +lspci -nnk -s 43:00.0 +``` + +Example output: + +```default +Kernel driver in use: nvidia +``` + +### Bind the Device + +Assign the device to the `vfio-pci` driver: + +```shell +driverctl set-override 0000:43:00.0 vfio-pci +``` + +Many PCI devices expose multiple functions. For example, GPUs often expose both a graphics controller and an audio controller. Repeat the command for every PCI function that will be assigned to the virtual machine. The override is persistent and is automatically restored after reboot. + +{{< alert title="Note" type="primary" >}} +Once a device is bound to a VFIO driver, it is no longer available to the host operating system until the override is removed. +{{< /alert >}} + +### Verification + +Verify that the device is managed by VFIO: + +```shell +lspci -nnk -s 43:00.0 +``` + +Expected output: + +```default +Kernel driver in use: vfio-pci +``` + +Verify that libvirt can detect the device: + +```shell +virsh nodedev-list | grep pci +``` + +List the configured driver overrides: + +```shell +driverctl list-overrides +``` + +### Removing an Override + +To restore the default host driver: + +```shell +driverctl unset-override 0000:43:00.0 +``` + +{{< alert title="Note" type="primary" >}} +Some hardware platforms require a platform-specific VFIO driver instead of `vfio-pci`. For example, NVIDIA Grace systems use the `nvgrace_gpu_vfio_pci` driver. These platform-specific procedures are described in the corresponding device guides. +{{< /alert >}} + +### VFIO Device Ownership + +For OpenNebula to manage the VFIO device files in `/dev/vfio/` must be owned by the root:kvm user and group. This is achieved by creating a `udev` rule. + +1. **Identify the IOMMU group for your GPU using its PCI address**: + + ```shell + find /sys/kernel/iommu_groups/ -type l | grep e1:00.0 + + /sys/kernel/iommu_groups/85/devices/0000:e1:00.0 + ``` + + In this example, the IOMMU group is 85 + +2. **Create a udev rule**: Create the file /etc/udev/rules.d/99-vfio.rules with the following content: + + ```default + SUBSYSTEM=="vfio", GROUP="kvm", MODE="0666" + ``` + +3. **Reload udev rules**: + + ```shell + udevadm control --reload + udevadm trigger + ``` + +4. **Verify ownership**: Check the ownership of the device file corresponding to your GPU’s IOMMU group. + + ```shell + ls -la /dev/vfio/ + crw-rw-rw- 1 root kvm 509, 0 Oct 16 10:00 85 + ``` + +## Step 4. Configure Huge Pages (Optional) + +Huge Pages reduce memory translation overhead and are recommended for memory-intensive workloads such as GPUs and high-performance networking. + +Edit the bootloader configuration and append the appropriate Huge Page parameters to the kernel command line. + +Example: + +```default +hugepages=1024 default_hugepagesz=1G hugepagesz=1G +``` + +The appropriate Huge Page size depends on the processor architecture and workload. On x86 platforms, common Huge Page sizes are 2 MB and 1 GB. + +Regenerate the bootloader configuration using the appropriate command for your Linux distribution and reboot the host. + +**Notes**: + +* Ensure sufficient free memory is available before reserving Huge Pages. +* The selected Huge Page size must be supported by both the processor and the kernel. +* Display the supported Huge Page size: + ```shell + grep Hugepagesize /proc/meminfo + ``` + +OpenNebula allows virtual machines to request Huge Pages directly from the VM Template. + +### Verification + +Display the current Huge Page configuration: + +```shell +grep Huge /proc/meminfo +``` + +## Step 5. Configure PCI Monitoring + +OpenNebula discovers PCI devices through the host monitoring subsystem. PCI monitoring is disabled by default to avoid exposing unnecessary hardware resources. + +Before PCI devices can be assigned to virtual machines, configure the monitoring subsystem to discover the devices intended for passthrough. + +### Configure System-wide PCI Monitoring + +The default monitoring configuration is stored on the Front-end: + +```default +/var/lib/one/remotes/etc/im/kvm-probes.d/pci.conf +``` + +The configuration supports three filtering mechanisms: + +* **filter** — Select devices using PCI vendor, device and class identifiers. +* **short_address** — Restrict discovery to specific PCI addresses. +* **device_name** — Select devices matching one or more regular expressions. + +The filters are applied sequentially. + +Example: + +```default +filter: + + - "10de:*" + +short_address: [] + +device_name: [] +``` + +To monitor a specific PCI device: + +```default +filter: + + - "10de:*" + +short_address: + + - "43:00.0" + +device_name: [] +``` + +To discover SR-IOV Virtual Functions: + +```default +filter: + + - "*:*" + +device_name: + + - "Virtual Function" +``` + +### Override Monitoring at Cluster or Host Level + +The system-wide configuration can be overridden for individual clusters or hosts using the corresponding template attributes: + +| Parameter | Description | +|-----------|-------------| +| PCI_FILTER | (List) Filters by PCI vendor:device:class patterns (same as for lspci) | +| PCI_SHORT_ADDRESS | (List) Filters by short PCI address bus:device.function | +| PCI_DEVICE_NAME | | + +This allows different clusters to expose different classes of PCI devices while sharing the same frontend configuration. + +{{< alert title="Recommendation" type="primary" >}} +Configure the narrowest possible filters to expose only devices intended for passthrough.{{< /alert >}} + +### Synchronize the Monitoring Probes + +After modifying `pci.conf`, synchronize the updated monitoring probes to all hosts (run as oneadmin): + +```shell +onehost sync --force +``` + +Then trigger a new monitoring cycle: + +```shell +onehost flush +``` + +Alternatively, wait for the next scheduled monitoring cycle. + +## Step 6. Verify PCI Device Discovery + +After the monitoring cycle completes, verify that OpenNebula has discovered the expected PCI devices. +Display the monitored devices: + +```shell +onehost show +``` + +Alternatively, inspect the PCI Devices tab from the Sunstone interface. + +Verify that: + +* The expected PCI devices are listed. +* Vendor and device identifiers are correct. +* Driver information is correct. +* NUMA information is reported. +* SR-IOV Virtual Functions are detected, when applicable. +* Device availability matches the host configuration. + +If a device does not appear: + +* Verify that it matches the configured monitoring filters. +* Verify that pci.conf has been synchronized to the hosts. +* Verify that the host has completed a monitoring cycle. +* Verify that the device is visible using lspci. +* Verify that the device is bound to the appropriate VFIO driver. +* Verify that the OpenNebula monitoring service is running. + +## Configuration Checklist + +Before deploying virtual machines using PCI passthrough, verify that the following requirements have been completed: +* ✔ Hardware virtualization enabled +* ✔ IOMMU enabled +* ✔ VFIO modules loaded +* ✔ PCI devices bound to VFIO +* ✔ Huge Pages configured (if required) +* ✔ SR-IOV configured (if required) +* ✔ PCI monitoring configured +* ✔ PCI devices discovered by OpenNebula + +Once these checks are complete, the host is ready to assign PCI devices to virtual machines. + +## Next Steps + +After completing the host configuration: + +* Continue with the [Network Interfaces Guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/network_interfaces/" %}}) to configure PCI passthrough or SR-IOV network devices. +* Continue with the [NVIDIA GPUs Guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough/" %}}) for NVIDIA GPU passthrough, mediated devices (vGPU), and platform-specific GPU configuration. +* Continue with the [NVIDIA Fabric Manager Guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/one_fabricmanager/" %}}) when deploying supported NVSwitch-based systems. + + diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/network_interfaces.md b/content/product/cluster_configuration/pci_passthrough_sriov/network_interfaces.md index 2b83b467e..2fecb15aa 100644 --- a/content/product/cluster_configuration/pci_passthrough_sriov/network_interfaces.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/network_interfaces.md @@ -6,4 +6,255 @@ categories: pageintoc: "58" tags: ['AI','NVIDIA'] weight: "3" ---- \ No newline at end of file +--- + +This guide describes how to use PCI network devices as OpenNebula network interfaces. + +OpenNebula extends the generic PCI passthrough mechanism by integrating PCI network devices with the Virtual Network subsystem. This allows virtual machines to benefit from the performance of direct device assignment while preserving the OpenNebula networking workflow, including IP address management, MAC address allocation, scheduling, and contextualization. + +General host preparation, including IOMMU, VFIO, Huge Pages, SR-IOV configuration, and PCI monitoring, is described in the [Host Configuration]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration" %}}) guide. + +## Overview + +OpenNebula supports assigning both Physical Functions (PFs) and Single Root I/O Virtualization (SR-IOV) Virtual Functions (VFs) as network interfaces. + +Unlike generic PCI devices, network interfaces can be fully integrated with OpenNebula Virtual Networks. During deployment, OpenNebula: + +* Selects a PCI device matching the requested constraints. +* Allocates networking resources from the selected Virtual Network. +* Assigns MAC and IP addresses. +* Configures VLAN parameters when required. +* Contextualizes the guest operating system. + +This provides the performance benefits of PCI passthrough while preserving the operational model of OpenNebula networking. + +## Physical Functions and Virtual Functions + +Modern network adapters commonly implement Single Root I/O Virtualization (SR-IOV), allowing a single Physical Function (PF) to expose multiple lightweight Virtual Functions (VFs): +* **Physical Functions**: A Physical Function represents the complete PCI device. Assigning a PF gives a virtual machine exclusive access to the network adapter and all of its capabilities. +* **Virtual Functions**: A Virtual Function is an independent PCI function created by the Physical Function. Each VF can be assigned independently to a virtual machine while sharing the underlying hardware resources. + +Virtual Functions are typically used for cloud and NFV deployments because they provide excellent performance while allowing multiple virtual machines to share the same physical adapter. + +### Legacy and Switchdev Modes + +OpenNebula supports both SR-IOV operating modes. + +* **Legacy Mode**: In Legacy mode, OpenNebula programs the Virtual Function directly. The following attributes are supported: + * MAC + * VLAN_ID + * TRUST + * SPOOFCHK +
+ + These attributes are applied directly by the network adapter. + +* **Switchdev Mode**: In Switchdev mode, VF parameters are controlled by host-side representor interfaces. These representor interfaces can be attached to a virtual switch to establish port-level control. + + In this mode, only the MAC address is applied directly to the VF interface. All other control parameters are managed by the virtual switch driver associated with the Virtual Network. + + OpenNebula automatically configures the representor interface during deployment. As of now, only Open vSwitch is supported for Switchdev mode. + +## Host Configuration + +If the PCI device supports Single Root I/O Virtualization (SR-IOV), Virtual Functions (VFs) can be created and assigned independently to virtual machines. Determine the maximum number of supported Virtual Functions: + +```shell +cat /sys/bus/pci/devices//sriov_totalvfs +``` + +Enable the desired number of Virtual Functions: + +```shell +echo 8 > /sys/bus/pci/devices//sriov_numvfs +``` + +{{< alert title="Note" type="primary" >}} +The configured number of Virtual Functions is typically reset after reboot. Refer to your Linux distribution or hardware vendor documentation to configure persistent SR-IOV devices.{{< /alert >}} + +### Verification + +Verify that the Virtual Functions have been created: + +```shell +lspci +``` + +or + +```shell +ip link +``` + +depending on the device type. + +Additional SR-IOV configuration for network adapters is described in the **Network Interfaces** guide. + +## Host Configuration for DPDK Interfaces + +## Using PCI Devices as Network Interfaces + +To use a PCI device as a network interface, set the `TYPE` attribute of the `PCI` element to `NIC`. Example: + +```default +PCI = [ + TYPE = "NIC", + NETWORK = "SRIOV-NET" +] +``` + +Unlike generic PCI passthrough, a PCI device configured as a network interface becomes part of the OpenNebula networking subsystem. + +During deployment, OpenNebula: + +1. Selects a compatible PCI device. +2. Allocates networking resources from the specified Virtual Network. +3. Configures the PCI device. +4. Generates the corresponding NIC context information. +5. Contextualizes the guest operating system. + +As a result, the guest receives a fully configured network interface without additional manual configuration. + +## Selecting PCI Devices + +PCI devices may be selected explicitly or automatically. + +### Automatic Selection + +Automatic selection is the recommended approach. Instead of specifying a PCI address, define the required device characteristics. + +Example: + +``` +PCI = [ + TYPE = "NIC", + NETWORK = "SRIOV-NET", + + CLASS = "0200", + VENDOR = "15b3" +] +``` + +The scheduler automatically selects an available PCI device satisfying the specified constraints. Automatic selection improves workload portability across hosts. + +### Explicit Device Selection + +Specific devices may also be selected using their PCI address. + +Example: + +``` +PCI = [ + TYPE = "NIC", + DEVICE = "0000:81:00.4" +] +``` + +Explicit selection should generally be reserved for specialized deployments where the VM needs to be attached to specific networks. + +## Virtual Network Integration + +Unlike generic PCI passthrough, PCI network interfaces participate fully in OpenNebula Virtual Networks. The selected Virtual Network provides: + +* MAC address allocation +* IPv4 allocation +* IPv6 allocation +* VLAN configuration +* Security Groups +* Address management + +This allows PCI passthrough interfaces to behave consistently with virtual network interfaces from the administrator's perspective. + +## Contextualization + +When the Context package is installed inside the guest operating system, OpenNebula automatically configures the assigned PCI interface. The guest receives: + +* MAC address +* IPv4 address +* IPv6 address +* Network mask +* Gateway +* DNS configuration +* Hostname + +No manual network configuration is required inside the guest. + +## Supported PCI Attributes + +PCI network interfaces support the standard PCI attributes together with networking-specific attributes. + +Common PCI attributes include: + +* `DEVICE` +* `CLASS` +* `VENDOR` +* `TYPE` + +Network-specific attributes include: + +* `NETWORK` +* `NETWORK_UNAME` +* `MAC` +* `IP` +* `IP6` +* `VLAN_ID` +* `TRUST` +* `SPOOFCHK` + +Refer to the Virtual Machine Template reference for a complete description of each attribute. + +## Supported PCI Attributes + +PCI network interfaces support the standard PCI attributes together with networking-specific attributes. + +Common PCI attributes include: + +* `DEVICE` +* `CLASS` +* `VENDOR` +* `TYPE` + +Network-specific attributes include: + +* `NETWORK` +* `NETWORK_UNAME` +* `MAC` +* `IP` +* `IP6` +* `VLAN_ID` +* `TRUST` +* `SPOOFCHK` + +Refer to the Virtual Machine Template reference for a complete description of each attribute. + +## Guest Verification + +After deployment, verify that the guest detects the assigned network adapter. + +Display the PCI devices: + +```shell +lspci +``` + +Display the network interfaces: + +```shell +ip link +``` + +The interface should appear as a native PCI network adapter and be configured automatically through contextualization. + +## Best Practices + +* Prefer automatic PCI device selection whenever possible. +* Use Virtual Functions instead of Physical Functions for cloud deployments. +* Reserve Physical Functions for workloads requiring exclusive device ownership. +* Configure PCI monitoring to expose only passthrough devices. +* Install the OpenNebula Context package in guest operating systems. +* Use NUMA-aware placement for latency-sensitive workloads. +* Prefer Switchdev mode when integrating with Open vSwitch. + +## Next Steps + +If you have not yet configured the host for PCI passthrough, complete the **Host Configuration** guide. For NVIDIA GPUs, continue with the **NVIDIA GPU** guide. \ No newline at end of file diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough.md b/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough.md index 47c405150..6cbe2fcec 100644 --- a/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough.md @@ -1,278 +1,545 @@ --- title: "NVIDIA GPU Passthrough" +linkTitle: "NVIDIA GPU (vGPU, MIG, Passthrough)" date: "2025-10-16" description: categories: pageintoc: "58" tags: ['AI','NVIDIA'] -weight: "7" +weight: "5" --- - +## Overview - +This guide describes how to deploy NVIDIA GPUs using PCI passthrough technologies in OpenNebula. OpenNebula supports multiple NVIDIA GPU deployment models, including conventional PCI passthrough, NVIDIA vGPU, MIG-backed vGPU, and NVIDIA Grace platform virtualization. While these deployment models share the same scheduling and deployment workflow, each requires a different host configuration. -Here you will find detailed instructions for configuring PCI passthrough for high-performance NVIDIA® GPUs on x86_64 hypervisors. The procedures described here have been validated with NVIDIA H100 GPUs but can be adapted for other similar high-performance NVIDIA GPUs. This allows Virtual Machines to get exclusive access to the GPU, which is recommended for AI/ML workloads. It builds upon the concepts explained in the general [PCI Passthrough]({{% relref "pci_passthrough.md" %}}) guide. This guide is not applicable to ARM-based systems. +The generic PCI passthrough configuration, including IOMMU, VFIO, Huge Pages, PCI monitoring, and device discovery, is described in the [**Host Configuration**]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}) guide. This guide focuses exclusively on the NVIDIA-specific configuration and deployment procedures for each supported deployment model. -{{< alert title="Note" type="info" >}} -As an alternative to PCI passthrough, OpenNebula also supports NVIDIA vGPU, which allows a single physical GPU to be partitioned and shared among multiple VMs. While PCI passthrough is the recommended approach for demanding AI/ML workloads, especially model training, vGPU can be a suitable option for less intensive tasks like model inference or development environments. For more information, see the [NVIDIA vGPU guide]({{% relref "vgpu.md" %}}). -{{< /alert >}} +## Deployment Models -## Hypervisor Configuration +NVIDIA GPUs can be deployed in OpenNebula using one of the following deployment models. -The following configurations must be performed on the KVM hypervisors that will host the GPUs. +| Deployment Model | Typical Platforms | VFIO Driver | Additional Configuration | +| ----- | ----- | ----- | ----- | +| Conventional PCI Passthrough | H100 PCIe, H100 SXM, H200, L40, L40S, RTX, A100 | `vfio-pci` | Standard PCI passthrough | +| NVIDIA vGPU / MIG-backed vGPU | A100, H100, H200, B200 | NVIDIA vGPU stack | NVIDIA vGPU or MIG-backed vGPU configuration | +| Grace Platform Virtualization | GH200, GB200 | `nvgrace_gpu_vfio_pci` | Grace-specific virtualization configuration | -### Enabling IOMMU +For **conventional PCI passthrough**, the NVIDIA driver is **not required** on the host. The GPU is owned exclusively by the guest operating system, where the NVIDIA driver is installed after deployment. -The IOMMU (Input-Output Memory Management Unit) is a hardware feature that allows the hypervisor to isolate I/O devices and is a prerequisite for PCI passthrough. To enable it, you need to add kernel parameters to the hypervisor's boot configuration. +For **NVIDIA vGPU** and **MIG-backed vGPU**, the NVIDIA driver is required on the host because the host manages GPU partitioning and virtual GPU creation before assigning GPU resources to virtual machines. -1. Edit the GRUB configuration file at `/etc/default/grub` and add the appropriate parameter to the `GRUB_CMDLINE_LINUX_DEFAULT` line: +--- -* **For Intel CPUs**: `intel_iommu=on iommu=pt` -* **For AMD CPUs**: `amd_iommu=on iommu=pt` +## Conventional PCI Passthrough -Example for an Intel-based hypervisor: +## Overview -```default -GRUB_CMDLINE_LINUX_DEFAULT="intel_iommu=on iommu=pt" +Conventional PCI passthrough assigns one or more physical NVIDIA GPUs directly to a virtual machine, providing the guest operating system with exclusive access to the assigned devices. In this deployment model, the host does not use the GPUs, which are instead bound to the `vfio-pci` driver and managed entirely by the guest operating system. + +This deployment model is recommended for workloads requiring direct access to the GPU, such as AI training and inference, high-performance computing (HPC), scientific computing, visualization, and CUDA development. It is supported by NVIDIA PCIe and SXM GPUs, including NVIDIA H100, H200, L40, L40S, RTX, and A100 GPUs when Multi-Instance GPU (MIG) is not enabled. + +## Requirements + +Before deploying NVIDIA GPUs using conventional PCI passthrough, complete the generic PCI passthrough configuration described in the **Host Configuration** guide. + +Verify that the host satisfies the following requirements: + +* Hardware-assisted virtualization and the IOMMU are enabled. +* The GPU is bound to the `vfio-pci` driver. +* PCI monitoring is configured to discover NVIDIA GPUs. +* The GPUs have been discovered by OpenNebula. + +Verify that the GPU is managed by the `vfio-pci` driver: + +```shell +lspci -nnk -d 10de: ``` -2. After saving the file, update the GRUB configuration and reboot the hypervisor: +Example output: -```default -# update-grub -# reboot +``` +81:00.0 3D controller: NVIDIA Corporation H100 PCIe + Kernel driver in use: vfio-pci + +81:00.1 Audio device: NVIDIA Corporation Device xxxx + Kernel driver in use: vfio-pci ``` -3. After rebooting, verify that IOMMU is enabled by checking the kernel messages: +Verify that the GPUs have been discovered by OpenNebula: -```default -# dmesg | grep -i iommu +```shell +onehost show ``` -Alternatively, to confirm that IOMMU is active proceed to check that the `/sys/kernel/iommu_groups/` directory exists and is populated with subdirectories. An empty directory might indicate that IOMMU is not correctly enabled in the kernel or BIOS. +The GPUs should appear in the **PCI Devices** section and be available for scheduling. -### VFIO Driver Binding +{{< alert title="Note" type="primary" >}} +Unlike NVIDIA vGPU or MIG-backed vGPU deployments, the NVIDIA driver is not required on the host for conventional PCI passthrough. The GPU is owned exclusively by the guest operating system, where the NVIDIA driver is installed after deployment.{{< /alert >}} -Once IOMMU is enabled, the GPU must be unbound from the default host driver (e.g., `nouveau`) and bound to the `vfio-pci` driver, which is designed for PCI passthrough. +--- -1. Install `driverctl` utility: +## Host Configuration - ```default - # apt install driverctl - ``` +This section describes the NVIDIA-specific configuration required after completing the generic PCI passthrough configuration. If the NVIDIA driver is installed on the host, prevent it from binding to GPUs intended for passthrough by blacklisting the NVIDIA kernel modules. -2. Ensure `vfio-pci` module is loaded on boot: +Create the following configuration file: - ```default - # echo "vfio-pci" | sudo tee /etc/modules-load.d/vfio-pci.conf - # modprobe vfio-pci - ``` +```default +/etc/modprobe.d/blacklist-nvidia.conf +``` -3. Identify the GPU's PCI address: +Example contents: - ```default - # lspci -D | grep -i nvidia - 0000:e1:00.0 3D controller: NVIDIA Corporation GH100 [H100 PCIe] (rev a1) - ``` +```default +blacklist nouveau +blacklist nvidia +blacklist nvidia_drm +blacklist nvidia_modeset +blacklist nvidia_uvm +``` + +Regenerate the initramfs using the appropriate command for your Linux distribution and reboot the host. -4. Set the driver override: - Use the PCI address from the previous step to set an override for the device to use the `vfio-pci` driver. +{{< alert title="Note" type="primary" >}} +This step is only required if the NVIDIA driver is installed on the host. Hosts dedicated to GPU PCI passthrough typically do not require the NVIDIA driver.{{< /alert >}} - ```default - # driverctl set-override 0000:e1:00.0 vfio-pci - ``` +### Verify the GPU Driver -5. Verify the driver binding: - Check that the GPU is now using the `vfio-pci` driver. +After completing the generic PCI passthrough configuration, verify that all GPU PCI functions are managed by the `vfio-pci` driver. - ```default - # lspci -Dnns e1:00.0 -k - Kernel driver in use: vfio-pci - ``` +```shell +lspci -nnk -d 10de: +``` -### VFIO Device Ownership +Example output: + +``` +81:00.0 3D controller: NVIDIA Corporation H100 PCIe + Kernel driver in use: vfio-pci -For OpenNebula to manage the GPU, the VFIO device files in `/dev/vfio/` must be owned by the `root:kvm` user and group. This is achieved by creating a `udev` rule. +81:00.1 Audio device: NVIDIA Corporation Device xxxx + Kernel driver in use: vfio-pci +``` -1. Identify the IOMMU group for your GPU using its PCI address: +If any GPU function is still managed by the NVIDIA or Nouveau driver, review the VFIO configuration described in the **Host Configuration** guide. - ```default - # find /sys/kernel/iommu_groups/ -type l | grep e1:00.0 - /sys/kernel/iommu_groups/85/devices/0000:e1:00.0 - ``` - In this example, the IOMMU group is `85`. +{{< alert title="Note" type="primary" >}} +NVIDIA GPUs may expose multiple PCI functions, such as audio or USB controllers. All functions belonging to the GPU should be assigned together to the same virtual machine.{{< /alert >}} -2. Create a `udev` rule: - Create the file `/etc/udev/rules.d/99-vfio.rules` with the following content: +### Verify GPU Discovery - ```default - SUBSYSTEM=="vfio", GROUP="kvm", MODE="0666" - ``` +After the next monitoring cycle, verify that OpenNebula has discovered the GPUs. -3. Reload `udev` rules: +```shell +onehost show +``` - ```default - # udevadm control --reload - # udevadm trigger - ``` +Example output: -4. Verify ownership: - Check the ownership of the device file corresponding to your GPU's IOMMU group. +``` +PCI DEVICES - ```default - # ls -la /dev/vfio/ - crw-rw-rw- 1 root kvm 509, 0 Oct 16 10:00 85 - ``` + VM ADDR TYPE NAME + e1:00.0 10de:2321:0302 NVIDIA Corporation GH100 [H100L 94GB] +``` -## OpenNebula Configuration +The GPUs should appear in the **PCI Devices** section and be available for scheduling. -### Monitoring PCI Devices +Alternatively, the detected PCI devices can be inspected from the **PCI Devices** tab in Sunstone. -To make the GPUs available in OpenNebula, configure the PCI probe on the front-end node to monitor NVIDIA devices. +--- -1. Edit the PCI probe configuration file at `/var/lib/one/remotes/etc/im/kvm-probes.d/pci.conf`. -2. Add a filter for NVIDIA devices: +## Deploying a Virtual Machine - ```default - :filter: '10de:*' - ``` +After the host has been configured and the GPUs have been discovered by OpenNebula, they can be assigned to virtual machines using the standard `PCI` attribute in the Virtual Machine Template. -3. Synchronize the hosts from the Front-end to apply the new configuration: +OpenNebula supports both automatic and explicit GPU selection. Automatic selection is recommended because it allows the scheduler to place workloads on any compatible host, improving workload portability and resource utilization. - ```default - # su - oneadmin - $ onehost sync -f - ``` +### Automatic GPU Selection -After a few moments, you can check if the GPU is being monitored correctly by showing the host information (`onehost show `). The GPU should appear in the `PCI DEVICES` section. +The following example requests any available NVIDIA GPU: -By default, the host system monitoring probe may take up to **10 minutes** to detect new PCI devices. To run the host monitoring probe immediately, you can force it with: -```default -$ onehost forceupdate +``` +PCI = [ + CLASS = "0302", + VENDOR = "10de" +] ``` -## VM Template Best Practices for AI Workloads +During deployment, OpenNebula selects a compatible GPU that matches the requested attributes and assigns it to the virtual machine. -To achieve proper GPU operation inside the VM, including optimal performance for AI/ML workloads, configure the VM Template with the following settings: +Additional `PCI` attributes, such as `DEVICE` or `SHORT_ADDRESS`, can be used to further restrict device selection when required. -### Firmware (UEFI) +### Selecting a Specific GPU -Modern high-performance GPUs like the H100 benefit from Resizable BAR, which requires UEFI booting. OpenNebula will automatically select the appropriate UEFI firmware file. If you need to use a specific OVMF file, you can provide its full path in the `FIRMWARE` attribute instead of `\"UEFI\"`. +For topology-sensitive deployments, benchmarking, or debugging, a specific GPU can be requested using its PCI address. -* **Attribute**: `FIRMWARE` -* **Section**: `OS` -* **Value**: `"UEFI"` +For example: -```default -OS = [ - ARCH = "x86_64", - FIRMWARE = "UEFI" +``` +PCI = [ + SHORT_ADDRESS = "81:00.0" ] ``` -### Machine Type (q35) +Explicit device selection should be reserved for specialized deployments. In most environments, automatic GPU selection provides greater flexibility and simplifies workload scheduling. -The `q35` machine type provides a modern PCIe-based chipset, improving compatibility and performance for PCIe devices like GPUs. Additionally, if the q35 machine type is used, OpenNebula replicates the hypervisor PCI topology into the guest VM. This gives AI frameworks visibility into the PCI layout, allowing them to optimize data transfers and reduce latency. +### Assigning Multiple GPUs -* **Attribute**: `MACHINE` -* **Section**: `OS` -* **Value**: `"q35"` +Multiple GPUs can be assigned to the same virtual machine by including multiple `PCI` sections. -```default -OS = [ - ..., - MACHINE = "q35" +The following example requests two NVIDIA GPUs: + +``` +PCI = [ + CLASS = "0302", + VENDOR = "10de" +] + +PCI = [ + CLASS = "0302", + VENDOR = "10de" ] ``` -### CPU Model (Host Passthrough) +Each `PCI` section requests one compatible GPU. During deployment, OpenNebula assigns the requested number of devices to the virtual machine. + +--- -Exposing the host CPU exact model and feature set to the VM results in better hardware support and performance. Having the full list of CPU features is a hard requirement for modern high-performance GPUs like the NVIDIA H100, because its drivers require access to advanced CPU instruction sets to initialize and function correctly. +## Example H100 Virtual Machine Template -* **Attribute**: `CPU_MODEL` -* **Value**: `MODEL="host-passthrough"` +The following example shows a Virtual Machine Template for an NVIDIA H100 SXM system with eight GPUs assigned through PCI passthrough. ```default +CONTEXT = [ + NETWORK = "YES", + SSH_PUBLIC_KEY = "$USER[SSH_PUBLIC_KEY]" +] + +CPU = "208" +VCPU = "208" +MEMORY = "716800" + CPU_MODEL = [ - MODEL = "host-passthrough" + MODEL = "host-passthrough" ] -``` -### NUMA and CPU Pinning +TOPOLOGY = [ + CORES = "52", + SOCKETS = "2", + THREADS = "2", + PIN_POLICY = "THREAD" +] -CPU pinning is crucial for performance as it dedicates physical CPU cores to the VM, preventing them from being shared with other VMs. When a `PIN_POLICY` is defined, the OpenNebula scheduler automatically places the VM on a NUMA node that is physically close to the requested GPU and pins the vCPUs to the cores of that node, minimizing latency. For a more in-depth explanation of this topic, refer to the [Virtual Topology and CPU Pinning]({{% relref "numa.md" %}}) guide. +OS = [ + ARCH = "x86_64", + FIRMWARE = "/usr/share/OVMF/OVMF_CODE_4M.fd", + FIRMWARE_SECURE = "NO", + MACHINE = "pc-q35-jammy" +] + +DISK = [ + IMAGE = "ubuntu-24.04-gpu", + SIZE = "1572864" +] -For VM pinning to work, you must also enable the pinning policy on the Host. You can do this by editing the Host's template and setting `PIN_POLICY="PINNED"`, or by selecting the `PINNED` policy in the Host's `NUMA` tab in Sunstone. +NIC = [ + NETWORK = "admin_net" +] -* **Attribute**: `TOPOLOGY` -* **Values**: `PIN_POLICY`, `CORES`, `SOCKETS` +GRAPHICS = [ + LISTEN = "0.0.0.0", + TYPE = "vnc" +] -```default -TOPOLOGY = [ - PIN_POLICY = "CORE", - CORES = "16", - SOCKETS = "1" +FEATURES = [ + PCIHOLE64 = "2147483648" ] + +PCI = [ SHORT_ADDRESS = "1b:00.0" ] +PCI = [ SHORT_ADDRESS = "43:00.0" ] +PCI = [ SHORT_ADDRESS = "52:00.0" ] +PCI = [ SHORT_ADDRESS = "61:00.0" ] +PCI = [ SHORT_ADDRESS = "9d:00.0" ] +PCI = [ SHORT_ADDRESS = "c3:00.0" ] +PCI = [ SHORT_ADDRESS = "d1:00.0" ] +PCI = [ SHORT_ADDRESS = "df:00.0" ] ``` -### PCI Device Passthrough +The `PCI` entries assign the eight H100 GPUs to the virtual machine. -Finally, assign the GPU to the VM using the `PCI` attribute. You can select a specific GPU by its address. Once the VM is running, verify that the guest OS recognizes the device by executing the `lspci` command inside the VM. +--- -* **Attribute**: `PCI` -* **Value**: `SHORT_ADDRESS=""` +## Guest Configuration -```default -PCI = [ - SHORT_ADDRESS = "e1:00.0" -] +After the virtual machine has been deployed, verify that the GPUs are visible inside the guest: + +```shell +lspci | grep -i nvidia +``` + +Example output: + +``` +23:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] +24:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] +25:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] +26:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] +43:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] +44:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] +45:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] +46:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] +``` + +Install the appropriate NVIDIA driver inside the guest operating system. The selected driver version must support the assigned GPU model and be compatible with the required CUDA software stack. + +After installing the driver, verify that all assigned GPUs are detected: + +```shell +nvidia-smi +``` + +Use the output provided in the NVIDIA qualification guide for your platform to verify that all assigned GPUs are present and that no driver or hardware errors are reported. Avoid using placeholder outputs, as driver versions and formatting vary across NVIDIA software releases. + +## NVIDIA vGPU and MIG-backed vGPU + +### Overview + +NVIDIA vGPU enables multiple virtual machines to share the resources of a physical GPU by exposing one or more virtual GPU (vGPU) profiles that can be independently assigned to guest operating systems. + +Depending on the GPU generation, vGPU profiles can be created using one of two deployment models: + +* **NVIDIA vGPU**, where virtual GPU profiles are created directly by the NVIDIA AI Enterprise software stack. +* **MIG-backed vGPU**, where the GPU is first partitioned using NVIDIA Multi-Instance GPU (MIG), and one or more vGPU profiles are created from the resulting GPU Instances. + +Regardless of how the profiles are created, OpenNebula automatically discovers the available vGPU profiles during host monitoring and schedules them as GPU resources that can be assigned to virtual machines. + +Before deploying NVIDIA vGPU devices, complete the generic PCI passthrough configuration described in the **Host Configuration** guide. + +--- + +## Requirements + +Before continuing, verify that the host satisfies the following requirements: + +* A supported NVIDIA GPU is installed. +* The NVIDIA host driver is installed and operational. +* PCI monitoring is configured. +* The GPU has been discovered by OpenNebula. + +Verify that the NVIDIA driver is correctly installed: + +```shell +nvidia-smi +``` + +Verify that the GPU has been discovered by OpenNebula: + +```shell +onehost show +``` + +The GPU should appear in the **PCI Devices** section. + +--- + +### Host Configuration + +Depending on the GPU model, configure either **NVIDIA vGPU** or **MIG-backed vGPU**. + +#### Configure NVIDIA vGPU + +Conventional NVIDIA vGPU is supported on GPUs that expose vGPU profiles directly through the NVIDIA AI Enterprise software stack. + +Install the NVIDIA AI Enterprise software stack and the NVIDIA vGPU Manager according to the NVIDIA documentation. + +After installation, verify that the NVIDIA driver is operational: + +```shell +nvidia-smi +``` + +Display the supported vGPU profiles: + +```shell +nvidia-smi vgpu -s -v +``` + +The command lists all vGPU profiles supported by the GPU. + +After the next monitoring cycle, OpenNebula automatically discovers the available vGPU profiles. + +## Configure MIG-backed vGPU + +Hopper and newer GPUs support creating vGPU profiles from GPU partitions created using NVIDIA Multi-Instance GPU (MIG). + +### Enable MIG Mode + +Display the current MIG configuration: + +```shell +nvidia-smi -i 0 -q | grep MIG -A2 ``` -## Sample VM Template +Enable MIG mode: + +```shell +sudo nvidia-smi -i 0 -mig 1 +``` -Here is a sample VM Template that incorporates all the recommended attributes for an AI workload VM with an NVIDIA H100 GPU. This template is a reference. To meet your specific requirements, specify `MEMORY`, `VCPU`, `IMAGE_ID`, and other parameters. +Verify that MIG mode has been enabled: + +```shell +nvidia-smi -i 0 -q | grep MIG -A2 +``` + +Example output: ```default -CONTEXT=[ - NETWORK="YES", - SSH_PUBLIC_KEY="$USER[SSH_PUBLIC_KEY]" ] +MIG Mode + Current : Enabled + Pending : Enabled +``` + +Some GPU models require a reboot before MIG mode becomes active. + +--- + +### Display Available GPU Instance Profiles + +Display the supported GPU Instance profiles: + +```shell +nvidia-smi mig -lgip +``` + +Example output: + +```shell ++-----------------------------------------------------------------------------+ +| GPU instance profiles: | +| GPU Name ID Instances Memory SM DEC ENC OFA | +| Profile Free/Total GiB CE | +|=============================================================================| +| 0 MIG 1g.10gb 19 7/7 9.62 16 0 0 0 | +| 0 MIG 2g.20gb 14 3/3 19.50 32 1 0 0 | +| 0 MIG 3g.40gb 9 2/2 39.25 60 2 0 0 | ++-----------------------------------------------------------------------------+ +``` + +Display the supported GPU Instance placements: + +```shell +nvidia-smi mig -lgipp +``` -CPU="1" +### Create GPU and Compute Instances -CPU_MODEL=[ - MODEL="host-passthrough" ] +Create the desired GPU Instances. -DISK=[ - IMAGE_ID="163" ] +For example, the following command creates four **1g.10gb** GPU Instances together with their default Compute Instances: -GRAPHICS=[ - LISTEN="0.0.0.0", - TYPE="vnc" ] +```shell +sudo nvidia-smi mig -cgi 19,19,19,19 -C +``` + +Verify the resulting MIG devices: + +```shell +nvidia-smi -L +``` + +Example output: + +``` +GPU 0: NVIDIA H100 PCIe + + MIG 1g.10gb Device 0: (UUID: MIG-xxxxxxxx) + MIG 1g.10gb Device 1: (UUID: MIG-xxxxxxxx) + MIG 1g.10gb Device 2: (UUID: MIG-xxxxxxxx) + MIG 1g.10gb Device 3: (UUID: MIG-xxxxxxxx) +``` + +### Configure vGPU Profiles + +After creating the GPU and Compute Instances, configure the required NVIDIA vGPU profiles according to the NVIDIA AI Enterprise documentation. + +Verify the available profiles: + +```shell +nvidia-smi vgpu -s -v +``` + +### Refresh OpenNebula Monitoring + +Once the GPU configuration has been completed, refresh host monitoring: + +```shell +onehost forceupdate +``` + +Verify that the configured vGPU profiles have been discovered: + +```shell +onehost show +``` + +The configured profiles should appear in the **PCI Devices** section and be available for scheduling. -HYPERVISOR="kvm" +--- + +### Deploying a Virtual Machine + +Virtual machines request NVIDIA vGPU resources by selecting one of the vGPU profiles discovered during host monitoring. + +The available profiles can be inspected from the **PCI Devices** tab in Sunstone or using: + +```shell +onehost show +``` + +Each discovered profile reports the profile name together with the number of available instances. + +--- + +**Example Virtual Machine Template** + +Virtual machines request NVIDIA vGPU resources using the `PCI` attribute. The `PROFILE` attribute must match one of the profiles discovered during host monitoring. -LOGO="images/logos/ubuntu.png" +The following example requests an NVIDIA L40S-2B vGPU profile: -LXD_SECURITY_PRIVILEGED="true" +``` +PCI = [ + CLASS = "0302", + DEVICE = "26b9", + PROFILE = "1146 (NVIDIA L40S-2B)", + VENDOR = "10de" +] +``` + +When the virtual machine is deployed, OpenNebula allocates a compatible GPU exposing the requested profile. -MEMORY="768" +For MIG-backed vGPU deployments, the deployment workflow is identical. The available profiles are generated from the configured GPU Instances and automatically discovered during host monitoring. -OS=[ - ARCH="x86_64", - FIRMWARE="UEFI", - MACHINE="q35" ] +--- -PCI=[ - SHORT_ADDRESS="e1:00.0" ] +### Guest Configuration + +After the virtual machine has been deployed, install the NVIDIA guest driver corresponding to the selected NVIDIA vGPU software release. + +Refer to the NVIDIA AI Enterprise documentation or your Linux distribution for instructions on installing the appropriate guest driver. + +After the installation completes, verify that the assigned virtual GPU is detected: + +```shell +nvidia-smi +``` -SCHED_REQUIREMENTS="HYPERVISOR=kvm" +Use the output provided by the NVIDIA vGPU software stack for your selected profile to verify that: -TOPOLOGY=[ - CORES="4", - PIN_POLICY="CORE", - SOCKETS="1", - THREADS="1" ] +* the assigned virtual GPU is detected correctly; +* the reported GPU name matches the selected vGPU profile; +* no driver or hardware errors are reported. -VCPU="4" -``` \ No newline at end of file +The guest configuration is identical for conventional NVIDIA vGPU and MIG-backed vGPU deployments. Once deployed, the guest operating system interacts with the assigned virtual GPU transparently, regardless of how the profile was created. \ No newline at end of file diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_grace_platform.md b/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_grace_platform.md new file mode 100644 index 000000000..6b1ee5afc --- /dev/null +++ b/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_grace_platform.md @@ -0,0 +1,267 @@ +--- +title: "NVIDIA Grace Platform Virtualization (AE)" +linkTitle: "NVIDIA Grace Platforms (AE)" +date: "2026-07-09" +description: +categories: +pageintoc: "58" +tags: ['AI','NVIDIA'] +weight: "9" +--- + +## Overview + +NVIDIA Grace Hopper and Grace Blackwell platforms implement a virtualization architecture that differs from conventional PCI passthrough systems. In addition to assigning GPUs to virtual machines, Grace platforms require a specific PCI topology based on dedicated PCI Root Complexes, SMMUv3 devices, IOMMUFD, and ACPI Generic Initiator NUMA nodes. + +OpenNebula automates the creation of this virtual hardware topology during deployment. From the administrator's perspective, GPU assignment uses the standard `PCI` attribute while OpenNebula generates the libvirt configuration required by the Grace virtualization architecture. + +Before deploying GPUs on Grace platforms, complete the generic PCI passthrough configuration described in the **Host Configuration** guide. + +--- + +### Requirements + +Before configuring Grace platform virtualization, ensure that the host has already been configured following the **Host Configuration** guide. + +In addition, verify that the host satisfies the following Grace-specific requirements: + +* A Linux kernel supporting NVIDIA Grace virtualization. +* NVIDIA QEMU and libvirt packages with Grace virtualization support. +* QEMU configured with `CAP_IPC_LOCK`. +* GPUs bound to the `nvgrace_gpu_vfio_pci` driver. + +The installation and configuration of the virtualization software stack is outside the scope of this guide. Refer to the NVIDIA Grace Virtualization documentation for platform-specific installation instructions. + +### Host Configuration + +Only the Grace-specific configuration required after completing the generic host configuration is described in this section. + +### Configure QEMU Memory Locking + +Grace platforms require QEMU to lock large GPU memory mappings. + +Grant the `CAP_IPC_LOCK` capability to the QEMU binary: + +```shell +sudo setcap cap_ipc_lock=ep /usr/bin/qemu-system-aarch64 +``` + +Verify the capability: + +```shell +getcap /usr/bin/qemu-system-aarch64 +``` + +The capability must be restored whenever the QEMU binary is replaced during a package upgrade. + +### Bind GPUs to the Grace VFIO Driver + +Load the Grace VFIO driver: + +```shell +sudo modprobe nvgrace-gpu-vfio-pci +``` + +Register the NVIDIA GB200 device ID with the driver: + +```shell +echo "10de 2941" | sudo tee /sys/bus/pci/drivers/nvgrace_gpu_vfio_pci/new_id +``` + +Verify that the GPUs are bound to the `nvgrace_gpu_vfio_pci` driver: + +```shell +lspci -nnkk | grep -i 3D -A2 +``` + +Example output: + +```default +0008:01:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2941] (rev a1) + Subsystem: NVIDIA Corporation Device [10de:2046] + Kernel driver in use: nvgrace_gpu_vfio_pci +-- +0009:01:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2941] (rev a1) + Subsystem: NVIDIA Corporation Device [10de:2046] + Kernel driver in use: nvgrace_gpu_vfio_pci +-- +0018:01:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2941] (rev a1) + Subsystem: NVIDIA Corporation Device [10de:2046] + Kernel driver in use: nvgrace_gpu_vfio_pci +-- +0019:01:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2046] + Kernel driver in use: nvgrace_gpu_vfio_pci +``` +### Deploying a Virtual Machine + +Grace platform virtual machines are deployed using the standard OpenNebula `PCI` attribute together with the CPU and NUMA configuration required by the workload. + +The following example shows the relevant sections of a Virtual Machine Template configured with two Grace CPU NUMA nodes and four NVIDIA GB200 GPUs. + +``` +TOPOLOGY = [ + SOCKETS = "2", + CORES = "72", + THREADS = "1", + PIN_POLICY = "THREAD", + MEMORY_ACCESS = "shared", + HUGEPAGE_SIZE = "512" +] + +NUMA_NODE = [ + MEMORY = "192000", + TOTAL_CPUS = "72", + DISTANCE = "2-17:254" +] + +NUMA_NODE = [ + MEMORY = "192000", + TOTAL_CPUS = "72", + DISTANCE = "2-17:254" +] + +PCI=[ + ACPI_NODES="2-9", + CLASS="0302", + DEVICE="2941", + IOMMU="YES", + IOMMUFD="YES", + ROOT="dedicated", + VENDOR="10de" +] + +PCI=[ + ACPI_NODES="10-17", + CLASS="0302", + ... + + +FEATURES=[ + ACPI="yes", + APIC="yes", + GIC="3", + PCIHOLE64="4294967296", + RAS="yes" +] + +IOMMU=[ + MODE="device", + MODEL="smmuv3", + OPTIONS="accel=on ats=on ril=off pasid=on oas=48" +] +``` + +The `PCI` attributes request two NVIDIA GB200 GPUs using dedicated PCI Root Complexes and dedicated IOMMU contexts. + +During deployment, OpenNebula automatically generates the Grace virtualization topology required by the guest, including: + +* PCI Root Complexes and PCI Root Ports. +* Virtual SMMUv3 devices. +* IOMMUFD objects. +* ACPI Generic Initiator NUMA nodes. +* Guest NUMA topology. +* NUMA distance matrices. + +This topology follows the NVIDIA Grace virtualization architecture and preserves CPU and GPU NUMA locality. + +{{< alert title="Note" type="primary" >}} +When using automatic GPU selection, OpenNebula computes the required `ACPI_NODES` assignment automatically. Explicit `ACPI_NODES` values are only required when selecting specific devices and defining a fixed virtual topology.{{< /alert >}} + +### Guest Configuration + +Install the NVIDIA data center driver inside the guest operating system following the NVIDIA documentation. + +After installation, the GPUs are exposed as native Grace devices and CUDA applications require no additional configuration. + +A correctly configured guest exposes: + +* The configured CPU NUMA nodes. +* Eight ACPI Generic Initiator NUMA nodes for each assigned GPU. +* Preserved NVLink connectivity. +* GPU affinity matching the physical Grace topology. + +The NUMA topology can be inspected using: + +```shell +numactl -H +``` + +Example output: + +``` +available: 32 nodes (0-4,6-7,9-33) + +node 0 cpus: 0-71 +node 0 size: 191674 MB + +node 1 cpus: 72-143 +node 1 size: 191741 MB + +... + +node distances: +node 0 1 2 3 4 ... +0: 10 20 254 254 254 ... +1: 20 10 254 254 254 ... +2: 254 254 10 20 20 ... +... +``` + +This topology reflects the virtual hardware generated by OpenNebula. NUMA nodes 0 and 1 correspond to the Grace CPU memory domains, while the remaining nodes represent the ACPI Generic Initiator nodes associated with the assigned GPUs. + +Verify that the GPUs are visible inside the guest: + +```shell +nvidia-smi +``` + +Example output: + +```default ++-----------------------------------------------------------------+ +| NVIDIA-SMI 595.71.05 Driver Version: 595.71.05 | +| CUDA Version: 13.2 | ++-----------------------------------------------------------------+ +| GPU Name Persistence-M | Bus-Id Disp.A | Vol ECC | +| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU Compute | +| | | MIG M | +|=============================+=====================+=============| +| 0 NVIDIA GB200 Off | 00000000:A1:00.0 Off | 0 | +| N/A 38C P0 163W/1200W | 0MiB / 189471MiB | 0% Def | +| | | Disabled | ++-----------------------------+------------------------+----------+ +| 1 NVIDIA GB200 Off | 00000000:A9:00.0 Off | 0 | +| N/A 38C P0 164W/1200W | 0MiB / 189471MiB | 0% Def | +| | | Disabled | ++-----------------------------+------------------------+----------+ +| 2 NVIDIA GB200 Off | 00000000:B1:00.0 Off | 0 | +| N/A 38C P0 206W/1200W | 0MiB / 189471MiB | 0% Def | +| | | Disabled | ++-----------------------------+------------------------+----------+ +| 3 NVIDIA GB200 Off | 00000000:B9:00.0 Off | 0 | +| N/A 38C P0 221W/1200W | 0MiB / 189471MiB | 0% Def | +| | | Disabled | ++-----------------------------+------------------------+----------+ +``` + +Inspect the GPU topology: + +```shell +nvidia-smi topo -m +``` + +Example output: + +```default + GPU0 GPU1 GPU2 GPU3 CPU Affinity NUMA Affinity GPU NUMA ID +GPU0 X NV18 NV18 NV18 0-71 0 4 +GPU1 NV18 X NV18 NV18 0-71 0 3 +GPU2 NV18 NV18 X NV18 72-143 1 9 +GPU3 NV18 NV18 NV18 X 72-143 1 2 +``` + +This output confirms that: + +* The GPUs are correctly detected inside the guest +* NVLink connectivity is preserved +* GPU affinity matches the corresponding CPU NUMA node and the virtual topology generated by OpenNebula reproduces the physical Grace platform topology. diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_vswitch.md b/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_vswitch.md new file mode 100644 index 000000000..a118adee3 --- /dev/null +++ b/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_vswitch.md @@ -0,0 +1,10 @@ +--- +title: "NVIDIA NVSwitch (AE)" +linkTitle: "NVIDIA NVSwitch (AE) " +date: "2026-07-09" +description: +categories: +pageintoc: "58" +tags: ['AI','NVIDIA'] +weight: "8" +--- \ No newline at end of file diff --git a/content/product/cluster_configuration/networking_system/one_fabricmanager.md b/content/product/cluster_configuration/pci_passthrough_sriov/one_fabricmanager.md similarity index 99% rename from content/product/cluster_configuration/networking_system/one_fabricmanager.md rename to content/product/cluster_configuration/pci_passthrough_sriov/one_fabricmanager.md index 029609d99..41b01a689 100644 --- a/content/product/cluster_configuration/networking_system/one_fabricmanager.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/one_fabricmanager.md @@ -1,7 +1,7 @@ --- title: OpenNebula NVIDIA Fabric Manager (AE) linkTitle: NVIDIA Fabric Manager (AE) -weight: 8 +weight: 10 tags: ['AI','NVIDIA'] --- diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/overview.md b/content/product/cluster_configuration/pci_passthrough_sriov/overview.md index 2d1930178..3abb3e726 100644 --- a/content/product/cluster_configuration/pci_passthrough_sriov/overview.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/overview.md @@ -6,4 +6,71 @@ categories: pageintoc: "52" tags: weight: "1" ---- \ No newline at end of file +--- + + +Overview +PCI passthrough allows virtual machines to access physical PCI devices directly, bypassing device emulation. This approach enables workloads to use the full capabilities of specialized hardware such as GPUs, high-performance network adapters, storage controllers, and other accelerators while maintaining the flexibility of virtualization. + +This guide introduces the PCI passthrough architecture in OpenNebula and provides an overview of the supported device types. Detailed configuration procedures are covered in the following guides. + +## PCI Passthrough Architecture + +A PCI passthrough deployment relies on coordinated hardware and software support. Modern processors provide an Input-Output Memory Management Unit (IOMMU), such as Intel VT-d, AMD-Vi, or Arm SMMUv3, to safely map device access to guest memory. The Linux kernel exposes this capability through the VFIO framework, allowing libvirt and QEMU to securely assign physical PCI devices directly to virtual machines. + +OpenNebula manages this process by discovering available PCI devices on each host, exposing them as host resources that can be scheduled for virtual machines, selecting suitable hosts during scheduling, and generating the appropriate virtualization configuration as part of its integrated scheduling, monitoring, and virtual machine management infrastructure. + +OpenNebula abstracts this complexity and allows administrators to manage PCI devices using standard host and virtual machine templates. + +## Supported Device Types + +OpenNebula supports assigning a wide variety of PCI devices to virtual machines. PCI passthrough is a generic mechanism that can be applied to many types of hardware. However, two categories are of particular relevance and OpenNebula provides enhanced integration and configuration capabilities: + +* **Graphics Processing Units (GPUs)**: GPU passthrough enables virtual machines to use physical GPUs for compute-intensive workloads such as Artificial Intelligence (AI), High Performance Computing (HPC), visualization, and graphics acceleration. OpenNebula supports NVIDIA GPUs through both full PCI passthrough and mediated devices (vGPU), depending on the GPU model and virtualization technology. +* **Network Interfaces**: PCI passthrough can be used with high-performance network adapters to provide direct access to physical networking hardware from virtual machines. OpenNebula supports assigning both Physical Functions (PFs) and Single Root I/O Virtualization (SR-IOV) Virtual Functions (VFs), while maintaining centralized management through OpenNebula. + +## PCI Device Lifecycle in OpenNebula + +OpenNebula manages PCI devices throughout their lifecycle, allowing administrators to manage PCI devices using the same workflow as other OpenNebula resources: + +1. **Host Discovery**: The monitoring subsystem automatically discovers PCI devices available on each virtualization host and collects information such as vendor, device identifiers, class, NUMA locality, and virtualization capabilities. +2. **Device Scheduling**: PCI devices become schedulable host resources. During deployment, the scheduler selects a host satisfying both the virtual machine requirements and the requested PCI devices. +3. **Virtual Machine Deployment**: When a virtual machine is deployed, OpenNebula generates the corresponding libvirt domain configuration, attaches the requested PCI devices, configures the required virtual PCI topology, and enables additional virtualization features when required by the hardware platform. + * The PCI device can also be configured in the VM post VM deployment. Network interfaces can be hot-plugged. +4. **Device Release**: When the virtual machine is terminated, the PCI devices are automatically released and become available for future deployments. + +## Supported Virtualization Features + +OpenNebula supports several PCI virtualization technologies, including: + +* Direct PCI passthrough using VFIO +* SR-IOV Virtual Functions (VFs) in switchdev and legacy mode +* NVIDIA mediated devices (vGPU) and MIG + +Depending on the hardware platform, OpenNebula also supports additional virtualization capabilities, including: + +* IOMMUFD-based device assignment +* NUMA-aware device placement +* Huge Page-backed memory +* Advanced PCI topology generation +* Platform-specific features such as Arm SMMUv3, ACPI Generic Initiator nodes, and dedicated IOMMU devices for NVIDIA Grace platforms + +Not all features are applicable to every device type or hardware platform. Refer to the device-specific guides for detailed compatibility information. + +## Documentation Structure + +The PCI passthrough documentation is organized into the following guides: + +| **Guide** | **Description** | +|-------|-------------| +| [Host Configuration]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}) | Configure virtualization hosts for PCI passthrough, including IOMMU, VFIO, Huge Pages, SR-IOV, and other common host requirements. | +| [Network Interfaces]({{% relref "product/cluster_configuration/pci_passthrough_sriov/network_interfaces/" %}}) | Configure PCI passthrough and SR-IOV for network adapters. | +| [Device Passthrough]({{% relref "product/cluster_configuration/pci_passthrough_sriov/pci_passthrough/" %}}) | Configure the passthrough configuration of a given device. | +| [NVIDIA GPUs]({{% relref "product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough/" %}}) | Configure NVIDIA GPUs for passthrough and vGPU deployments, including platform-specific features such as Grace and Grace Blackwell. | +| [NVIDIA Fabric Manager]({{% relref "product/cluster_configuration/pci_passthrough_sriov/one_fabricmanager/" %}}) | Configure NVIDIA Fabric Manager for supported GPU platforms. | + +## Next Steps + +Before assigning PCI devices to virtual machines, configure the virtualization hosts by following the [Host Configuration guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}). + +Additional configuration required for specific device types is described in the corresponding device-specific guides. diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/pci_passthrough.md b/content/product/cluster_configuration/pci_passthrough_sriov/pci_passthrough.md index c894deb3f..a0042de06 100644 --- a/content/product/cluster_configuration/pci_passthrough_sriov/pci_passthrough.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/pci_passthrough.md @@ -5,7 +5,7 @@ description: categories: pageintoc: "56" tags: -weight: "5" +weight: "4" --- It is possible to discover PCI devices in the Hosts and directly assign them to Virtual Machines in the KVM hypervisor. diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/vgpu.md b/content/product/cluster_configuration/pci_passthrough_sriov/vgpu.md index 39a2d2d8b..a12b4c0f9 100644 --- a/content/product/cluster_configuration/pci_passthrough_sriov/vgpu.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/vgpu.md @@ -7,6 +7,7 @@ categories: pageintoc: "57" tags: ['AI','NVIDIA'] weight: "4" +toc_hide: true --- From 846a031a3d47e87681da58d78e8cd00af802aa4f Mon Sep 17 00:00:00 2001 From: mattrowe-opennebula Date: Mon, 20 Jul 2026 12:08:29 +0200 Subject: [PATCH 03/38] F OpenNebula/one#7518: PCI updates --- .../{ => hosts_and_clusters}/hosts_create.png | Bin .../hosts_fireedge.png | Bin .../sunstone_cluster_create.png | Bin .../sunstone_cluster_dashboard.png | Bin .../sunstone_cluster_details.png | Bin .../sunstone_cluster_evc_attributes.png | Bin .../sunstone_cluster_evc_update.png | Bin .../hosts_and_clusters/cluster_guide.md | 110 +++--- .../hosts_and_clusters/hosts.md | 72 ++-- .../hosts_and_clusters/overview.md | 20 +- .../networking_system/infiniband.md | 25 +- .../networking_system/overview.md | 22 +- .../host_configuration.md | 2 +- .../network_interfaces.md | 263 +++++++++++++- .../nvidia_gpu_passthrough.md | 331 +++++++++++++++--- .../nvidia_grace_platform.md | 11 +- .../pci_passthrough_sriov/overview.md | 14 +- 17 files changed, 688 insertions(+), 182 deletions(-) rename assets/images/{ => hosts_and_clusters}/hosts_create.png (100%) rename assets/images/{ => hosts_and_clusters}/hosts_fireedge.png (100%) rename assets/images/{ => hosts_and_clusters}/sunstone_cluster_create.png (100%) rename assets/images/{ => hosts_and_clusters}/sunstone_cluster_dashboard.png (100%) rename assets/images/{ => hosts_and_clusters}/sunstone_cluster_details.png (100%) rename assets/images/{ => hosts_and_clusters}/sunstone_cluster_evc_attributes.png (100%) rename assets/images/{ => hosts_and_clusters}/sunstone_cluster_evc_update.png (100%) diff --git a/assets/images/hosts_create.png b/assets/images/hosts_and_clusters/hosts_create.png similarity index 100% rename from assets/images/hosts_create.png rename to assets/images/hosts_and_clusters/hosts_create.png diff --git a/assets/images/hosts_fireedge.png b/assets/images/hosts_and_clusters/hosts_fireedge.png similarity index 100% rename from assets/images/hosts_fireedge.png rename to assets/images/hosts_and_clusters/hosts_fireedge.png diff --git a/assets/images/sunstone_cluster_create.png b/assets/images/hosts_and_clusters/sunstone_cluster_create.png similarity index 100% rename from assets/images/sunstone_cluster_create.png rename to assets/images/hosts_and_clusters/sunstone_cluster_create.png diff --git a/assets/images/sunstone_cluster_dashboard.png b/assets/images/hosts_and_clusters/sunstone_cluster_dashboard.png similarity index 100% rename from assets/images/sunstone_cluster_dashboard.png rename to assets/images/hosts_and_clusters/sunstone_cluster_dashboard.png diff --git a/assets/images/sunstone_cluster_details.png b/assets/images/hosts_and_clusters/sunstone_cluster_details.png similarity index 100% rename from assets/images/sunstone_cluster_details.png rename to assets/images/hosts_and_clusters/sunstone_cluster_details.png diff --git a/assets/images/sunstone_cluster_evc_attributes.png b/assets/images/hosts_and_clusters/sunstone_cluster_evc_attributes.png similarity index 100% rename from assets/images/sunstone_cluster_evc_attributes.png rename to assets/images/hosts_and_clusters/sunstone_cluster_evc_attributes.png diff --git a/assets/images/sunstone_cluster_evc_update.png b/assets/images/hosts_and_clusters/sunstone_cluster_evc_update.png similarity index 100% rename from assets/images/sunstone_cluster_evc_update.png rename to assets/images/hosts_and_clusters/sunstone_cluster_evc_update.png diff --git a/content/product/cluster_configuration/hosts_and_clusters/cluster_guide.md b/content/product/cluster_configuration/hosts_and_clusters/cluster_guide.md index c60ea7f86..5c25c1f2e 100644 --- a/content/product/cluster_configuration/hosts_and_clusters/cluster_guide.md +++ b/content/product/cluster_configuration/hosts_and_clusters/cluster_guide.md @@ -12,14 +12,14 @@ weight: "3" -Clusters group together Hosts, datastores, and virtual networks that are configured to work together. A cluster is used to: +Clusters group together Hosts, datastores, and virtual networks that are configured to work together. A Cluster is used to: > * Ensure that VMs use resources that are compatible. > * Assign resources to user groups by creating Virtual Private Clouds. -Clusters should contain homogeneous resources. Note that some operations like live migrations are restricted to Hosts in the same cluster. +Clusters should contain homogeneous resources. Note that some operations like live migrations are restricted to Hosts in the same Cluster. -The requirements for live migrating VMs between Hosts of the same cluster are that no differences occur in the following areas of the hypervisors: +The requirements for live migrating VMs between Hosts of the same Cluster are that no differences occur in the following areas of the hypervisors: * CPU model * Firmware settings @@ -32,20 +32,20 @@ The requirements for live migrating VMs between Hosts of the same cluster are th ## Cluster Management -Clusters are managed with the `onecluster` command. To create new clusters, use `onecluster create `. Existing clusters can be inspected with the `onecluster list` and `show` commands. +Clusters are managed with the `onecluster` command. To create new Clusters, use `onecluster create `. Existing Clusters can be inspected with the `onecluster list` and `show` commands. -```default -$ onecluster list +```shell +onecluster list ID NAME HOSTS NETS DATASTORES -$ onecluster create production +onecluster create production ID: 100 -$ onecluster list +onecluster list ID NAME HOSTS NETS DATASTORES 100 production 0 0 0 -$ onecluster show production +onecluster show production CLUSTER 100 INFORMATION ID : 100 NAME : production @@ -59,24 +59,24 @@ DATASTORES ### Add Hosts to a Cluster -Every Host must belong to a cluster, so if no cluster is specified it will be assigned to the `default` cluster by default. Hosts can be created directly in a different cluster by using the `--cluster` option of `onehost create`, or be added at any time with the command `onecluster addhost`. Hosts can be in **only one cluster** at a time. +Every Host must belong to a Cluster, so if no Cluster is specified it will be assigned to the `default` Cluster by default. Hosts can be created directly in a different Cluster by using the `--cluster` option of `onehost create`, or be added at any time with the command `onecluster addhost`. Hosts can be in **only one Cluster** at a time. -To delete a Host from a cluster, the command `onecluster delhost` must be used. +To delete a Host from a Cluster, the command `onecluster delhost` must be used. -In the following example, we will add Host 0 to the cluster we created before. You will notice that the `onecluster show` command will list the Host ID 0 as part of the cluster. +In the following example, we will add Host 0 to the Cluster we created before. You will notice that the `onecluster show` command will list the Host ID 0 as part of the Cluster. -```default -$ onehost list +```shell +onehost list ID NAME CLUSTER RVM TCPU FCPU ACPU TMEM FMEM AMEM STAT 0 host01 - 7 400 290 400 3.7G 2.2G 3.7G on -$ onecluster addhost production host01 +onecluster addhost production host01 -$ onehost list +onehost list ID NAME CLUSTER RVM TCPU FCPU ACPU TMEM FMEM AMEM STAT 0 host01 producti 7 400 290 400 3.7G 2.2G 3.7G on -$ onecluster show production +onecluster show production CLUSTER 100 INFORMATION ID : 100 NAME : production @@ -91,22 +91,22 @@ DATASTORES ### Add Resources to Clusters -Datastores and virtual networks can be added to multiple clusters. This means that any Host in those clusters is properly configured to run VMs using images from those datastores, or is using leases from those virtual networks. +Datastores and virtual networks can be added to multiple Clusters. This means that any Host in those Clusters is properly configured to run VMs using images from those datastores, or is using leases from those virtual networks. -For instance, if you have several Hosts configured to use a given Open vSwitch network, you would group them in the same cluster. The [Scheduler]({{% relref "../../cloud_system_administration/scheduler" %}}) will know that VMs using these resources can be deployed in any of the Hosts of the cluster. +For instance, if you have several Hosts configured to use a given Open vSwitch network, you would group them in the same Cluster. The [Scheduler]({{% relref "product/cloud_system_administration/scheduler" %}}) will know that VMs using these resources can be deployed in any of the Hosts of the Cluster. These operations can be done with the `onecluster` `addvnet/delvnet` and `adddatastore/deldatastore`, respectively: -```default -$ onecluster addvnet production priv-ovswitch +```shell +onecluster addvnet production priv-ovswitch -$ onecluster adddatastore production iscsi +onecluster adddatastore production iscsi -$ onecluster list +onecluster list ID NAME HOSTS NETS DATASTORES 100 production 1 1 1 -$ onecluster show 100 +onecluster show 100 CLUSTER 100 INFORMATION ID : 100 NAME : production @@ -125,79 +125,83 @@ DATASTORES ### The System Datastore for a Cluster -In order to create a complete environment where the scheduler can deploy VMs, your clusters need to have at least one System Datastore. +In order to create a complete environment where the scheduler can deploy VMs, your Clusters need to have at least one System Datastore. You can add the default System Datastore (ID: 0) or create a new one to improve its performance (e.g., balance VM I/O between different servers) or to use different System Datastore types (e.g., `shared` and `local`). -To use a specific System Datastore with your cluster instead of the default one, just create it and associate it just like any other datastore (`onecluster adddatastore`). +To use a specific System Datastore with your Cluster instead of the default one, just create it and associate it just like any other datastore (`onecluster adddatastore`). ## Managing Clusters in Sunstone -The [Sunstone UI interface]({{% relref "../../control_plane_configuration/graphical_user_interface/fireedge_sunstone#fireedge-sunstone" %}}) offers an easy way to manage clusters and the resources within them. You will find the cluster sub-menu under the infrastructure menu. From there you will be able to: +The [Sunstone UI interface]({{% relref "../../control_plane_configuration/graphical_user_interface/fireedge_sunstone#fireedge-sunstone" %}}) offers an easy way to manage Clusters and the resources within them. You will find the Cluster sub-menu under the infrastructure menu. From there you will be able to: -- Create new clusters selecting the resources you want to include in this cluster. +- Create new Clusters selecting the resources you want to include in this Cluster. -![create_cluster](/images/sunstone_cluster_create.png) +{{< image path="/images/hosts_and_clusters/sunstone_cluster_create.png" alt="Sunstone login" align="center" width="90%" mb="20px" +>}} -- See the list of current clusters, from which you can update or delete existing ones. +- See the list of current Clusters, from which you can update or delete existing ones. -![dashboard_cluster](/images/sunstone_cluster_dashboard.png) +{{< image path="/images/hosts_and_clusters/sunstone_cluster_dashboard.png" alt="Sunstone login" align="center" width="90%" mb="20px" +>}} +- See Cluster details and update overcommitment. -- See cluster details and update overcommitment. - -![details_cluster](/images/sunstone_cluster_details.png) +{{< image path="/images/hosts_and_clusters/sunstone_cluster_details.png" alt="Sunstone login" align="center" width="90%" mb="20px" +>}} ## Enhanced VM Compatibility (EVC) -The Enhanced VM Compatibility (EVC) feature facilitates the management of heterogeneous OpenNebula clusters by masking host CPU capabilities to enforce a unified base model. Using a lowest-common-denominator approach ensures CPU compatibility across hosts and enables seamless live migration of Virtual Machines between hosts with different processor generations. +The Enhanced VM Compatibility (EVC) feature facilitates the management of heterogeneous OpenNebula Clusters by masking Host CPU capabilities to enforce a unified base model. Using a lowest-common-denominator approach ensures CPU compatibility across Hosts and enables seamless live migration of Virtual Machines between Hosts with different processor generations. -EVC is configured at the cluster level. This simplifies management and improves scalability by allowing administrators to add newer hardware to existing clusters without preventing VM migration due to CPU differences. +EVC is configured at the Cluster level. This simplifies management and improves scalability by allowing administrators to add newer hardware to existing Clusters without preventing VM migration due to CPU differences. ### Using EVC with the CLI -1. Inspect the cluster to view the current template and attributes: +1. Inspect the Cluster to view the current template and attributes: -```bash -$ onecluster show default +```shell +onecluster show default ``` -Look for the `CLUSTER TEMPLATE` section. If `EVC_MODE` is not present, it has not been configured for the cluster. +Look for the `CLUSTER TEMPLATE` section. If `EVC_MODE` is not present, it has not been configured for the Cluster. -2. Set the `EVC_MODE` attribute on a cluster using `onecluster update`. For example, to set a Sandy Bridge baseline: +2. Set the `EVC_MODE` attribute on a Cluster using `onecluster update`. For example, to set a Sandy Bridge baseline: -```bash -$ onecluster update default" +```shell +onecluster update default" ``` Then add the `EVC_MODE` attribute to the list: -```bash +```shell ... EVC_MODE="sandybridge" ... ``` -The exact CPU model string depends on the hypervisor's supported CPU map. You can view the supported cpu models of a given host with the following command under the `KVM_CPU_MODELS` key: +The exact CPU model string depends on the hypervisor's supported CPU map. You can view the supported cpu models of a given Host with the following command under the `KVM_CPU_MODELS` key: -```bash -$ onehost show -j +```shell +onehost show -j ``` -Make sure to select a cpu model available in all hosts in the cluster, otherwise you may fail to deploy VMs on unsupported hosts. +Make sure to select a cpu model available in all Hosts in the Cluster, otherwise you may fail to deploy VMs on unsupported Hosts. -3. To revert or remove EVC, update the cluster template to remove the `EVC_MODE` attribute (for example by setting it to an empty string or re-applying a template without the attribute). +3. To revert or remove EVC, update the Cluster template to remove the `EVC_MODE` attribute (for example by setting it to an empty string or re-applying a template without the attribute). ### Using EVC with Sunstone The Fireedge / Sunstone web UI provides a convenient way to enable and change EVC without editing templates directly. -1. Open the Infrastructure → Clusters view and select the cluster you want to configure. +1. Open the Infrastructure → Clusters view and select the Cluster you want to configure. 2. Click the Update button and go to the Select Hosts tabs, there you will see the EVC Mode section. To enable EVC, choose a model from the droplist. Afterwards you can click Finish. -![Update cluster EVC mode](/images/sunstone_cluster_evc_update.png) +{{< image path="/images/hosts_and_clusters/sunstone_cluster_evc_update.png" alt="Update cluster EVC mode" align="center" width="90%" mb="20px" +>}} -3. Once the EVC mode is set, you can see it listed in the cluster attributes the same way as if the CLI had been used. +3. Once the EVC mode is set, you can see it listed in the Cluster attributes the same way as if the CLI had been used. -![EVC set in cluster attributes](/images/sunstone_cluster_evc_attributes.png) +{{< image path="/images/hosts_and_clusters/sunstone_cluster_evc_attributes.png" alt="EVC set in cluster attributes" align="center" width="90%" mb="20px" +>}} \ No newline at end of file diff --git a/content/product/cluster_configuration/hosts_and_clusters/hosts.md b/content/product/cluster_configuration/hosts_and_clusters/hosts.md index 847e2ca50..3dc0ce3a0 100644 --- a/content/product/cluster_configuration/hosts_and_clusters/hosts.md +++ b/content/product/cluster_configuration/hosts_and_clusters/hosts.md @@ -12,9 +12,9 @@ weight: "2" - +In order to use a physical or virtual server as a Host, you must first prepare the server with a hypervisor and configure it to be added to OpenNebula as a Host, refer to the guides to prepare a [KVM node]({{% relref "software/installation_process/cluster_installation/kvm_node_installation/" %}}) or an [LXC node]({{% relref "software/installation_process/cluster_installation/lxc_node_installation/" %}}). -In order to use your existing physical nodes, you have to add them to OpenNebula as Hosts. To add a Host only its hostname and type is needed. +Once you have prepared your physical or virtual nodes, you can add them to OpenNebula as Hosts. To add a Host only its hostname and type is needed. {{< alert title="Warning" type="warning" >}} Before adding a Linux Host check that you can SSH to it without being prompted for a password.{{< /alert >}} @@ -25,8 +25,8 @@ Hosts are the servers managed by OpenNebula responsible for running VMs. To use Creating a Host: -```default -$ onehost create host01 --im kvm --vm kvm +```shell +onehost create host01 --im kvm --vm kvm ID: 0 ``` @@ -40,17 +40,17 @@ In the examples included in this guide we’ll use KVM as the hypervisor. Note t To remove a Host you can either specify it by ID or by name. The following commands are equivalent: -```default -$ onehost delete host01 -$ onehost delete 0 +```shell +onehost delete host01 +onehost delete 0 ``` ## Showing and Listing Hosts To display information about a single Host, use the `show` command: -```default -$ onehost show server +```shell +onehost show server HOST 0 INFORMATION ID : 0 @@ -131,8 +131,8 @@ The information of a Host contains: To see a list of all the Hosts: -```default -$ onehost list +```shell +onehost list ID NAME CLUSTER RVM ALLOCATED_CPU ALLOCATED_MEM STAT 0 server server 1 100 / 400 (25%) 1024M / 7.3G (13%) on 1 kvm1 kvm 0 - - off @@ -204,20 +204,20 @@ In order to manage the life cycle of a Host it can be set to different operation The `onehost` tool provides commands to set the operation mode of a Host: `disable`, `offline`, and `enable`, for example: -```default -$ onehost disable 0 +```shell +onehost disable 0 ``` To re-enable the Host, use the `enable` command: -```default -$ onehost enable 0 +```shell +onehost enable 0 ``` Similarly, to take the Host offline: -```default -$ onehost offline 0 +```shell +onehost offline 0 ``` {{< alert title="Note" type="info" >}} @@ -227,13 +227,13 @@ Apart from the commands above, the `onehost` tool also provides some commands th You can use `forceupdate` subcommand to reset the monitoring process on the Host: -```default -$ onehost forceupdate 0 +```shell +onehost forceupdate 0 ``` The `flush` command will migrate all the active VMs in the specified Host to another server with enough capacity. At the same time, the specified Host will be disabled so no more Virtual Machines are deployed in it. This command is useful to clean a Host of active VMs. The migration process can be done by a `resched` action or by a recover `delete-recreate` action; it can be configured in `/etc/one/cli/onehost.yaml` by setting the field `default_actions\flush` to `delete-recreate` or to `resched`. Here is an example: -```default +```shell :default_actions: - :flush: delete-recreate ``` @@ -246,8 +246,8 @@ You can add custom attributes either by [creating a probe in the host]({{% relre For example, to label a Host as *production* we can add a custom tag *TYPE*: -```default -$ onehost update +```shell +onehost update ... TYPE="production" ``` @@ -260,8 +260,8 @@ This tag can be used at a later time for scheduling purposes, [see more details When OpenNebula monitors a Host it copies driver files to `/var/tmp/one`. When these files are updated they need to be copied again to the Hosts with the `sync` command. To keep track of the probes version there’s a file in `/var/lib/one/remotes/VERSION`. By default this holds the OpenNebula version (e.g., ‘7.0.0’). This version can be seen in the Hosts by using `onehost show `: -```default -$ onehost show 0 +```shell +onehost show 0 HOST 0 INFORMATION ID : 0 [...] @@ -274,15 +274,15 @@ The command `onehost sync` only updates the Hosts with `VERSION` lower than the In case you want to force an upgrade, that is, without any `VERSION` checking, you can do it by using the `--force` option: -```default -$ onehost sync --force +```shell +onehost sync --force ``` -You can also select which Hosts you want to upgrade by naming them or selecting a cluster: +You can also select which Hosts you want to upgrade by naming them or selecting a Cluster: -```default -$ onehost sync host01,host02,host03 -$ onehost sync -c myCluster +```shell +onehost sync host01,host02,host03 +onehost sync -c myCluster ``` @@ -332,8 +332,8 @@ The cache is cleared when the monitoring daemon restarts. The monitoring mechanism in OpenNebula reports all VMs found in a hypervisor, even those not launched through OpenNebula. These VMs are referred to as Wild VMs. The Wild VMs can be spotted through the `onehost show` command: -```default -$ onehost show 3 +```shell +onehost show 3 HOST 3 INFORMATION ID : 3 NAME : MyAWSHost @@ -353,8 +353,10 @@ Wild VMs’ support and limitations may differ depending on the virtualization d You can also manage your Hosts using [Sunstone UI Interface]({{% relref "../../control_plane_configuration/graphical_user_interface/fireedge_sunstone#fireedge-sunstone" %}}). Select the Host tab and there you will be able to create, enable, disable, delete, and see information about your Hosts in a user-friendly way. -![image1](/images/hosts_fireedge.png) +{{< image path="/images/hosts_and_clusters/hosts_fireedge.png" alt="Sunstone login" align="center" width="90%" mb="20px" +>}} -- Create new hosts +- Create new Hosts: -![image2](/images/hosts_create.png) +{{< image path="/images/hosts_and_clusters/hosts_create.png" alt="Sunstone login" align="center" width="90%" mb="20px" +>}} diff --git a/content/product/cluster_configuration/hosts_and_clusters/overview.md b/content/product/cluster_configuration/hosts_and_clusters/overview.md index 3808ea566..fe711c94b 100644 --- a/content/product/cluster_configuration/hosts_and_clusters/overview.md +++ b/content/product/cluster_configuration/hosts_and_clusters/overview.md @@ -12,16 +12,28 @@ weight: "1" -A **Host** is a server that has the ability to run Virtual Machines and that is connected to OpenNebula’s Front-end server. To learn how to prepare the Hosts, you can read the [Installation]({{% relref "../../../software/installation_process" %}}) guide. Hosts are usually grouped in **Clusters**. +A **Host** is a server (physical or virtual) that provides compute capacity for cloud workloads, such as Virtual Machines or Kubernetes Clusters. Hosts must be connected to and controlled by one or more OpenNebula Front-end servers. To learn how to prepare Hosts, read the [Cluster section of the installation guides]({{% relref "software/installation_process/cluster_installation/" %}}). A **Cluster** is a logical grouping of OpenNebula resources including Hosts, Virtual Networks and datastores. Hosts are usually logically grouped within **Clusters**, but may exist independently of a Cluster object. ## How Should I Read This Chapter In this chapter there are four guides describing these objects. -* **Host Management**: Host management is achieved through the `onehost` CLI command or through the Sunstone GUI. You can read about Host Management in more detail in the [Hosts]({{% relref "hosts#hosts-guide" %}}) guide. -* **Cluster Management**: Hosts can be grouped in clusters. These clusters are managed with the `onecluster` CLI command or through the Sunstone GUI. You can read about Cluster Management in more detail in the [Clusters]({{% relref "cluster_guide#cluster-guide" %}}) guide. +* **Host Management**: Host management is achieved through the `onehost` CLI command or through the **Infrastructure** section of the Sunstone GUI. You can read about Host Management in more detail in the [Host Management]({{% relref "hosts#hosts-guide" %}}) guide. +* **Cluster Management**: Hosts can be grouped in Clusters. These Clusters are managed with the `onecluster` CLI command or through the **Infrastructure** section of the Sunstone GUI. You can read about Cluster Management in more detail in the [Cluster Management]({{% relref "cluster_guide#cluster-guide" %}}) guide. -You should read all the guides in this chapter to familiarize yourself with these objects. For small and homogeneous clouds you may not need to create new clusters. +You should read all the guides in this chapter to familiarize yourself with the details of Host and Cluster objects. For small and homogeneous clouds you may not need to create new Clusters. + +### PCI Passthrough and SR-IOV + +If you intend to use specialized PCI hardware, such as GPUs or PCI network interfaces, it is necessary to complete additional configuration to ensure that workloads deployed within OpenNebula Hosts or Clusters have proper access to the devices. Refer to the [PCI Passthrough and SR-IOV]({{% relref "product/cluster_configuration/pci_passthrough_sriov/" %}}) section for more details. + +### Networking + +Virtual Machines deployed by OpenNebula on Hosts and Clusters within a cloud deployment must be connected to a Virtual Network to facilitate communication within the cloud and to the internet. Refer to the [Networking System Section]({{% relref "product/cluster_configuration/networking_system/" %}}) for details on configuring Virtual Networks within an OpenNebula cloud. + +### Storage and Backups + +OpenNebula supports multiple options for cloud storage, including Ceph storage and SAN storage and backup solutions from multiple vendors. Refer to the [Storage System Guides]({{% relref "product/cluster_configuration/storage_system/" %}}) and the [Backup System Section]({{% relref "product/cluster_configuration/backup_system/" %}}) for further details. ## Hypervisor Compatibility diff --git a/content/product/cluster_configuration/networking_system/infiniband.md b/content/product/cluster_configuration/networking_system/infiniband.md index 30eaa5dd5..59ccd9ffa 100644 --- a/content/product/cluster_configuration/networking_system/infiniband.md +++ b/content/product/cluster_configuration/networking_system/infiniband.md @@ -7,25 +7,25 @@ tags: ["networking"] weight: "7" --- -InfiniBand is a high-performance networking technology designed for environments where extremely low latency, high throughput, and efficient CPU utilization are critical. It is widely used in High Performance Computing (HPC), AI training and inference clusters, and other data-intensive workloads that require significantly higher performance than conventional Ethernet networks. InfiniBand achieves this through technologies such as Remote Direct Memory Access (RDMA), allowing applications to exchange data directly between systems with minimal CPU involvement. +InfiniBand is a high-performance networking technology designed for environments where extremely low latency, high throughput, and efficient CPU utilization are critical. It is widely used in High Performance Computing (HPC), AI training and inference Clusters, and other data-intensive workloads that require significantly higher performance than conventional Ethernet networks. InfiniBand achieves this through technologies such as Remote Direct Memory Access (RDMA), allowing applications to exchange data directly between systems with minimal CPU involvement. OpenNebula supports deployment on infrastructure equipped with InfiniBand fabrics, enabling virtualized and bare-metal workloads to take advantage of high-speed interconnects. Depending on the workload requirements, InfiniBand can be used in several different ways: * As an IP network using IP over InfiniBand (IPoIB). * By exposing InfiniBand adapters directly to Virtual Machines using PCI Passthrough or SR-IOV Virtual Functions (VFs). -* For storage and cluster communication over high-speed fabrics. +* For storage and Cluster communication over high-speed fabrics. * For applications that use RDMA directly. ## Typical Use Cases InfiniBand is most commonly deployed for workloads such as: -* AI and machine learning training clusters +* AI and machine learning training Clusters * High Performance Computing (HPC) * Scientific simulations * High-performance distributed storage * MPI-based parallel applications -* GPU clusters requiring low-latency node-to-node communication +* GPU Clusters requiring low-latency node-to-node communication These environments benefit from InfiniBand's low latency, high bandwidth, and efficient RDMA transport. @@ -37,7 +37,7 @@ OpenNebula does not implement a dedicated InfiniBand networking driver. Instead, The simplest deployment method is IP over InfiniBand (IPoIB), where the InfiniBand fabric behaves as a conventional IP network. -Once the host operating system has configured the InfiniBand interfaces, they appear as standard Linux network interfaces and can be used throughout OpenNebula just like Ethernet interfaces. +Once the Host operating system has configured the InfiniBand interfaces, they appear as standard Linux network interfaces and can be used throughout OpenNebula just like Ethernet interfaces. Typical uses include: @@ -78,7 +78,7 @@ depending on whether the adapter operates in Legacy or Switchdev mode. ## Host Requirements -Before deploying workloads using InfiniBand, ensure that each host is correctly configured by the operating system. +Before deploying workloads using InfiniBand, ensure that each Host is correctly configured by the operating system. Typical requirements include: @@ -101,7 +101,7 @@ If Virtual Machines require native InfiniBand functionality, the guest operating Guests using PCI Passthrough or SR-IOV interact directly with the assigned hardware and are responsible for managing the device. -Considerations +### Considerations When planning an InfiniBand deployment, consider the following: @@ -110,13 +110,4 @@ PCI Passthrough and SR-IOV provide the highest performance but may reduce Virtua IPoIB offers excellent compatibility with existing networking tools but does not expose all RDMA capabilities to applications. Applications must be specifically designed or configured to use RDMA in order to benefit from InfiniBand's lowest latency communication. -Network configuration, firmware management, and Subnet Manager deployment remain the responsibility of the underlying operating system and network infrastructure. - -## Related Documentation - -* PCI Passthrough -* Virtual Networks -* Linux Bridge Networks -* Open vSwitch Networks -* NVIDIA Spectrum-X -* Bare Metal Provisioning (when using InfiniBand-enabled hosts) \ No newline at end of file +Network configuration, firmware management, and Subnet Manager deployment remain the responsibility of the underlying operating system and network infrastructure. \ No newline at end of file diff --git a/content/product/cluster_configuration/networking_system/overview.md b/content/product/cluster_configuration/networking_system/overview.md index 91d8c96cb..ffa01cc40 100644 --- a/content/product/cluster_configuration/networking_system/overview.md +++ b/content/product/cluster_configuration/networking_system/overview.md @@ -16,17 +16,29 @@ When a new Virtual Machine is launched, OpenNebula will connect its virtual netw OpenNebula supports the following networking modes: -* [Bridged]({{% relref "bridged#bridged" %}}). The VM NIC is added to a Linux bridge on the Host. This mode can be configured to use Security Groups and network isolation. -* [802.1Q VLAN]({{% relref "vlan#hm-vlan" %}}). The VM NIC is added to a Linux bridge on the Host and the Virtual Network is configured to handle 802.1Q VLAN isolation. -* [VXLAN]({{% relref "vxlan#vxlan" %}}). The VM NIC is added to a Linux bridge on the Host and the Virtual Network implements isolation using the VXLAN encapsulation. -* [Open vSwitch]({{% relref "openvswitch#openvswitch" %}}). The VM NIC is added to a Open vSwitch bridge on the Host and the Virtual Network optionally handles 802.1Q VLAN isolation. -* [Open vSwitch on VXLAN]({{% relref "openvswitch#openvswitch-vxlan" %}}). The VM NIC is added to a Open vSwitch bridge on the Host and the Virtual Network is configured to provide both isolation with VXLAN encapsulation and optionally 802.1Q VLAN. +* [Bridged]({{% relref "bridged#bridged" %}}): The VM NIC is added to a Linux bridge on the Host. This mode can be configured to use Security Groups and network isolation. +* [802.1Q VLAN]({{% relref "vlan#hm-vlan" %}}): The VM NIC is added to a Linux bridge on the Host and the Virtual Network is configured to handle 802.1Q VLAN isolation. +* [VXLAN]({{% relref "vxlan#vxlan" %}}): The VM NIC is added to a Linux bridge on the Host and the Virtual Network implements isolation using the VXLAN encapsulation. +* [Open vSwitch]({{% relref "openvswitch#openvswitch" %}}): The VM NIC is added to a Open vSwitch bridge on the Host and the Virtual Network optionally handles 802.1Q VLAN isolation. +* [Open vSwitch on VXLAN]({{% relref "openvswitch#openvswitch-vxlan" %}}): The VM NIC is added to a Open vSwitch bridge on the Host and the Virtual Network is configured to provide both isolation with VXLAN encapsulation and optionally 802.1Q VLAN. The attribute `VN_MAD` of a Virtual Network determines which of the above networking modes is used. {{< alert title="Note" type="info" >}} Security Groups are not supported in the Open vSwitch modes.{{< /alert >}} +## Accelerated Networking + +OpenNebula supports accelerated networking and interconnect technologies for AI and HPC environments. These technologies complement the standard Virtual Network modes by providing high-bandwidth, low-latency communication, direct device access, hardware offload, and optimized communication between GPUs and compute nodes. + +* [InfiniBand]({{% relref "product/cluster_configuration/networking_system/infiniband/" %}}): Provides a high-throughput, low-latency network fabric for distributed AI and HPC workloads. InfiniBand devices can be exposed to Virtual Machines through mechanisms such as PCI passthrough or SR-IOV. + +* [NVIDIA Spectrum-X]({{% relref "product/cluster_configuration/networking_system/spectrumx/" %}}): Provides an accelerated Ethernet fabric optimized for AI workloads, combining NVIDIA Spectrum switches and high-performance network adapters to improve communication between compute nodes. + +* [NVIDIA BlueField DPU]({{% relref "product/cluster_configuration/networking_system/nvidia_bluefield_dpu/" %}}): Offloads networking, security, encryption, and infrastructure services from the Host CPU. BlueField devices can be integrated into the infrastructure to provide accelerated and isolated data paths for tenant workloads. + +* [NVIDIA Fabric Manager]({{% relref "product/cluster_configuration/pci_passthrough_sriov/one_fabricmanager/" %}}): Manages and monitors the NVSwitch fabric used for high-speed communication between multiple NVIDIA GPUs within a Host. It initializes the fabric and coordinates GPU connectivity for supported multi-GPU systems. + ## How Should I Read This Chapter Before reading this Chapter make sure you are familiar with the [Open Cloud Storage]({{% relref "../storage_system/overview#storage" %}}). It’s necessary to be aware of requirements for your selected storage solution in order to be able to design the network architecture of your hypervisor nodes. diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/host_configuration.md b/content/product/cluster_configuration/pci_passthrough_sriov/host_configuration.md index c076c5a92..e40850d38 100644 --- a/content/product/cluster_configuration/pci_passthrough_sriov/host_configuration.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/host_configuration.md @@ -364,7 +364,7 @@ The system-wide configuration can be overridden for individual clusters or hosts |-----------|-------------| | PCI_FILTER | (List) Filters by PCI vendor:device:class patterns (same as for lspci) | | PCI_SHORT_ADDRESS | (List) Filters by short PCI address bus:device.function | -| PCI_DEVICE_NAME | | +| PCI_DEVICE_NAME | (List) Filters by the PCI device name reported by the Host | This allows different clusters to expose different classes of PCI devices while sharing the same frontend configuration. diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/network_interfaces.md b/content/product/cluster_configuration/pci_passthrough_sriov/network_interfaces.md index 2fecb15aa..71ae87b50 100644 --- a/content/product/cluster_configuration/pci_passthrough_sriov/network_interfaces.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/network_interfaces.md @@ -49,7 +49,7 @@ OpenNebula supports both SR-IOV operating modes. These attributes are applied directly by the network adapter. -* **Switchdev Mode**: In Switchdev mode, VF parameters are controlled by host-side representor interfaces. These representor interfaces can be attached to a virtual switch to establish port-level control. +* **Switchdev Mode**: In Switchdev mode, VF parameters are controlled by Host-side representor interfaces. These representor interfaces can be attached to a virtual switch to establish port-level control. In this mode, only the MAC address is applied directly to the VF interface. All other control parameters are managed by the virtual switch driver associated with the Virtual Network. @@ -92,6 +92,265 @@ Additional SR-IOV configuration for network adapters is described in the **Netwo ## Host Configuration for DPDK Interfaces +In cases where high network performance is needed but passing through PCI network interfaces to a VM is not possible, Open vSwitch can run with an accelerated datapath by using DPDK userspace libraries. In this mode, the packet processing responsibility is taken away from the kernel and dedicated resources are assigned to the packet processing. This includes CPU threads and huge pages. + +The virtual network interfaces of the VM are not passed through, but the uplink backing the virtual switch normally is passed through to OVS, with the use of vfio-pci. In this section there is the host configuration required to set up DPDK. + +### Installation + +You need a version of OVS that has been compiled with DPDK support. Linux distributions handle the distribution of this version quite differently. + +* **Ubuntu and Debian**: Use the openvswitch-switch-dpdk package. The openvswitch-switch package lacks DPDK libraries. +* **Red Hat**: + * Activate the fast-datapath-for-rhel--x86_64-rpms repo in subscription manager. + * Install any of the openvswitch packages. Red Hat distributes multiple versions, each with its own package. +* **Alma**: + * Install centos-release-nfv-openvswitch to activate the required repo. + * Install any of the openvswitch packages. + +Verify DPDK support by checking the OVS version: + +```shell +ovs-vswitchd --version + ovs-vswitchd (Open vSwitch) 3.5.3-6.el9s + DPDK 24.11.3 +``` + +### Resource Allocation + +It is important to have a clear picture of which resources are going to be exclusively dedicated to DPDK. These resources are effectively a payload, since they are not available to the rest of the system. + +### Network Interfaces + +Identify which network interfaces are going to be used as DPDK interfaces. When the system has multiple NUMA nodes, it is important to consider the node placement of these interfaces. + +To identify which node the interfaces belong to: + +```shell +cat /sys/bus/pci/devices/0000\:01\:00.0/numa_nod +``` + +### Memory + +Each Network Interface in DPDK requires a certain amount of memory in terms of hugepages. This amount of memory depends on the MTU of the interface and the NUMA node location of the interface. Whenever possible, use 1GB hugepages. + +A good rule of thumb is to use 1GB per 1500 MTU NIC and 3GB per 9000+ MTU NIC. For a detailed memory calculation refer to the [memory model documentation](https://docs.openvswitch.org/en/stable/topics/dpdk/memory/) in the OpenvSwitch doc. If there are NUMA nodes without a network interface, 1GB of memory should be allocated to said NUMA node. + +VMs with their virtual network interfaces backed by a DPDK capable bridge need hugepages to run as well. Therefore, more huge pages are required to consume this feature. + +Refer to the Huge Pages section to configure the required amount of pages. Consider that huge pages exist on a per node basis. If the node location is unspecified when requesting hugepages, the pages will be requested evenly. Make sure enough is available per node. + +VMs backed by a DPDK bridge also require hugepages. On top of the hugepages required for the OVS daemon, consider also pages for running VMs. + +Every memory dedicated to hugepages is effectively memory that is no longer available for running regular non huge page backed VMs. Since dynamic huge page allocation is not guaranteed, especially with 1GB huge pages, it is important to pre-allocate in the kernel command line a reasonable number, based on a typical workload. Alternatively, 2MB huge pages could be used since they are much easier to dynamically allocate. + +### CPU + +The DPDK PMD driver runs continuous polling threads to process network packets. These threads are assigned to dedicated CPUs from the operating system. By default, one thread per interface in a NUMA node is used. More threads means faster polling. + +After the configuration, regardless of whether there is traffic or not in the switch, the polling processes will be using these threads at 100% usage, so it is effectively removed from the system and the linux scheduler will not use those processes normally. + +For added security, you can use the isolcpus kernel parameter to declare those threads as not available to the linux scheduler, however the linux scheduler is mature enough to not need this. The important reservation comes in the OpenNebula scheduler. + +You must set the ISOCLPUS host parameter to prevent a case where the scheduler could pin VCPUs from VMs to those threads. + +### Deamon Configuration + +After having a clear picture of the resource allocation, it’s time to tell OVS about how to use them. + +First, make sure that the daemon is enabled: + +```shell +systemctl start openvswitch +systemctl enable openvswitch +``` + +Then initialize DPDK and signal the huge table mountpount: + +```shell +ovs-vsctl set Open_vSwitch . other_config:dpdk-init=true +ovs-vsctl set Open_vSwitch . other_config:dpdk-hugepage-dir="/dev/hugepages" +``` + +This mountpoint should be automatically managed by a system where libvirt is installed. It is an interface to consume the pages of the size specified in that mountpoint: + +```shell +mount | grep -i huge + hugetlbfs on /dev/hugepages type hugetlbfs + (rw,relatime,seclabel,pagesize=1024M) +``` +To assign the previously reserved huge pages to DPDK use the` other_config:dpdk-socket-mem` parameter. This is a comma separated list of memory, in MB, to allocate per node, which will then be backed by the huge pages available at `other_config:dpdk-hugepage-dir`. + +### Examples + +A system has 2 NUMA nodes. Two network interfaces are going to be used as DPDK interfaces. Each interface is in a different NUMA node. The interfaces will have 1500 MTU. 1GB hugepages are used. 2 pages are required in each node: + +```shell +ovs-vsctl set Open_vSwitch . other_config:dpdk-socket-mem=1024,1024 +``` + +A system has 1 NUMA node. Two network interfaces are going to be used as DPDK interfaces. The interfaces will have 9000 MTU. 1GB hugepages are used. 6 pages are required: + +```shell +ovs-vsctl set Open_vSwitch . other_config:dpdk-socket-mem=6144 +``` + +A system has 4 NUMA nodes. Two network interfaces are going to be used as DPDK interfaces. Interfaces are located in node0 and node1. The interfaces will have 9000 MTU. 1GB hugepages are used. 3 pages are required in node0 and node1 each.1 page is required in node2 and 3 each. + +```shell +ovs-vsctl set Open_vSwitch . other_config:dpdk-socket-mem=3072,3072,1024,1024 +``` + +### PMD Threads + +The CPU threads where OVS will pin the PMD threads are signaled with the parameter `other_config:pmd-cpu-mask`. It is a hex bitmask. Each bit represents a specific logical CPU ID. At least one CPU thread per node is needed. When assigning multiple threads per node, it is recommended to pick threads sharing the same physical CPU core. + +To generate the value of the bitmask: + +* Inspect the CPUs available in the Operating System. To get a full picture of this, run the command lscpu --all -p=CPU,CORE,NODE. +* This will yield a list of logical CPU threads ids, their respective parent logical core id and the NUMA node they belong to. +* Create a comma separated list of the CPU IDs going to be used according to recommendations. +* Create a binary bitmask with each desired CPU thread ID set to 1. +* Convert to hex. + +Example: + +```shell +lscpu --all -p=CPU,CORE,NODE + # The following is the parsable format, which can be fed to other + # programs. Each different item in every column has an unique ID + # starting usually from zero. + # CPU,Core,Node + 0,0,0 # pick + 1,1,1 # pick + 2,2,0 + ... +``` + +Core 0 in node 0 holds threads 0 and 64. Core 1 in node 1 holds threads 1 and 65. The string `0,1,64,65` should be used as the ISOLCPUS parameter in the hypervisor node configuration. + +```shell +echo "ISOLCPUS=\"0,1,64,65\"" > /tmp/dpdk-host.tpl +onehost update sm15 -a /tmp/dpdk-host.tpl +``` + +The subsequent mask is then applied: + +```shell +ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=0x30000000000000003 +``` + +Restart the openvswitch daemon so it loads all of the DPDK related configurations: + +```shell +systemctl restart openvswitch +``` + +### Verification + +Check OVS is properly configured. Make sure that DPDK is initialized and the configuration values we established for the OVS daemon are loaded: + +```shell +ovs-vsctl get Open_vSwitch . dpdk_initialized +grep DPDK /var/log/openvswitch/ovs-vswitchd.log +ovs-vsctl get Open_vSwitch . other_config:dpdk-socket-mem +ovs-vsctl get Open_vSwitch . other_config:pmd-cpu-mask +ovs-vsctl get Open_vSwitch . other_config:dpdk-hugepage-dir +``` + +### Bridge Creation + +The OVS DPDK bridge must be pre-created before being used in OpenNebula. Besides some extra configuration, most of the normal OVS bridge related configurations apply. There are two elements that distinguish a DPDK bridge from a regular bridge: accelerated datapath and the use of DPDK interfaces. + +A DPDK bridge is created as follows: + +```shell +ovs-vsctl --may-exist add-br 'ovsbr0' -- set Bridge 'ovsbr0' 'datapath_type=netdev' +``` + +Then the DPDK interfaces must be assigned to that bridge. Normally, those interfaces need to have their kernel driver unbound and use instead the `vfio-pci` driver used for passthrough. However, there are cases where the kernel driver must not be unbound. This is the case for the `MT27710 Family [ConnectX-4 Lx] 1015` Mellanox network interfaces using the `mlx5_core` driver. + +Refer to the PCI Device VFIO binding section for this procedure. Alternatively, use the utility `dpdk-devbind.py` provided by the DPDK related packages. It allows to rebind interfaces as well, without the use of `driverctl` and it also provides a summary of every PCI device related property. + +```shell +dpdk-devbind.py --status-dev net + + Network devices using DPDK-compatible driver + ============================================ + 0000:01:00.0 'BCM57416 NetXtreme-E Dual-Media 10G RDMA Ethernet Controller 16d8' numa_node=0 drv=vfio-pci unused=bnxt_en + 0000:01:00.1 'BCM57416 NetXtreme-E Dual-Media 10G RDMA Ethernet Controller 16d8' numa_node=0 drv=vfio-pci unused=bnxt_en + 0000:81:00.2 'MT27710 Family [ConnectX-4 Lx Virtual Function] 1016' numa_node=0 drv=vfio-pci unused=mlx5_core + ... +``` + +After the interface is ready, attach it to the bridge: + +```shell +ovs-vsctl add-port ovsbr0 dpdk0 -- set Interface dpdk0 \ +type=dpdk options:dpdk-devargs= # replace with the network interface PCI device address +``` + +In this case `dpdk0` was the name used for the interface and the port. This name is not important as the interface is referenced by its PCI address. vfio-pci bound interfaces do not even have names. What’s important is that the said name must be unique per interface. + +If using multiple interfaces in bond, first create the bond normally, then attach the interfaces to the bond port. For example: + +```shell +ovs-vsctl add-bond 'ovsbr0' 'bond0' 'dpdk0' 'dpdk1' 'bond_mode=balance-slb' \ + -- set Interface 'vmnic0' 'type=dpdk' \ + -- set Interface 'vmnic0' 'options:dpdk-devargs=0000:01:00.0' \ + -- set Interface 'vmnic0' 'mtu_request=9126' \ + -- set Interface 'vmnic1' 'type=dpdk' \ + -- set Interface 'vmnic1' 'options:dpdk-devargs=0000:01:00.1' \ + -- set Interface 'vmnic1' 'mtu_request=9126' \ +``` + +After binding interfaces you should now start seeing the PMD threads at 100% CPU usage. This is expected and will happen regardless of whether that bridge is serving traffic to VMs or not. + +If the DPDK interface holds an IP address which is needed, this IP address must be migrated to the OVS bridge internal interface. It has the same name as the bridge. This interface can be configured like regular system interfaces. We recommend setting all of the L2 related configuration in OVS directly and only manage the IP related configuration outside of OVS, you can use manual commands or the system network renderer for this. + +If the interface is a management interface then you must ensure a proper IP migration via a script since binding the network interface and submitting it to a bridge makes it lose connectivity. + +### Security Configuration + +Depending on your distro, it might be required to tune Selinux or AppArmor to allow proper OVS-QEMU interaction. + +When a VM is created, qemu creates a UNIX socket for each network interface backed by a DPDK capable bridge. OVS then attempts to connect to these sockets. Some operations involving VM states, like migrations and power cycles require qemu also to perform an unlink operation in the socket. + +Selinux or AppArmor can, at any given time block any of these operations. This is affected also by how the Operating System distributes the OVS binary. In the case of the Red Hat familiy, OVS runs with a dedicated user. In the case of the Debian family, OVS runs as root. This might cause issues with directory based permissions, depending on the location of the socket. These sockets, starting from OpenNebula 7.2.1+ are located at `/var/run/one/vhost-socks/`. + +Below is a reference of the configuration required for Selinux systems. If errors persist after creating VMs, check the system logs, especially the audit logs, for operations being blocked if you still see permission denied errors but permissions look correct: + +```shell +sudo chcon -t virt_var_run_t /var/run/one/vhost-socks/ + +TDIR=$(mktemp -d) +cat << 'EOF' > "$TDIR/dpdk_virt.te" +module dpdk_virt 1.0; +require { + type openvswitch_t; + type virt_var_run_t; + class dir { search getattr read open }; + class sock_file { write getattr append }; +} +allow openvswitch_t virt_var_run_t:dir { search getattr read open }; +allow openvswitch_t virt_var_run_t:sock_file { write getattr append }; +EOF + +checkmodule -M -m -o "$TDIR/dpdk_virt.mod" "$TDIR/dpdk_virt.te" +semodule_package -o "$TDIR/dpdk_virt.pp" -m "$TDIR/dpdk_virt.mod" +sudo semodule -i "$TDIR/dpdk_virt.pp" +rm -rf "$TDIR" +sudo setfacl -m u:openvswitch:rx /var/run/one/ +sudo setfacl -m u:openvswitch:rx /var/run/one/vhost-socks/ +sudo setfacl -d -m u:openvswitch:rwX /var/run/one/vhost-socks/ +``` + +Refer to the OpenvSwitch with DPDK section for the Virtual Network configuration and reference VM Templates. + +### Security Configuration + +You can use the [openvswitch role](https://github.com/OpenNebula/one-deploy/blob/dbbec90d80a0a6a7e598b9a55169b0050a8c7c9f/roles/openvswitch/README.md#L16) to automate all of the DPDK related configuration and standalone OVS complex configurations as well. + ## Using PCI Devices as Network Interfaces To use a PCI device as a network interface, set the `TYPE` attribute of the `PCI` element to `NIC`. Example: @@ -257,4 +516,4 @@ The interface should appear as a native PCI network adapter and be configured au ## Next Steps -If you have not yet configured the host for PCI passthrough, complete the **Host Configuration** guide. For NVIDIA GPUs, continue with the **NVIDIA GPU** guide. \ No newline at end of file +If you have not yet configured the host for PCI passthrough, complete the [Host Configuration Guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}). For NVIDIA GPUs, continue with the [NVIDIA GPU Guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough/" %}}). \ No newline at end of file diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough.md b/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough.md index 6cbe2fcec..0320f03c1 100644 --- a/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough.md @@ -11,9 +11,9 @@ weight: "5" ## Overview -This guide describes how to deploy NVIDIA GPUs using PCI passthrough technologies in OpenNebula. OpenNebula supports multiple NVIDIA GPU deployment models, including conventional PCI passthrough, NVIDIA vGPU, MIG-backed vGPU, and NVIDIA Grace platform virtualization. While these deployment models share the same scheduling and deployment workflow, each requires a different host configuration. +This guide describes how to deploy NVIDIA GPUs using PCI passthrough technologies in OpenNebula. OpenNebula supports multiple NVIDIA GPU deployment models, including conventional PCI passthrough, NVIDIA vGPU, MIG-backed vGPU, and NVIDIA Grace platform virtualization. While these deployment models share the same scheduling and deployment workflow, each requires a different Host configuration. -The generic PCI passthrough configuration, including IOMMU, VFIO, Huge Pages, PCI monitoring, and device discovery, is described in the [**Host Configuration**]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}) guide. This guide focuses exclusively on the NVIDIA-specific configuration and deployment procedures for each supported deployment model. +The generic PCI passthrough configuration, including IOMMU, VFIO, Huge Pages, PCI monitoring, and device discovery, is described in the [Host Configuration Guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}). This guide focuses exclusively on the NVIDIA-specific configuration and deployment procedures for each supported deployment model. ## Deployment Models @@ -25,9 +25,9 @@ NVIDIA GPUs can be deployed in OpenNebula using one of the following deployment | NVIDIA vGPU / MIG-backed vGPU | A100, H100, H200, B200 | NVIDIA vGPU stack | NVIDIA vGPU or MIG-backed vGPU configuration | | Grace Platform Virtualization | GH200, GB200 | `nvgrace_gpu_vfio_pci` | Grace-specific virtualization configuration | -For **conventional PCI passthrough**, the NVIDIA driver is **not required** on the host. The GPU is owned exclusively by the guest operating system, where the NVIDIA driver is installed after deployment. +For **conventional PCI passthrough**, the NVIDIA driver is **not required** on the Host. The GPU is owned exclusively by the guest operating system, where the NVIDIA driver is installed after deployment. -For **NVIDIA vGPU** and **MIG-backed vGPU**, the NVIDIA driver is required on the host because the host manages GPU partitioning and virtual GPU creation before assigning GPU resources to virtual machines. +For **NVIDIA vGPU** and **MIG-backed vGPU**, the NVIDIA driver is required on the Host because the Host manages GPU partitioning and virtual GPU creation before assigning GPU resources to Virtual Machines. --- @@ -35,15 +35,15 @@ For **NVIDIA vGPU** and **MIG-backed vGPU**, the NVIDIA driver is required on th ## Overview -Conventional PCI passthrough assigns one or more physical NVIDIA GPUs directly to a virtual machine, providing the guest operating system with exclusive access to the assigned devices. In this deployment model, the host does not use the GPUs, which are instead bound to the `vfio-pci` driver and managed entirely by the guest operating system. +Conventional PCI passthrough assigns one or more physical NVIDIA GPUs directly to a Virtual Machine, providing the guest operating system with exclusive access to the assigned devices. In this deployment model, the Host does not use the GPUs, which are instead bound to the `vfio-pci` driver and managed entirely by the guest operating system. This deployment model is recommended for workloads requiring direct access to the GPU, such as AI training and inference, high-performance computing (HPC), scientific computing, visualization, and CUDA development. It is supported by NVIDIA PCIe and SXM GPUs, including NVIDIA H100, H200, L40, L40S, RTX, and A100 GPUs when Multi-Instance GPU (MIG) is not enabled. ## Requirements -Before deploying NVIDIA GPUs using conventional PCI passthrough, complete the generic PCI passthrough configuration described in the **Host Configuration** guide. +Before deploying NVIDIA GPUs using conventional PCI passthrough, complete the generic PCI passthrough configuration described in the [Host Configuration Guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}). -Verify that the host satisfies the following requirements: +Verify that the Host satisfies the following requirements: * Hardware-assisted virtualization and the IOMMU are enabled. * The GPU is bound to the `vfio-pci` driver. @@ -75,13 +75,13 @@ onehost show The GPUs should appear in the **PCI Devices** section and be available for scheduling. {{< alert title="Note" type="primary" >}} -Unlike NVIDIA vGPU or MIG-backed vGPU deployments, the NVIDIA driver is not required on the host for conventional PCI passthrough. The GPU is owned exclusively by the guest operating system, where the NVIDIA driver is installed after deployment.{{< /alert >}} +Unlike NVIDIA vGPU or MIG-backed vGPU deployments, the NVIDIA driver is not required on the Host for conventional PCI passthrough. The GPU is owned exclusively by the guest operating system, where the NVIDIA driver is installed after deployment.{{< /alert >}} --- ## Host Configuration -This section describes the NVIDIA-specific configuration required after completing the generic PCI passthrough configuration. If the NVIDIA driver is installed on the host, prevent it from binding to GPUs intended for passthrough by blacklisting the NVIDIA kernel modules. +This section describes the NVIDIA-specific configuration required after completing the generic PCI passthrough configuration. If the NVIDIA driver is installed on the Host, prevent it from binding to GPUs intended for passthrough by blacklisting the NVIDIA kernel modules. Create the following configuration file: @@ -99,10 +99,10 @@ blacklist nvidia_modeset blacklist nvidia_uvm ``` -Regenerate the initramfs using the appropriate command for your Linux distribution and reboot the host. +Regenerate the initramfs using the appropriate command for your Linux distribution and reboot the Host. {{< alert title="Note" type="primary" >}} -This step is only required if the NVIDIA driver is installed on the host. Hosts dedicated to GPU PCI passthrough typically do not require the NVIDIA driver.{{< /alert >}} +This step is only required if the NVIDIA driver is installed on the Host. Hosts dedicated to GPU PCI passthrough typically do not require the NVIDIA driver.{{< /alert >}} ### Verify the GPU Driver @@ -122,10 +122,10 @@ Example output: Kernel driver in use: vfio-pci ``` -If any GPU function is still managed by the NVIDIA or Nouveau driver, review the VFIO configuration described in the **Host Configuration** guide. +If any GPU function is still managed by the NVIDIA or Nouveau driver, review the VFIO configuration described in the [Host Configuration Guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}). {{< alert title="Note" type="primary" >}} -NVIDIA GPUs may expose multiple PCI functions, such as audio or USB controllers. All functions belonging to the GPU should be assigned together to the same virtual machine.{{< /alert >}} +NVIDIA GPUs may expose multiple PCI functions, such as audio or USB controllers. All functions belonging to the GPU should be assigned together to the same Virtual Machine.{{< /alert >}} ### Verify GPU Discovery @@ -137,7 +137,7 @@ onehost show Example output: -``` +```default PCI DEVICES VM ADDR TYPE NAME @@ -148,13 +148,11 @@ The GPUs should appear in the **PCI Devices** section and be available for sched Alternatively, the detected PCI devices can be inspected from the **PCI Devices** tab in Sunstone. ---- - ## Deploying a Virtual Machine -After the host has been configured and the GPUs have been discovered by OpenNebula, they can be assigned to virtual machines using the standard `PCI` attribute in the Virtual Machine Template. +After the Host has been configured and the GPUs have been discovered by OpenNebula, they can be assigned to Virtual Machines using the standard `PCI` attribute in the Virtual Machine Template. -OpenNebula supports both automatic and explicit GPU selection. Automatic selection is recommended because it allows the scheduler to place workloads on any compatible host, improving workload portability and resource utilization. +OpenNebula supports both automatic and explicit GPU selection. Automatic selection is recommended because it allows the scheduler to place workloads on any compatible Host, improving workload portability and resource utilization. ### Automatic GPU Selection @@ -167,7 +165,7 @@ PCI = [ ] ``` -During deployment, OpenNebula selects a compatible GPU that matches the requested attributes and assigns it to the virtual machine. +During deployment, OpenNebula selects a compatible GPU that matches the requested attributes and assigns it to the Virtual Machine. Additional `PCI` attributes, such as `DEVICE` or `SHORT_ADDRESS`, can be used to further restrict device selection when required. @@ -187,7 +185,7 @@ Explicit device selection should be reserved for specialized deployments. In mos ### Assigning Multiple GPUs -Multiple GPUs can be assigned to the same virtual machine by including multiple `PCI` sections. +Multiple GPUs can be assigned to the same Virtual Machine by including multiple `PCI` sections. The following example requests two NVIDIA GPUs: @@ -203,7 +201,7 @@ PCI = [ ] ``` -Each `PCI` section requests one compatible GPU. During deployment, OpenNebula assigns the requested number of devices to the virtual machine. +Each `PCI` section requests one compatible GPU. During deployment, OpenNebula assigns the requested number of devices to the Virtual Machine. --- @@ -260,20 +258,15 @@ FEATURES = [ PCI = [ SHORT_ADDRESS = "1b:00.0" ] PCI = [ SHORT_ADDRESS = "43:00.0" ] PCI = [ SHORT_ADDRESS = "52:00.0" ] -PCI = [ SHORT_ADDRESS = "61:00.0" ] -PCI = [ SHORT_ADDRESS = "9d:00.0" ] -PCI = [ SHORT_ADDRESS = "c3:00.0" ] -PCI = [ SHORT_ADDRESS = "d1:00.0" ] PCI = [ SHORT_ADDRESS = "df:00.0" ] ``` -The `PCI` entries assign the eight H100 GPUs to the virtual machine. +The `PCI` entries assign the eight H100 GPUs to the Virtual Machine. ---- ## Guest Configuration -After the virtual machine has been deployed, verify that the GPUs are visible inside the guest: +After the Virtual Machine has been deployed, verify that the GPUs are visible inside the guest: ```shell lspci | grep -i nvidia @@ -281,14 +274,10 @@ lspci | grep -i nvidia Example output: -``` +```default 23:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] 24:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] -25:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] -26:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] -43:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] -44:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] -45:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] +... 46:00.0 3D controller: NVIDIA Corporation GH100 [H100 SXM5 80GB] ``` @@ -306,25 +295,25 @@ Use the output provided in the NVIDIA qualification guide for your platform to v ### Overview -NVIDIA vGPU enables multiple virtual machines to share the resources of a physical GPU by exposing one or more virtual GPU (vGPU) profiles that can be independently assigned to guest operating systems. +NVIDIA vGPU enables multiple Virtual Machines to share the resources of a physical GPU by exposing one or more virtual GPU (vGPU) profiles that can be independently assigned to guest operating systems. Depending on the GPU generation, vGPU profiles can be created using one of two deployment models: * **NVIDIA vGPU**, where virtual GPU profiles are created directly by the NVIDIA AI Enterprise software stack. * **MIG-backed vGPU**, where the GPU is first partitioned using NVIDIA Multi-Instance GPU (MIG), and one or more vGPU profiles are created from the resulting GPU Instances. -Regardless of how the profiles are created, OpenNebula automatically discovers the available vGPU profiles during host monitoring and schedules them as GPU resources that can be assigned to virtual machines. +Regardless of how the profiles are created, OpenNebula automatically discovers the available vGPU profiles during Host monitoring and schedules them as GPU resources that can be assigned to Virtual Machines. -Before deploying NVIDIA vGPU devices, complete the generic PCI passthrough configuration described in the **Host Configuration** guide. +Before deploying NVIDIA vGPU devices, complete the generic PCI passthrough configuration described in the [Host Configuration Guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}). --- ## Requirements -Before continuing, verify that the host satisfies the following requirements: +Before continuing, verify that the Host satisfies the following requirements: * A supported NVIDIA GPU is installed. -* The NVIDIA host driver is installed and operational. +* The NVIDIA Host driver is installed and operational. * PCI monitoring is configured. * The GPU has been discovered by OpenNebula. @@ -342,8 +331,6 @@ onehost show The GPU should appear in the **PCI Devices** section. ---- - ### Host Configuration Depending on the GPU model, configure either **NVIDIA vGPU** or **MIG-backed vGPU**. @@ -404,8 +391,6 @@ MIG Mode Some GPU models require a reboot before MIG mode becomes active. ---- - ### Display Available GPU Instance Profiles Display the supported GPU Instance profiles: @@ -473,7 +458,7 @@ nvidia-smi vgpu -s -v ### Refresh OpenNebula Monitoring -Once the GPU configuration has been completed, refresh host monitoring: +Once the GPU configuration has been completed, refresh Host monitoring: ```shell onehost forceupdate @@ -491,7 +476,7 @@ The configured profiles should appear in the **PCI Devices** section and be avai ### Deploying a Virtual Machine -Virtual machines request NVIDIA vGPU resources by selecting one of the vGPU profiles discovered during host monitoring. +Virtual machines request NVIDIA vGPU resources by selecting one of the vGPU profiles discovered during Host monitoring. The available profiles can be inspected from the **PCI Devices** tab in Sunstone or using: @@ -505,7 +490,7 @@ Each discovered profile reports the profile name together with the number of ava **Example Virtual Machine Template** -Virtual machines request NVIDIA vGPU resources using the `PCI` attribute. The `PROFILE` attribute must match one of the profiles discovered during host monitoring. +Virtual machines request NVIDIA vGPU resources using the `PCI` attribute. The `PROFILE` attribute must match one of the profiles discovered during Host monitoring. The following example requests an NVIDIA L40S-2B vGPU profile: @@ -518,15 +503,13 @@ PCI = [ ] ``` -When the virtual machine is deployed, OpenNebula allocates a compatible GPU exposing the requested profile. +When the Virtual Machine is deployed, OpenNebula allocates a compatible GPU exposing the requested profile. -For MIG-backed vGPU deployments, the deployment workflow is identical. The available profiles are generated from the configured GPU Instances and automatically discovered during host monitoring. - ---- +For MIG-backed vGPU deployments, the deployment workflow is identical. The available profiles are generated from the configured GPU Instances and automatically discovered during Host monitoring. ### Guest Configuration -After the virtual machine has been deployed, install the NVIDIA guest driver corresponding to the selected NVIDIA vGPU software release. +After the Virtual Machine has been deployed, install the NVIDIA guest driver corresponding to the selected NVIDIA vGPU software release. Refer to the NVIDIA AI Enterprise documentation or your Linux distribution for instructions on installing the appropriate guest driver. @@ -542,4 +525,248 @@ Use the output provided by the NVIDIA vGPU software stack for your selected prof * the reported GPU name matches the selected vGPU profile; * no driver or hardware errors are reported. -The guest configuration is identical for conventional NVIDIA vGPU and MIG-backed vGPU deployments. Once deployed, the guest operating system interacts with the assigned virtual GPU transparently, regardless of how the profile was created. \ No newline at end of file +The guest configuration is identical for conventional NVIDIA vGPU and MIG-backed vGPU deployments. Once deployed, the guest operating system interacts with the assigned virtual GPU transparently, regardless of how the profile was created. + +--- + +## NVIDIA Grace Platforms (AE) + +### Overview + +NVIDIA Grace Hopper and Grace Blackwell platforms are based on the Arm architecture and implement a virtualization model that differs from conventional x86 PCI passthrough systems. In addition to assigning GPUs to Virtual Machines, Grace platforms require a specific PCI topology based on dedicated PCI Root Complexes, SMMUv3 devices, IOMMUFD, and ACPI Generic Initiator NUMA nodes. + +OpenNebula automates the creation of this virtual hardware topology during deployment. From the administrator's perspective, GPU assignment uses the standard `PCI` attribute while OpenNebula generates the libvirt configuration required by the Grace virtualization architecture. + +### Requirements + +Before configuring Grace platform virtualization, ensure that the Host has already been configured following the [Host Configuration Guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}). + +In addition, verify that the Host satisfies the following Grace-specific requirements: + +* A Linux kernel supporting NVIDIA Grace virtualization. +* NVIDIA QEMU and libvirt packages with Grace virtualization support. +* QEMU configured with `CAP_IPC_LOCK`. +* GPUs bound to the `nvgrace_gpu_vfio_pci` driver. + +The installation and configuration of the virtualization software stack is outside the scope of this guide. Refer to the NVIDIA Grace Virtualization documentation for platform-specific installation instructions. + +### Host Configuration + +Only the Grace-specific configuration required after completing the generic Host configuration is described in this section. + +#### Configure QEMU Memory Locking + +Grace platforms require QEMU to lock large GPU memory mappings. + +Grant the `CAP_IPC_LOCK` capability to the QEMU binary: + +```shell +sudo setcap cap_ipc_lock=ep /usr/bin/qemu-system-aarch64 +``` + +Verify the capability: + +```shell +getcap /usr/bin/qemu-system-aarch64 +``` + +The capability must be restored whenever the QEMU binary is replaced during a package upgrade. + +#### Bind GPUs to the Grace VFIO Driver + +Load the Grace VFIO driver: + +```shell +sudo modprobe nvgrace-gpu-vfio-pci +``` + +Register the NVIDIA GB200 device ID with the driver: + +```shell +echo "10de 2941" | sudo tee /sys/bus/pci/drivers/nvgrace_gpu_vfio_pci/new_id +``` + +Verify that the GPUs are bound to the `nvgrace_gpu_vfio_pci` driver: + +```shell +lspci -nnkk | grep -i 3D -A2 +``` + +Example output: + +```default +0008:01:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2941] (rev a1) + Subsystem: NVIDIA Corporation Device [10de:2046] + Kernel driver in use: nvgrace_gpu_vfio_pci +-- +0009:01:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2941] (rev a1) + Subsystem: NVIDIA Corporation Device [10de:2046] + Kernel driver in use: nvgrace_gpu_vfio_pci +-- +0019:01:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2046] + Kernel driver in use: nvgrace_gpu_vfio_pci +``` +#### Deploying a Virtual Machine + +Grace platform Virtual Machines are deployed using the standard OpenNebula `PCI` attribute together with the CPU and NUMA configuration required by the workload. + +The following example shows the relevant sections of a Virtual Machine Template configured with two Grace CPU NUMA nodes and four NVIDIA GB200 GPUs. + +```default +TOPOLOGY = [ + SOCKETS = "2", + CORES = "72", + THREADS = "1", + PIN_POLICY = "THREAD", + MEMORY_ACCESS = "shared", + HUGEPAGE_SIZE = "512" +] + +NUMA_NODE = [ + MEMORY = "192000", + TOTAL_CPUS = "72", + DISTANCE = "2-17:254" +] + +NUMA_NODE = [ + MEMORY = "192000", + TOTAL_CPUS = "72", + DISTANCE = "2-17:254" +] + +PCI=[ + ACPI_NODES="2-9", + CLASS="0302", + DEVICE="2941", + IOMMU="YES", + IOMMUFD="YES", + ROOT="dedicated", + VENDOR="10de" +] + +PCI=[ + ACPI_NODES="10-17", + CLASS="0302", + ... + +FEATURES=[ + ACPI="yes", + APIC="yes", + GIC="3", + PCIHOLE64="4294967296", + RAS="yes" +] + +IOMMU=[ + MODE="device", + MODEL="smmuv3", + OPTIONS="accel=on ats=on ril=off pasid=on oas=48" +] +``` + +The `PCI` attributes request two NVIDIA GB200 GPUs using dedicated PCI Root Complexes and dedicated IOMMU contexts. + +During deployment, OpenNebula automatically generates the Grace virtualization topology required by the guest, including: + +* PCI Root Complexes and PCI Root Ports. +* Virtual SMMUv3 devices. +* IOMMUFD objects. +* ACPI Generic Initiator NUMA nodes. +* Guest NUMA topology. +* NUMA distance matrices. + +This topology follows the NVIDIA Grace virtualization architecture and preserves CPU and GPU NUMA locality. + +{{< alert title="Note" type="primary" >}} +When using automatic GPU selection, OpenNebula computes the required `ACPI_NODES` assignment automatically. Explicit `ACPI_NODES` values are only required when selecting specific devices and defining a fixed virtual topology.{{< /alert >}} + +### Guest Configuration + +Install the NVIDIA data center driver inside the guest operating system following the NVIDIA documentation. + +After installation, the GPUs are exposed as native Grace devices and CUDA applications require no additional configuration. + +A correctly configured guest exposes: + +* The configured CPU NUMA nodes. +* Eight ACPI Generic Initiator NUMA nodes for each assigned GPU. +* Preserved NVLink connectivity. +* GPU affinity matching the physical Grace topology. + +The NUMA topology can be inspected using: + +```shell +numactl -H +``` + +Example output: + +``` +available: 32 nodes (0-4,6-7,9-33) + +node 0 cpus: 0-71 +node 0 size: 191674 MB + +node 1 cpus: 72-143 +node 1 size: 191741 MB + +... + +node distances: +node 0 1 2 3 4 ... +0: 10 20 254 254 254 ... +1: 20 10 254 254 254 ... +2: 254 254 10 20 20 ... +... +``` + +This topology reflects the virtual hardware generated by OpenNebula. NUMA nodes 0 and 1 correspond to the Grace CPU memory domains, while the remaining nodes represent the ACPI Generic Initiator nodes associated with the assigned GPUs. + +Verify that the GPUs are visible inside the guest: + +```shell +nvidia-smi +``` + +Example output: + +```default ++-----------------------------------------------------------------+ +| NVIDIA-SMI 595.71.05 Driver Version: 595.71.05 | +| CUDA Version: 13.2 | ++-----------------------------------------------------------------+ +| GPU Name Persistence-M | Bus-Id Disp.A | Vol ECC | +| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU Compute | +| | | MIG M | +|=============================+=====================+=============| +| 0 NVIDIA GB200 Off | 00000000:A1:00.0 Off | 0 | +| N/A 38C P0 163W/1200W | 0MiB / 189471MiB | 0% Def | +| | | Disabled | ++-----------------------------+------------------------+----------+ +| 3 NVIDIA GB200 Off | 00000000:B9:00.0 Off | 0 | +| N/A 38C P0 221W/1200W | 0MiB / 189471MiB | 0% Def | +| | | Disabled | ++-----------------------------+------------------------+----------+ +``` + +Inspect the GPU topology: + +```shell +nvidia-smi topo -m +``` + +Example output: + +```default + GPU0 GPU1 GPU2 GPU3 CPU Affinity NUMA Affinity GPU NUMA ID +GPU0 X NV18 NV18 NV18 0-71 0 4 +GPU1 NV18 X NV18 NV18 0-71 0 3 +GPU2 NV18 NV18 X NV18 72-143 1 9 +GPU3 NV18 NV18 NV18 X 72-143 1 2 +``` + +This output confirms that: + +* The GPUs are correctly detected inside the guest +* NVLink connectivity is preserved +* GPU affinity matches the corresponding CPU NUMA node and the virtual topology generated by OpenNebula reproduces the physical Grace platform topology. diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_grace_platform.md b/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_grace_platform.md index 6b1ee5afc..9d884a998 100644 --- a/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_grace_platform.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/nvidia_grace_platform.md @@ -7,6 +7,7 @@ categories: pageintoc: "58" tags: ['AI','NVIDIA'] weight: "9" +toc_hide: true --- ## Overview @@ -15,15 +16,11 @@ NVIDIA Grace Hopper and Grace Blackwell platforms implement a virtualization arc OpenNebula automates the creation of this virtual hardware topology during deployment. From the administrator's perspective, GPU assignment uses the standard `PCI` attribute while OpenNebula generates the libvirt configuration required by the Grace virtualization architecture. -Before deploying GPUs on Grace platforms, complete the generic PCI passthrough configuration described in the **Host Configuration** guide. - ---- - ### Requirements -Before configuring Grace platform virtualization, ensure that the host has already been configured following the **Host Configuration** guide. +Before configuring Grace platform virtualization, ensure that the Host has already been configured following the [Host Configuration Guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}). -In addition, verify that the host satisfies the following Grace-specific requirements: +In addition, verify that the Host satisfies the following Grace-specific requirements: * A Linux kernel supporting NVIDIA Grace virtualization. * NVIDIA QEMU and libvirt packages with Grace virtualization support. @@ -34,7 +31,7 @@ The installation and configuration of the virtualization software stack is outsi ### Host Configuration -Only the Grace-specific configuration required after completing the generic host configuration is described in this section. +Only the Grace-specific configuration required after completing the generic Host configuration is described in this section. ### Configure QEMU Memory Locking diff --git a/content/product/cluster_configuration/pci_passthrough_sriov/overview.md b/content/product/cluster_configuration/pci_passthrough_sriov/overview.md index 3abb3e726..2470b80f5 100644 --- a/content/product/cluster_configuration/pci_passthrough_sriov/overview.md +++ b/content/product/cluster_configuration/pci_passthrough_sriov/overview.md @@ -18,9 +18,9 @@ This guide introduces the PCI passthrough architecture in OpenNebula and provide A PCI passthrough deployment relies on coordinated hardware and software support. Modern processors provide an Input-Output Memory Management Unit (IOMMU), such as Intel VT-d, AMD-Vi, or Arm SMMUv3, to safely map device access to guest memory. The Linux kernel exposes this capability through the VFIO framework, allowing libvirt and QEMU to securely assign physical PCI devices directly to virtual machines. -OpenNebula manages this process by discovering available PCI devices on each host, exposing them as host resources that can be scheduled for virtual machines, selecting suitable hosts during scheduling, and generating the appropriate virtualization configuration as part of its integrated scheduling, monitoring, and virtual machine management infrastructure. +OpenNebula manages this process by discovering available PCI devices on each Host, exposing them as Host resources that can be scheduled for virtual machines, selecting suitable Hosts during scheduling, and generating the appropriate virtualization configuration as part of its integrated scheduling, monitoring, and virtual machine management infrastructure. -OpenNebula abstracts this complexity and allows administrators to manage PCI devices using standard host and virtual machine templates. +OpenNebula abstracts this complexity and allows administrators to manage PCI devices using standard Host and virtual machine templates. ## Supported Device Types @@ -33,8 +33,8 @@ OpenNebula supports assigning a wide variety of PCI devices to virtual machines. OpenNebula manages PCI devices throughout their lifecycle, allowing administrators to manage PCI devices using the same workflow as other OpenNebula resources: -1. **Host Discovery**: The monitoring subsystem automatically discovers PCI devices available on each virtualization host and collects information such as vendor, device identifiers, class, NUMA locality, and virtualization capabilities. -2. **Device Scheduling**: PCI devices become schedulable host resources. During deployment, the scheduler selects a host satisfying both the virtual machine requirements and the requested PCI devices. +1. **Host Discovery**: The monitoring subsystem automatically discovers PCI devices available on each virtualization Host and collects information such as vendor, device identifiers, class, NUMA locality, and virtualization capabilities. +2. **Device Scheduling**: PCI devices become schedulable Host resources. During deployment, the scheduler selects a Host satisfying both the virtual machine requirements and the requested PCI devices. 3. **Virtual Machine Deployment**: When a virtual machine is deployed, OpenNebula generates the corresponding libvirt domain configuration, attaches the requested PCI devices, configures the required virtual PCI topology, and enables additional virtualization features when required by the hardware platform. * The PCI device can also be configured in the VM post VM deployment. Network interfaces can be hot-plugged. 4. **Device Release**: When the virtual machine is terminated, the PCI devices are automatically released and become available for future deployments. @@ -63,14 +63,16 @@ The PCI passthrough documentation is organized into the following guides: | **Guide** | **Description** | |-------|-------------| -| [Host Configuration]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}) | Configure virtualization hosts for PCI passthrough, including IOMMU, VFIO, Huge Pages, SR-IOV, and other common host requirements. | +| [Host Configuration]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}) | Configure virtualization Hosts for PCI passthrough, including IOMMU, VFIO, Huge Pages, SR-IOV, and other common Host requirements. | | [Network Interfaces]({{% relref "product/cluster_configuration/pci_passthrough_sriov/network_interfaces/" %}}) | Configure PCI passthrough and SR-IOV for network adapters. | | [Device Passthrough]({{% relref "product/cluster_configuration/pci_passthrough_sriov/pci_passthrough/" %}}) | Configure the passthrough configuration of a given device. | | [NVIDIA GPUs]({{% relref "product/cluster_configuration/pci_passthrough_sriov/nvidia_gpu_passthrough/" %}}) | Configure NVIDIA GPUs for passthrough and vGPU deployments, including platform-specific features such as Grace and Grace Blackwell. | +| [AMD GPUs]({{% relref "product/cluster_configuration/pci_passthrough_sriov/amd_gpu_passthrough/" %}}) | Configure AMD GPUs for passthrough. | +| [Axelera GPUs]({{% relref "product/cluster_configuration/pci_passthrough_sriov/axelera_gpu_passthrough/" %}}) | Configure Axelera GPUs for passthrough. | | [NVIDIA Fabric Manager]({{% relref "product/cluster_configuration/pci_passthrough_sriov/one_fabricmanager/" %}}) | Configure NVIDIA Fabric Manager for supported GPU platforms. | ## Next Steps -Before assigning PCI devices to virtual machines, configure the virtualization hosts by following the [Host Configuration guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}). +Before assigning PCI devices to Virtual Machines, configure the virtualization Hosts by following the [Host Configuration guide]({{% relref "product/cluster_configuration/pci_passthrough_sriov/host_configuration/" %}}). Additional configuration required for specific device types is described in the corresponding device-specific guides. From 3facbae79af842536590d7850538c286c163f7f2 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Wed, 1 Jul 2026 18:20:11 +0200 Subject: [PATCH 04/38] F OpenNebula/one#7615: Documentation of DISK_IDs selection for backups --- .../backup_system/restic.md | 2 +- .../infrastructure_drivers_development/sd.md | 6 +-- .../system_interfaces/api.md | 6 ++- .../hypervisor_configuration/kvm_driver.md | 2 +- .../guest_operating_systems/os_profile.md | 1 + .../virtual_machine_backups/backup_jobs.md | 2 + .../virtual_machine_backups/operations.md | 46 +++++++++++++++++++ .../virtual_machines/vm_instances.md | 4 +- .../release_notes/whats_new.md | 3 +- 9 files changed, 63 insertions(+), 9 deletions(-) diff --git a/content/product/cluster_configuration/backup_system/restic.md b/content/product/cluster_configuration/backup_system/restic.md index 0c14d7636..a67e3fa2b 100644 --- a/content/product/cluster_configuration/backup_system/restic.md +++ b/content/product/cluster_configuration/backup_system/restic.md @@ -18,7 +18,7 @@ weight: "2" In both the Enterprise and Community editions of OpenNebula, the correct version of restic is included as a dependency. In this guide we will use the following terminology (introduced by restic): - *Repository*: This is the storage volume where the disk images backups will be stored. Restic creates a specific interval structure to store the backups efficiently. The restic driver accesses the repository through the sftp. protocol. OpenNebula will create a separate restic repository for each VM or backup job. -- *Snapshot*: It represents a backup and it is referenced by an unique hash (e.g., `eda52f34`). Each snapshot stores a VM backup and includes all of its disks and the metadata description of the VM at the time you make the backup. +- *Snapshot*: It represents a backup and it is referenced by a unique hash (e.g., `eda52f34`). Each snapshot stores a VM backup and includes the backed up disks and the metadata description of the VM at the time you make the backup. - *Backup Server*: A Host that will store the VM backups and the restic repositories. ## Step 1. [Backup Server] Set up the backup server diff --git a/content/product/integration_references/infrastructure_drivers_development/sd.md b/content/product/integration_references/infrastructure_drivers_development/sd.md index 38c8747e0..de30503e6 100644 --- a/content/product/integration_references/infrastructure_drivers_development/sd.md +++ b/content/product/integration_references/infrastructure_drivers_development/sd.md @@ -102,7 +102,7 @@ The backup datastore drivers are responsible for storing the generate `backup` f - **ARGUMENTS**: `host:remote_system_ds disks deploy_id vm_id ds_id` - `remote_system_ds_dir` is the path for the VM directory in the system datastore in the Host - `host` is the target Host where the VM is running - - `disks` List (‘:’ separated) of disk_ids of disks that needs backup (e.g., “0:1:”) + - `disks` List (‘:’ separated) of disk IDs that need backup (e.g., “0:1:”). This list is already filtered by `BACKUP_CONFIG/DISK_IDS` and disk eligibility. - `deploy_id` ID of the VM in the hypervisor - `backupjob_id` if defined ‘-’ otherwise - `vm_id` is the id of the VM @@ -293,7 +293,7 @@ VM = [ ID = ${vm_id}, MONITOR = "\ - **ARGUMENTS**: `host:remote_system_ds disks deploy_id vm_id ds_id` - `remote_system_ds_dir` is the path for the VM directory in the system datastore in the Host - `host` is the target Host where the VM is running - - `disks` List (‘:’ separated) of disk_ids of disks that needs backup (e.g. “0:1:”) + - `disks` List (‘:’ separated) of disk IDs that need backup (e.g. “0:1:”). This list is already filtered by `BACKUP_CONFIG/DISK_IDS` and disk eligibility. - `deploy_id` ID of the VM in the hypervisor - `backupjob_id` is the id of the Backup job (‘-’ if undefined) - `vm_id` is the id of the VM @@ -302,7 +302,7 @@ VM = [ ID = ${vm_id}, MONITOR = "\ - **ARGUMENTS**: `host:remote_system_ds disks deploy_id vm_id ds_id` - `remote_system_ds_dir` is the path for the VM directory in the system datastore in the Host - `host` is the target Host where the VM is running - - `disks` List (‘:’ separated) of disk_ids of disks that needs backup (e.g. “0:1:”) + - `disks` List (‘:’ separated) of disk IDs that need backup (e.g. “0:1:”). This list is already filtered by `BACKUP_CONFIG/DISK_IDS` and disk eligibility. - `deploy_id` ID of the VM in the hypervisor - `backupjob_id` is the id of the Backup job (‘-’ if undefined) - `vm_id` is the id of the VM diff --git a/content/product/integration_references/system_interfaces/api.md b/content/product/integration_references/system_interfaces/api.md index 07b181fd1..8c70727da 100644 --- a/content/product/integration_references/system_interfaces/api.md +++ b/content/product/integration_references/system_interfaces/api.md @@ -1163,7 +1163,7 @@ The supported attributes are: | `VIDEO` | `TYPE`, `IOMMU`, `ATS`, `VRAM`, `RESOLUTION` | | `RAW` | `DATA`, `DATA_VMX`, `TYPE`, `VALIDATE` | | `CONTEXT` | Any value, except `ETH*`. **Variable substitution will be made** | -| `BACKUP_CONFIG` | `FS_FREEZE`, `KEEP_LAST`, `BACKUP_VOLATILE`, `MODE`, `INCREMENT_MODE` | +| `BACKUP_CONFIG` | `FS_FREEZE`, `KEEP_LAST`, `BACKUP_VOLATILE`, `MODE`, `INCREMENT_MODE`, `DISK_IDS` | {{< alert title="Note" type="info" >}} Visit the [Virtual Machine Template reference]({{% relref "../../../product/operation_references/configuration_references/template#template" %}}) for a complete description of each attribute{{< /alert >}} @@ -1387,6 +1387,8 @@ For example: | OUT | Int/String | The VM ID / The error string. | | OUT | Int | Error code. | +For backups created with a selected disk list, only disks present in the backup image metadata can be restored. + ### one.vm.exec - **Description**: Executes a command inside a Virtual Machine. The VM needs to be in RUNNING state. @@ -3144,6 +3146,8 @@ The range can be used to retrieve a subset of the pool, from the ‘start’ to | OUT | Int | Error code. | | OUT | Int | ID of the object that caused the error. | +Backups created with a selected disk list cannot be restored as a full VM template. In this case `DISK_ID` is required, and the disk must be present in the backup image metadata. + ### one.imagepool.info - **Description**: Retrieves information for all or part of the images in the pool. diff --git a/content/product/operation_references/hypervisor_configuration/kvm_driver.md b/content/product/operation_references/hypervisor_configuration/kvm_driver.md index b0091afeb..9b7c7e57c 100644 --- a/content/product/operation_references/hypervisor_configuration/kvm_driver.md +++ b/content/product/operation_references/hypervisor_configuration/kvm_driver.md @@ -34,7 +34,7 @@ GRAPHICS = ["TYPE", "LISTEN", "PASSWD", "KEYMAP", "COMMAND" ] VIDEO = ["TYPE", "IOMMU", "ATS", "VRAM", "RESOLUTION"] RAW = ["DATA", "DATA_VMX", "TYPE", "VALIDATE"] CPU_MODEL = ["MODEL", "FEATURES"] -BACKUP_CONFIG = ["FS_FREEZE", "KEEP_LAST", "BACKUP_VOLATILE", "MODE", "INCREMENT_MODE"] +BACKUP_CONFIG = ["FS_FREEZE", "KEEP_LAST", "BACKUP_VOLATILE", "MODE", "INCREMENT_MODE", "DISK_IDS"] CONTEXT (any value, except ETH*, **variable substitution will be made**) ``` diff --git a/content/product/virtual_machines_operation/guest_operating_systems/os_profile.md b/content/product/virtual_machines_operation/guest_operating_systems/os_profile.md index 04edc65ec..f6a76bd8f 100644 --- a/content/product/virtual_machines_operation/guest_operating_systems/os_profile.md +++ b/content/product/virtual_machines_operation/guest_operating_systems/os_profile.md @@ -444,3 +444,4 @@ NICs are configured under `Network→NIC` and PCI devices under `Network→PCI`{ | →→ BACKUP_VOLATILE | string | Include volatile disks in backup | “Yes”, “No” | | →→ FS_FREEZE | string | Filesystem freeze method | “NONE”, “AGENT”, “SUSPEND” | | →→ KEEP_LAST | number | Number of backups to keep | Any positive integer | +| →→ DISK_IDS | string | Disk IDs to back up | Comma-separated disk IDs | diff --git a/content/product/virtual_machines_operation/virtual_machine_backups/backup_jobs.md b/content/product/virtual_machines_operation/virtual_machine_backups/backup_jobs.md index cdb478de9..a610d3398 100644 --- a/content/product/virtual_machines_operation/virtual_machine_backups/backup_jobs.md +++ b/content/product/virtual_machines_operation/virtual_machine_backups/backup_jobs.md @@ -59,6 +59,8 @@ INCREMENT_MODE = "SNAPSHOT" | `RESET` | Create a new backup image. Only for incremental backup | | [Attributes for Single Backup operations]({{% relref "operations#vm-backups-config-attributes" %}}) | | +You can use `DISK_IDS` to configure the Backup Job to back up only selected disks for each VM. The same disk IDs are applied to every VM included in the Backup Job, so each selected disk ID must be eligible for backup in every VM. For more information, see [Selecting Disks for Backup]({{% relref "operations#vm-backups-selected-disks" %}}). + ### Priority Setting {{< alert title="Note" type="info" >}} diff --git a/content/product/virtual_machines_operation/virtual_machine_backups/operations.md b/content/product/virtual_machines_operation/virtual_machine_backups/operations.md index 8f7220376..816976c2c 100644 --- a/content/product/virtual_machines_operation/virtual_machine_backups/operations.md +++ b/content/product/virtual_machines_operation/virtual_machine_backups/operations.md @@ -152,6 +152,51 @@ Sunstone will display the screen to update the VM Configuration. ![vm_cfg_tab](/images/backup_vm_configuration_tab.png) + + +### Selecting Disks for Backup + +By default, a VM backup includes all disks that are eligible for backup. You can restrict the backup to a subset of VM disks by setting the `DISK_IDS` attribute in `BACKUP_CONFIG`. + +The value is a comma-separated list of disk IDs from the VM `DISK` section. For example, to back up only disks `0` and `2`: + +```default +$ onevm updateconf 0 + +BACKUP_CONFIG = [ + DISK_IDS = "0,2" +] +... +``` + +You can clear `DISK_IDS` by setting it to an empty value. A missing or empty `DISK_IDS` attribute means that all eligible disks are included in the backup: + +```default +$ onevm updateconf 0 + +BACKUP_CONFIG = [ + DISK_IDS = "" +] +... +``` + +OpenNebula validates `DISK_IDS` when the backup configuration is updated. The value must contain valid non-negative integer disk IDs, and every disk ID must refer to a disk that can be backed up. Disks of type `SWAP`, `CDROM`, `RBD_CDROM`, and `FILESYSTEM` are not included in VM backups. Volatile `FS` disks are included only when `BACKUP_VOLATILE="YES"` is set. + +For incremental backups, the effective disk set is part of the incremental chain. Changing `DISK_IDS`, changing `BACKUP_VOLATILE` so that the effective disk set changes, or attaching or detaching an eligible disk when all disks are selected resets the incremental chain. The next backup creates a new full base for the new disk set. If a disk listed in `DISK_IDS` is detached, OpenNebula removes that disk ID from the backup configuration and resets the chain. + + + +#### Restoring Selected Disk Backups + +A backup that contains only selected disks cannot be restored as a complete VM, because it may not contain all disks needed to boot or reconstruct the original VM. To restore data from this type of backup, restore an individual disk that is part of the backup: + +```default +$ oneimage restore -d default --disk_id 2 176 +Image: 203 +``` + +The disk ID must be present in the backup image metadata. You can check the backed up disk IDs with `oneimage show`; they are listed in the `BACKUP_DISK_IDS` section. + ### Reference: Backup Configuration Attributes @@ -163,6 +208,7 @@ Sunstone will display the screen to update the VM Configuration. | `KEEP_LAST` | Only keep the last N backups (full backups or increments) for the VM (default: none) | | `MODE` | Backup type `FULL` (default) or `INCREMENT` | | `INCREMENT_MODE` | Incremental backup type `CBT` (default) or `SNAPSHOT` | +| `DISK_IDS` | Comma-separated list of disk IDs to back up. Empty or missing means all eligible disks | | `INTERACTIVE` | Enable the OneBEX interactive workflow for supported backup integrations (default: `NO`) | | `INCREMENTAL_BACKUP_ID` | For `INCREMENT` points to the backup image where increment chain is stored (read-only) | | `LAST_INCREMENT_ID` | For `INCREMENT` the ID of the last incremental backup taken (read-only) | diff --git a/content/product/virtual_machines_operation/virtual_machines/vm_instances.md b/content/product/virtual_machines_operation/virtual_machines/vm_instances.md index c5b4729ee..7fb476a31 100644 --- a/content/product/virtual_machines_operation/virtual_machines/vm_instances.md +++ b/content/product/virtual_machines_operation/virtual_machines/vm_instances.md @@ -489,7 +489,7 @@ Some of the VM configuration attributes defined in the VM template can be update | `VIDEO` | `TYPE`, `IOMMU`, `ATS`, `VRAM`, `RESOLUTION` | | `RAW` | `DATA`, `DATA_VMX`, `TYPE`, `VALIDATE` | | `CPU_MODEL` | `MODEL`, `FEATURES` | -| `BACKUP_CONFIG` | `FS_FREEZE`, `KEEP_LAST`, `BACKUP_VOLATILE`, `MODE`,
`INCREMENT_MODE` | +| `BACKUP_CONFIG` | `FS_FREEZE`, `KEEP_LAST`, `BACKUP_VOLATILE`, `MODE`,
`INCREMENT_MODE`, `DISK_IDS` | | `CONTEXT` | Any value, except `ETH*`. **Variable substitution will be made** | Visit the [Virtual Machine Template reference]({{% relref "product/operation_references/configuration_references/template#template" %}}) for a complete description of each attribute. Visit the [VM Update Methods Reference]({{% relref "product/operation_references/configuration_references/vm_update_methods/" %}}) for additional details on all available VM configuration update methods. @@ -1292,7 +1292,7 @@ The `onevm` command manages OpenNebula Virtual Machines. The general structure o | `unresched range\|vmid_list` | Clears the rescheduling flag for the VM. States: RUNNING, POWEROFF | | `update vmid [file]` | Updates the user template contents. If a path is not provided the editor will be launched to modify the current content. Valid options: append | | `update-chart vmid sched_id [file]` | Updates a charter from a VM. Deprecated command: use `sched-update` instead. | -| `updateconf vmid [file]` |
  • Updates the configuration of a VM.
  • This command accepts a template or opens an editor. A template can be passed as a file with or the content via STDIN. Bash symbols must be escaped on STDIN passing.
  • Valid states are: running, pending, failure, poweroff, undeploy, hold or cloning. In running state only changes in CONTEXT and BACKUP_CONFIG take effect immediately, other values may need a VM restart.
  • Configuration attributes include:
    • OS = ["ARCH", "MACHINE", "KERNEL", "INITRD", "BOOTLOADER", "BOOT", "KERNEL_CMD", "ROOT", "SD_DISK_BUS", "UUID", "FIRMWARE", "FIRMWARE_FORMAT"]
    • FEATURES = ["ACPI", "PAE", "APIC", "LOCALTIME", "HYPERV", "GUEST_AGENT", "VIRTIO_SCSI_QUEUES", "VIRTIO_BLK_QUEUES", "IOTHREADS"]
    • INPUT = ["TYPE", "BUS"]
    • GRAPHICS = ["TYPE", "LISTEN", "PASSWD", "KEYMAP", "COMMAND"]
    • VIDEO = ["TYPE", "IOMMU", "ATS", "VRAM", "RESOLUTION"]
    • RAW = ["DATA", "DATA_VMX", "TYPE", "VALIDATE"]
    • CPU_MODEL = ["MODEL", "FEATURES"]
    • BACKUP_CONFIG = ["FS_FREEZE", "KEEP_LAST", "BACKUP_VOLATILE", "MODE", "INCREMENT_MODE"]
    • CONTEXT (any value, ETH* if CONTEXT_ALLOW_ETH_UPDATES set in oned.conf, *variable substitution will be made*)
  • Valid options: append
| +| `updateconf vmid [file]` |
  • Updates the configuration of a VM.
  • This command accepts a template or opens an editor. A template can be passed as a file with or the content via STDIN. Bash symbols must be escaped on STDIN passing.
  • Valid states are: running, pending, failure, poweroff, undeploy, hold or cloning. In running state only changes in CONTEXT and BACKUP_CONFIG take effect immediately, other values may need a VM restart.
  • Configuration attributes include:
    • OS = ["ARCH", "MACHINE", "KERNEL", "INITRD", "BOOTLOADER", "BOOT", "KERNEL_CMD", "ROOT", "SD_DISK_BUS", "UUID", "FIRMWARE", "FIRMWARE_FORMAT"]
    • FEATURES = ["ACPI", "PAE", "APIC", "LOCALTIME", "HYPERV", "GUEST_AGENT", "VIRTIO_SCSI_QUEUES", "VIRTIO_BLK_QUEUES", "IOTHREADS"]
    • INPUT = ["TYPE", "BUS"]
    • GRAPHICS = ["TYPE", "LISTEN", "PASSWD", "KEYMAP", "COMMAND"]
    • VIDEO = ["TYPE", "IOMMU", "ATS", "VRAM", "RESOLUTION"]
    • RAW = ["DATA", "DATA_VMX", "TYPE", "VALIDATE"]
    • CPU_MODEL = ["MODEL", "FEATURES"]
    • BACKUP_CONFIG = ["FS_FREEZE", "KEEP_LAST", "BACKUP_VOLATILE", "MODE", "INCREMENT_MODE", "DISK_IDS"]
    • CONTEXT (any value, ETH* if CONTEXT_ALLOW_ETH_UPDATES set in oned.conf, *variable substitution will be made*)
  • Valid options: append
| | `vnc vmid` | Opens a VNC session to the VM. Valid options include: vnc| Back to The `onevm` Command diff --git a/content/software/release_information/release_notes/whats_new.md b/content/software/release_information/release_notes/whats_new.md index 6d9f4c5e6..50887274b 100644 --- a/content/software/release_information/release_notes/whats_new.md +++ b/content/software/release_information/release_notes/whats_new.md @@ -18,6 +18,7 @@ The OpenNebula team is excited to announce the availability of the **OpenNebula ## Storage & Backups * Added [interactive backup integration support]({{% relref "../../../product/integration_references/infrastructure_drivers_development/interactive_backup.md#interactive-backup-integration" %}}), enabling third-party backup integrations to pull full and CBT incremental `qcow2` VM backups directly from KVM hypervisors through the OpenNebula Backup Exporter (OneBEX). +* Added [selected disk backups]({{% relref "../../../product/virtual_machines_operation/virtual_machine_backups/operations#vm-backups-selected-disks" %}}), allowing VM backup configurations and Backup Jobs to back up only a defined subset of eligible VM disks. Selected-disk backups can be restored as [individual disks]({{% relref "../../../product/virtual_machines_operation/virtual_machine_backups/operations#vm-backups-selected-disks-restore" %}}). ## Networking @@ -61,4 +62,4 @@ Additionally, the following functionalities are present that were not in OpenNeb * [Fix VM CDROM hot-attach without target or dev-prefix](https://github.com/OpenNebula/one/issues/7736). * [Fix API commands executed on HA follower, for full list of commands the GitHub issue](https://github.com/OpenNebula/one/issues/7725). * [Fix VirtioFS filesystem image size reporting always `0`](https://github.com/OpenNebula/one/issues/7751). -* [Fix onehost failing on CLI-only installs due to an unconditional require of HostSyncManager](https://github.com/OpenNebula/one/issues/7768). \ No newline at end of file +* [Fix onehost failing on CLI-only installs due to an unconditional require of HostSyncManager](https://github.com/OpenNebula/one/issues/7768). From 7494ebb8d2ef2b42beb3f428a0e6ccb96cac7fc0 Mon Sep 17 00:00:00 2001 From: MarioRobres Date: Mon, 6 Jul 2026 10:35:39 +0200 Subject: [PATCH 05/38] F OpenNebula/one#7765: add OneBEX LVM exporter docs (#735) Modify docs to add LVM exporter support for interactive backups --- .../cluster_configuration/backup_system/veeam.md | 2 +- .../interactive_backup.md | 15 +++++++++------ .../infrastructure_drivers_development/sd.md | 4 ++-- .../virtual_machine_backups/operations.md | 7 ++++--- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/content/product/cluster_configuration/backup_system/veeam.md b/content/product/cluster_configuration/backup_system/veeam.md index 94c1aa37d..1175e4e17 100644 --- a/content/product/cluster_configuration/backup_system/veeam.md +++ b/content/product/cluster_configuration/backup_system/veeam.md @@ -31,7 +31,7 @@ The following table summarizes the supported backup modes for each storage syste | File (qcow2) | Yes | Yes | | File (raw) | No† | No† | | Ceph | No† | No† | -| LVM | No† | No† | +| LVM | Yes | Yes | | NetApp | No† | No† | These backup modes were supported in previous OpenNebula versions, such as 7.0 and 7.2. From OpenNebula version 7.4 onwards, they are not supported by the current OneBEX-based integration. diff --git a/content/product/integration_references/infrastructure_drivers_development/interactive_backup.md b/content/product/integration_references/infrastructure_drivers_development/interactive_backup.md index eb8a1997a..ddf22a903 100644 --- a/content/product/integration_references/infrastructure_drivers_development/interactive_backup.md +++ b/content/product/integration_references/infrastructure_drivers_development/interactive_backup.md @@ -39,11 +39,11 @@ The current interactive backup implementation supports the following configurati | Component | Support | |-----------|---------| | Hypervisor | KVM | -| VM disk storage | File-based `qcow2` disks | +| VM disk storage | File-based `qcow2` disks and disks on LVM datastores | | Backup types | Full and incremental | | Incremental mode | CBT only (`INCREMENT_MODE="CBT"`) | | VM state | Running and powered off VMs | -| OneBEX exporter | NBD | +| OneBEX exporter | NBD, LVM | {{< alert title="Important" type="info" >}} Interactive incremental backups do not support the `SNAPSHOT` increment mode. OpenNebula rejects this combination when the backup configuration is updated. @@ -118,6 +118,8 @@ TYPE = "BACKUP_DS" DS_MAD = "interactive" TM_MAD = "-" + +DATASTORE_CAPACITY_CHECK="NO" ``` The datastore must be added to every cluster that contains VMs managed by the integration. @@ -131,7 +133,7 @@ $ onecluster adddatastore During interactive restores, OpenNebula passes the Image Datastore downloader a OneBEX URL in the following form: ```default -onbex://: +onebex://: ``` `IMAGE_DS_ID` is the destination Image Datastore ID where the restored disk image will be created. `PORT_ID` is the restore transfer port allocated for the interactive restore session. @@ -158,6 +160,7 @@ The OneBEX API is consumed by backup integrations. The current API is: OneBEX uses exporters to expose VM disk data to external backup systems. -| Exporter | Disk format | Transport | Description | -|----------|-------------|-----------|-------------| -| `nbd` | `qcow2` | Network Block Device | Exposes the backup disk through NBD. For local disk images, OneBEX starts a read-only `qemu-nbd` process and serves the image through a Unix socket. | +| Exporter | VM disk storage | Transport | Description | +|----------|-----------------|-----------|-------------| +| `nbd` | File-based `qcow2` disks | Network Block Device | Exposes the backup disk through NBD. OneBEX starts a read-only `qemu-nbd` process and serves the disk export through a Unix socket. | +| `lvm` | Disks on LVM datastores | Direct block-device reads | Exposes the prepared LVM block device directly. Full backups return the full device extent. Incremental backups use `thin_delta` to return changed extents from LVM thin metadata. | diff --git a/content/product/integration_references/infrastructure_drivers_development/sd.md b/content/product/integration_references/infrastructure_drivers_development/sd.md index de30503e6..1f94fd434 100644 --- a/content/product/integration_references/infrastructure_drivers_development/sd.md +++ b/content/product/integration_references/infrastructure_drivers_development/sd.md @@ -112,7 +112,7 @@ The backup datastore drivers are responsible for storing the generate `backup` f - `backup_id` driver reference for the backup - `size_mb` size that the backup takes - `format` value of the backup image’s FORMAT attribute (values: raw, rbd) -- **restore**: Restore the OpenNebula objects (VM Template and Images). Note that the actual download of the images will be made by the Image Datastore using the reference URI. The specific mechanism to download images for a given protocol is coded in the `downloader.sh` script. Standard backup datastore pseudo-URLs take the form: `://///` (example: `restic://100/23/0:25f4b298,1:6968545c//var/lib/one/datastores/0/0/backup/disk.0`, the backup job ID can be empty). Interactive restores use OneBEX-URL form `onbex://:`, where `IMAGE_DS_ID` is the destination Image Datastore ID and `PORT_ID` is the restore transfer port allocated for the interactive restore: +- **restore**: Restore the OpenNebula objects (VM Template and Images). Note that the actual download of the images will be made by the Image Datastore using the reference URI. The specific mechanism to download images for a given protocol is coded in the `downloader.sh` script. Standard backup datastore pseudo-URLs take the form: `://///` (example: `restic://100/23/0:25f4b298,1:6968545c//var/lib/one/datastores/0/0/backup/disk.0`, the backup job ID can be empty). Interactive restores use OneBEX-URL form `onebex://:`, where `IMAGE_DS_ID` is the destination Image Datastore ID and `PORT_ID` is the restore transfer port allocated for the interactive restore: - **ARGUMENTS**: `datastore_action_dump image_id` - **RETURNS**: `Template_ID Image_ID1 Image_ID2 ...` - **ls**: Lists the disk backups included in a given backup together with a downloader URL. The action receives the increment ID as a parameter and the information of the backup image, datastore and VM as XML through standard input. @@ -139,7 +139,7 @@ For interactive restores, the downloader URL uses the OneBEX pseudo-URL: ```default { - "0": "onbex://1:13050" + "0": "onebex://1:13050" } ``` diff --git a/content/product/virtual_machines_operation/virtual_machine_backups/operations.md b/content/product/virtual_machines_operation/virtual_machine_backups/operations.md index 816976c2c..d0d1397fe 100644 --- a/content/product/virtual_machines_operation/virtual_machine_backups/operations.md +++ b/content/product/virtual_machines_operation/virtual_machine_backups/operations.md @@ -44,8 +44,8 @@ The `INTERACTIVE` backup workflow is reserved for supported third-party integrat For interactive backup integrations, OpenNebula supports: -- **Full interactive backups** for `qcow2` disks. -- **Incremental interactive backups** for `qcow2` disks using **CBT** mode only. +- **Full interactive backups** for file-based `qcow2` disks and disks on LVM datastores. +- **Incremental interactive backups** for file-based `qcow2` disks and disks on LVM datastores using **CBT** mode only. Interactive incremental backups do not support the `SNAPSHOT` increment mode. {{< /alert >}} @@ -59,7 +59,7 @@ VM backups can be taken live or while the VM is powered off. The operation compr - *Post-backup*: Cleans any temporal file in the hypervisor. {{< alert title="Note" type="info" >}} -In order to save space in the backup system, RAW disk backups are converted and stored always in Qcow2 format.{{< /alert >}} +In order to save space in the backup system, RAW disk backups are converted and stored always in Qcow2 format.{{< /alert >}} ## Limitations @@ -68,6 +68,7 @@ In order to save space in the backup system, RAW disk backups are converted and - Attaching a disk to a VM that had an incremental backup previously made will yield an error. The –reset option for the backup operation is required to recreate a new incremental chain - Incremental backups on VMs with disk or system snapshots is not supported - `KEEP_LAST` option is not supported for Incremental backups of Ceph disks +- Interactive backups only support datastores using the `local`, `shared` and `lvm*` TM drivers. ## Preparing VMs for Backups From 53acd91ba05cb07dc1d76dba3b5a4509111cc521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mirko=20Stojiljkovi=C4=87?= <155116476+ms4ons@users.noreply.github.com> Date: Mon, 6 Jul 2026 11:05:32 +0200 Subject: [PATCH 06/38] F OpenNebula/one#7783: Add ONEDRS_BLOCKED attribute to avoid migrations (#742) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tino Vázquez Signed-off-by: ms4ons --- .../product/cloud_system_administration/scheduler/drs.md | 6 +++++- .../software/release_information/release_notes/whats_new.md | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/content/product/cloud_system_administration/scheduler/drs.md b/content/product/cloud_system_administration/scheduler/drs.md index 7ff87f08c..7caf12e24 100644 --- a/content/product/cloud_system_administration/scheduler/drs.md +++ b/content/product/cloud_system_administration/scheduler/drs.md @@ -96,7 +96,7 @@ When using OneDRS for placement, the following differences from workload optimiz - Predictive DRS is **not applicable** (forecasts are unavailable for pending VMs). - Migration threshold settings **do not apply**. -## OneDRS Configuration File +## OneDRS Configuration The main DRS configuration file is `/etc/one/schedulers/one_drs.conf`. This file defines default behavior, which can be overridden per cluster. The following options can be defined: @@ -174,3 +174,7 @@ MEMORY_SYSTEM_DS_SCALE: 0 DIFFERENT_VNETS: YES ``` + +### Blocking VM Migrations + +It is possible to avoid the migrations for specific VMs, by setting `ONEDRS_BLOCKED` to `YES` in its user template. diff --git a/content/software/release_information/release_notes/whats_new.md b/content/software/release_information/release_notes/whats_new.md index 50887274b..438786328 100644 --- a/content/software/release_information/release_notes/whats_new.md +++ b/content/software/release_information/release_notes/whats_new.md @@ -47,6 +47,10 @@ The OpenNebula team is excited to announce the availability of the **OpenNebula ## Packaging +## OpenNebula Distributed Resource Scheduler + +* [OneDRS]({{% relref "product/cloud_system_administration/scheduler/drs#scheduler-drs" %}}) can now skip automatic migration for VMs whose user template sets `ONEDRS_BLOCKED` to `YES`. + ## Features Backported to 7.2.x Additionally, the following functionalities are present that were not in OpenNebula 7.2.0, although they debuted in subsequent maintenance releases of the 7.2.x series: From 42327e210e9813b50466d7a23e2eec5fb9cb5064 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20N=C3=A9meth?= Date: Mon, 6 Jul 2026 12:33:12 +0200 Subject: [PATCH 07/38] M #-: add context compatibility and upgrade best practices (#741) The idea is to document that context packages are supported both directions. And also add best practices to the upgrade process how to handle the different context versions for running and future VMs. Signed-off-by: Balazs Nemeth Co-authored-by: mattrowe-opennebula --- .../guest_operating_systems/kvm_contextualization.md | 11 +++++++++++ .../upgrade_process/upgrade_guide/start_here.md | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/content/product/virtual_machines_operation/guest_operating_systems/kvm_contextualization.md b/content/product/virtual_machines_operation/guest_operating_systems/kvm_contextualization.md index 187e3ce3a..73ecd54a5 100644 --- a/content/product/virtual_machines_operation/guest_operating_systems/kvm_contextualization.md +++ b/content/product/virtual_machines_operation/guest_operating_systems/kvm_contextualization.md @@ -47,6 +47,17 @@ From the following links you can learn more about: * [Filesystem tuning](https://github.com/OpenNebula/one-apps/wiki/linux_feature#file-system-configuration). * [Other OS settings and OneGate](https://github.com/OpenNebula/one-apps/wiki/linux_feature#other-system-configuration). +## Compatibility Overview + +OpenNebula contextualization is designed to be highly flexible, supporting compatibility in both directions within the official release window. + +There is a single OpenNebula contextualization package maintained on the OpenNebula Marketplace that always represents the newest version. This latest package is continuously updated to support a wide range of OpenNebula releases. See the [contextualization package on the OpenNebula Marketplace](https://marketplace.opennebula.io/appliance/6f7a1735-5b88-4667-a319-07ffe5e684ee), where the compatible releases are listed. + +| **Scenario** | **Supported** | **Details** | +| ---- | ---- | ---- | +| Newer OpenNebula (e.g., v7.x) managing older Context (e.g., v6.x) | **Yes** | The upgraded `oned` daemon natively understands how to manage VMs running older contextualization packages. | +| Older OpenNebula (e.g., v6.x) deploying newer Context (e.g., v7.x) | **Yes** | You can run the latest contextualization package inside VM guests instantiated on older, compatible LTS infrastructure. | + ## Contextualization Reference The full list of options and attributes in the contextualization section are described in the [Virtual Machine Definition File reference section]({{% relref "../../operation_references/configuration_references/template#template-context" %}}) diff --git a/content/software/upgrade_process/upgrade_guide/start_here.md b/content/software/upgrade_process/upgrade_guide/start_here.md index 0d15e6b37..da000d3bb 100644 --- a/content/software/upgrade_process/upgrade_guide/start_here.md +++ b/content/software/upgrade_process/upgrade_guide/start_here.md @@ -45,3 +45,15 @@ Update your OpenNebula packages by following only the guide that applies to your - [Upgrading a Federation]({{% relref "upgrading_federation#upgrade-federation" %}}) + +## Upgrading Contextualization Packages + +When upgrading your OpenNebula infrastructure, you do not need to execute a massive update of the contextualization packages of all your running Virtual Machines. For details on the highly flexible compatibility support between contextualization and infrastructure versions, see the [Contextualization]({{% relref "kvm_contextualization#compatibility-overview" %}}) page + +To ensure stability and minimize disruption, follow these best practice recommendations: + +1. **Keep Running VMs as They Are**: Do not update the context packages of currently running VMs during an infrastructure upgrade. The new OpenNebula version will continue to manage them without issue. +2. **Update Context on Golden Images**: Update the contextualization packages on your customized "golden" images and templates. This ensures that all *new* VMs provisioned after the upgrade will utilize the latest contextualization features. +3. **Targeted Updates for Running VMs**: Only update the context package on an actively running VM if you specifically need a new feature introduced in the newer context version, or if you need to resolve a known bug that impacts that specific VM. + +You can find the installation and upgrade instructions in the one-apps wiki for [Linux](https://github.com/OpenNebula/one-apps/wiki/linux_installation) and [Windows](https://github.com/OpenNebula/one-apps/wiki/win_installation) guest VMs. \ No newline at end of file From 8a7b944b25cb3e098df773786404a066baba278a Mon Sep 17 00:00:00 2001 From: Guillermo Ramos Date: Mon, 6 Jul 2026 12:34:48 +0200 Subject: [PATCH 08/38] F 7600 + F 7772: NICo driver docs + AI guide (#732) Document https://github.com/OpenNebula/one/issues/7600 (NICo driver technical reference) + https://github.com/OpenNebula/one/issues/7772 (AI blueprint guide). Co-authored-by: mattrowe-opennebula --- .../hypervisor_configuration/_index.md | 5 +- .../hypervisor_configuration/nico_driver.md | 130 ++++++++++++++ .../virtual_machines_operation/_index.md | 2 +- .../metal_instances/_index.md | 6 + .../metal_instances/bare_metal_nico.md | 168 ++++++++++++++++++ .../metal_instances/overview.md | 18 ++ .../release_notes/editions.md | 2 + .../release_notes/whats_new.md | 3 + .../ai_factory_blueprints/overview.md | 9 +- 9 files changed, 337 insertions(+), 6 deletions(-) create mode 100644 content/product/operation_references/hypervisor_configuration/nico_driver.md create mode 100644 content/product/virtual_machines_operation/metal_instances/_index.md create mode 100644 content/product/virtual_machines_operation/metal_instances/bare_metal_nico.md create mode 100644 content/product/virtual_machines_operation/metal_instances/overview.md diff --git a/content/product/operation_references/hypervisor_configuration/_index.md b/content/product/operation_references/hypervisor_configuration/_index.md index e7f0ee3c6..0e5825839 100644 --- a/content/product/operation_references/hypervisor_configuration/_index.md +++ b/content/product/operation_references/hypervisor_configuration/_index.md @@ -2,7 +2,7 @@ title: "Hypervisor Configuration" linkTitle: "Virtualization Drivers" date: "2025-03-05" -description: "Configure KVM and LXC hypervisor nodes." +description: "Configure KVM, LXC, and NICo hypervisor nodes." categories: pageintoc: "" hide_feedback: true @@ -10,7 +10,6 @@ tags: weight: "1" --- -These pages contain explanations and configuration for configuring hypervisor nodes with the KVM and LXC drivers. - +These pages contain explanations and configuration for configuring hypervisor nodes with the KVM, LXC, and NICo drivers. diff --git a/content/product/operation_references/hypervisor_configuration/nico_driver.md b/content/product/operation_references/hypervisor_configuration/nico_driver.md new file mode 100644 index 000000000..930943abb --- /dev/null +++ b/content/product/operation_references/hypervisor_configuration/nico_driver.md @@ -0,0 +1,130 @@ +--- +title: "NICo Driver (AE)" +date: "2026-06-03" +description: "Configure OpenNebula Hosts and VM templates for NVIDIA NICo instances." +categories: +pageintoc: "177" +tags: +weight: "4" +--- + + + +## Overview + +The NICo [VMM]({{% relref "product/integration_references/infrastructure_drivers_development/devel-vmm/" %}}) and [IM]({{% relref "product/integration_references/infrastructure_drivers_development/devel-im/" %}}) drivers enable OpenNebula to deploy and monitor NVIDIA NICo instances through the NICo REST API. A NICo Host in OpenNebula does not represent a KVM or LXC hypervisor node. Instead, it represents a NICo allocation and the API connection settings used to create, inspect, and delete NICo instances. + +The NICo VMM driver stores the NICo instance UUID as the VM `DEPLOY_ID`. Later operations, such as shutdown and monitoring, use this value when making calls to the NICo REST API. + +OpenNebula maintains a NICo VM in the `RUNNING` state during a NICo reboot request. The monitor data includes `NICO_STATUS`, so that transient NICo states such as `Rebooting` can be inspected without changing the OpenNebula lifecycle state. + +## Creating a NICo Host + +Create a dedicated Host using the NICo IM and VMM drivers: + +```shell +onehost create nico --im nico --vm nico +``` + +After creating the Host, add the NICo connection and allocation attributes: + +```shell +onehost update nico +``` + +Example Host template: + +```default +NICO_CARBIDE_PROXY = "https://ncp-isv-carbide-proxy.nvidia.com/v1/carbide/proxy" +NICO_SSA_ISSUER = "https://issuer.example/token-provider" +NICO_NGC_ORG = "example-org" +NICO_ISV_CLIENT_ID = "client-id" +NICO_ISV_CLIENT_SECRET = "client-secret" +NICO_TARGET_SCOPES = "scope1 scope2" +NICO_ALLOCATION = "allocation-id" +NICO_API_TIMEOUT = "60" +NICO_FORCE_DESTROY = "NO" +``` + +Required Host attributes: + +- `NICO_CARBIDE_PROXY`: Base URL for the CARBIDE proxy. +- `NICO_SSA_ISSUER`: Issuer URL used to obtain the JWT token. +- `NICO_NGC_ORG`: NGC organization used in NICo API paths. +- `NICO_ISV_CLIENT_ID`: Client ID for the `client_credentials` flow. +- `NICO_ISV_CLIENT_SECRET`: Client secret for the `client_credentials` flow. +- `NICO_TARGET_SCOPES`: Scopes requested when acquiring the JWT token. +- `NICO_ALLOCATION`: NICo allocation ID represented by this OpenNebula Host. + +Optional Host attributes: + +- `NICO_API_TIMEOUT`: API timeout in seconds. The default is `60`. +- `NICO_FORCE_DESTROY`: Set to `YES` to request forced deletion on cancel operations. The default is `NO`. + +The IM driver uses `NICO_ALLOCATION` to query `GET /allocation/` and report Host capacity from `allocationConstraints[0].constraintValue`. + +## Creating a NICo VM Template + +Create a VM template with the NICo instance attributes required by the allocation and operating system you intend to deploy. + +Example VM template: + +```default +NAME = "nico-instance" +CPU = "1" +MEMORY = "1" + +NICO_INSTANCE_TYPE_ID = "instance-type-id" +NICO_OS_ID = "operating-system-id" +NICO_VPC_ID = "vpc-id" + +NICO_NETWORK_SECURITY_GROUP_ID = "security-group-id" +NICO_SSH_KEY_GROUP_IDS = "ssh-key-group-1,ssh-key-group-2" +NICO_USER_DATA = "cloud-init-or-user-data" +NICO_LABELS = "{\"environment\":\"test\"}" + +NIC = [ + NETWORK = "nico-network", + NICO_VPC_PREFIX_ID = "vpc-prefix-id" +] + +SCHED_REQUIREMENTS = "ID = 123" +``` + +Required VM attributes: + +- `CPU`: Must be `1`, as it represents a single instance to the OpenNebula scheduler. +- `MEMORY`: Must be `1`, same as with CPU. +- `NICO_INSTANCE_TYPE_ID`: NICo instance type to deploy. +- `NICO_OS_ID`: Operating system ID. +- `NICO_VPC_ID`: VPC used by the instance. This attribute must be defined in the VM template. +- `NIC`: Network interface used by the instance. +- `NIC/NICO_VPC_PREFIX_ID`: VPC prefix used by the instance interface. This attribute must be defined in the NIC section. +- `SCHED_REQUIREMENTS`: Scheduling expression used to place the VM on the NICo Host. + +`NICO_VPC_ID` is read only from the VM template. `NICO_VPC_PREFIX_ID` is read only from the first NIC section. + +Common optional VM attributes: + +- `NICO_NETWORK_SECURITY_GROUP_ID`: Network security group ID. +- `NICO_SSH_KEY_GROUP_IDS`: Comma-separated list of SSH key group IDs. +- `NICO_USER_DATA`: User data passed to the NICo instance. +- `NICO_LABELS`: JSON object with labels to attach to the NICo instance. + +## Scheduling to the NICo Host + +NICo instances must be scheduled to the OpenNebula Host configured with the NICo drivers and the corresponding NICo allocation attributes. Use `SCHED_REQUIREMENTS` in the VM template to force placement on that Host. + +Pin by Host ID: + +```default +SCHED_REQUIREMENTS = "ID = 123" +``` + +Alternatively, place the VM on any Host using the NICo VMM driver: + +```default +SCHED_REQUIREMENTS = "VM_MAD = \"nico\"" +``` + +Using explicit scheduling prevents the NICo template from being placed on regular KVM or LXC Hosts. diff --git a/content/product/virtual_machines_operation/_index.md b/content/product/virtual_machines_operation/_index.md index d8f98a8d9..918432f8a 100644 --- a/content/product/virtual_machines_operation/_index.md +++ b/content/product/virtual_machines_operation/_index.md @@ -1,5 +1,5 @@ --- -title: "Virtual Machines Operation" +title: "Workload Operation" linkTitle: "Workload Operation" date: "2025-02-17" description: "Complete information for creating and managing Virtual Machines. These guides include VM definitions, configurations for the supported networking architectures, creating VM backups, operating system parameters, and services comprising coordinated multiple Virtual Machines." diff --git a/content/product/virtual_machines_operation/metal_instances/_index.md b/content/product/virtual_machines_operation/metal_instances/_index.md new file mode 100644 index 000000000..6cfb06cff --- /dev/null +++ b/content/product/virtual_machines_operation/metal_instances/_index.md @@ -0,0 +1,6 @@ +--- +title: "Metal Instances (AE)" +description: "Integrate OpenNebula with external bare-metal infrastructure services." +weight: 7 +tags: ['AI'] +--- \ No newline at end of file diff --git a/content/product/virtual_machines_operation/metal_instances/bare_metal_nico.md b/content/product/virtual_machines_operation/metal_instances/bare_metal_nico.md new file mode 100644 index 000000000..34c027494 --- /dev/null +++ b/content/product/virtual_machines_operation/metal_instances/bare_metal_nico.md @@ -0,0 +1,168 @@ +--- +title: "Bare Metal as a Service with NICo" +date: "2026-06-24" +description: "Integrate OpenNebula with NVIDIA NICo to offer multi-tenant bare-metal instances as a service." +weight: 2 +tags: ['AI'] +--- + + + +This guide describes how to integrate an existing OpenNebula cloud with the [NVIDIA Infra Controller (NICo)](https://docs.nvidia.com/infra-controller/documentation/home) to offer basic multi-tenant Bare Metal as a Service. OpenNebula represents each NICo allocation as a Host and uses the NICo [Virtual Machine Manager (VMM)]({{% relref "product/integration_references/infrastructure_drivers_development/devel-vmm/" %}}) and [Information Manager (IM)]({{% relref "product/integration_references/infrastructure_drivers_development/devel-im/" %}}) drivers to create, monitor, and delete bare-metal instances through the [NICo REST API](https://docs.nvidia.com/infra-controller/rest-api-reference/getting-started). + +This integration is intended for environments where OpenNebula provides cloud management, user, group, quota, and template controls, while NICo provides the bare-metal capacity and lifecycle operations for each instance. + +This guide focuses on the service integration model. For the complete driver attribute reference, see the [NICo Driver]({{% relref "product/operation_references/hypervisor_configuration/nico_driver" %}}) documentation. + +## Prerequisites + +Before you start, it is expected that NICo is already set up and configured on compatible hardware, please refer to the [Official NVIDIA NICo Documentation](https://docs.nvidia.com/infra-controller/documentation/home) for details. Prior to using OpenNebula's NICo integration, ensure that: + +- OpenNebula is already [installed]({{% relref "software/installation_process/overview/" %}}) and running. +- The NICo service is already deployed and reachable from the OpenNebula Front-end. +- The NICo VMM and IM drivers are installed in the OpenNebula Front-end. +- You have a NICo allocation ID (the `id` from [Create](https://docs.nvidia.com/infra-controller/rest-api-reference/api-reference/allocation/create-allocation) or [Retrieve Allocation](https://docs.nvidia.com/infra-controller/rest-api-reference/api-reference/allocation/get-all-allocation)) for the capacity you want to expose through OpenNebula. +- You have the NICo API credentials and connection details required by your environment. +- The NICo VPC, VPC prefix, operating system, instance type, network security group, and SSH key group identifiers have been created in NICo. +- OpenNebula [users]({{% relref "product/cloud_system_administration/multitenancy/manage_users/" %}}), [groups]({{% relref "product/cloud_system_administration/multitenancy/manage_groups/" %}}), and [Virtual Data Centers (VDCs)]({{% relref "product/cloud_system_administration/multitenancy/manage_vdcs/" %}}) are already planned for the tenants that will consume the service. + +## Integration Model + +The NICo integration maps OpenNebula objects to NICo resources as follows: + +| **OpenNebula object** | **NICo resource** | +| --- | --- | +| Host using the `nico` IM and VMM drivers | NICo allocation and API connection | +| VM template | Bare-metal instance definition | +| VM | NICo bare-metal instance | +| VM `DEPLOY_ID` | NICo instance UUID | +| NIC section in the VM template | NICo VPC prefix selection | + +In this model, the OpenNebula Host does not represent a physical hypervisor. It represents a NICo allocation that OpenNebula can consume. The NICo IM driver reports capacity from that allocation, and the NICo VMM driver performs the instance lifecycle operations. + +For multi-tenancy, create one or more service templates and publish them only to the groups or VDCs that should consume each NICo allocation. Use OpenNebula quotas to limit how many bare-metal instances each tenant can deploy. + +## Create the NICo Host + +Create a dedicated Host that uses the NICo information manager and virtualization drivers: + +```shell +onehost create nico --im nico --vm nico +``` + +Update the Host template with the NICo connection details and the allocation that this Host represents. The required and optional Host attributes are described in the [NICo Driver Reference]({{% relref "product/operation_references/hypervisor_configuration/nico_driver" %}}). + +```shell +onehost update nico +``` + +After the next monitoring cycle, verify that OpenNebula can monitor the allocation: + +```shell +onehost show nico +``` + +If different tenants must consume different NICo allocations, create one OpenNebula Host per allocation and restrict the corresponding VM templates with `SCHED_REQUIREMENTS`. + +## Create a Tenant Network Placeholder + +NICo uses its own VPC and VPC prefix identifiers to attach the bare-metal instance to the requested network. OpenNebula still requires a VM template `NIC` section, so create or reuse a Virtual Network to serve as the tenant-facing network object. + +The [NICo driver]({{% relref "product/operation_references/hypervisor_configuration/nico_driver" %}}) reads `NICO_VPC_PREFIX_ID` from the first `NIC` section of the VM template. Define one VM template per tenant network, or clone the template and change the `NICO_VPC_PREFIX_ID` for each published service. + +## Create the Bare-metal Service Template + +Create a VM template that describes the NICo instance type, operating system, VPC, and networking attributes to use for the bare-metal instance. Use the attribute set documented in the [NICo Driver Reference]({{% relref "product/operation_references/hypervisor_configuration/nico_driver" %}}). + +At the service level, pay special attention to the scheduling expression and the tenant network mapping. For example, pin a service template to the intended NICo Host: + +```default +NIC = [ + NETWORK = "nico-network", + NICO_VPC_PREFIX_ID = "vpc-prefix-id" +] + +SCHED_REQUIREMENTS = "ID = 123" +``` + +Use `CPU = "1"` and `MEMORY = "1"` in the VM template since each OpenNebula VM represents one NICo instance. Capacity control derives from the NICo allocation reported by the Host and from OpenNebula quotas, not from the CPU and memory values in the template. + +If a template can be placed on any NICo Host, schedule by VMM driver instead: + +```default +SCHED_REQUIREMENTS = "VM_MAD = \"nico\"" +``` + +For production services, pinning by Host ID is usually safer because it prevents a tenant template from consuming the wrong NICo allocation. + +## Publish the Service to Tenants + +Use OpenNebula groups, VDCs, and template permissions to expose the service to the correct tenants. + +Recommended model: + +- Create a group for each tenant or service tier. +- Add the tenant users to the corresponding group. +- Create a VDC that includes the NICo Host, the tenant Virtual Network, and the service template. +- Publish only the VM templates that match the tenant entitlement. +- Apply VM quotas to limit how many bare-metal instances each tenant can run. + +Example quota for a tenant group that can run up to two NICo bare-metal instances: + +```shell +onegroup quota tenant-a +``` + +```default +VM = [ + RUNNING_VMS = "2" +] +``` + +This keeps the service multi-tenant at the OpenNebula layer while delegating the physical bare-metal provisioning to NICo. + +## Instantiate and Operate Bare-metal Instances + +Tenants can instantiate the published service template from Sunstone or with the CLI: + +```shell +onetemplate instantiate nico-bare-metal --name tenant-a-bm-01 +``` + +OpenNebula sends the create request to NICo and stores the returned NICo instance UUID as the VM `DEPLOY_ID`. You can inspect the mapping with: + +```shell +onevm show tenant-a-bm-01 +``` + +Use standard OpenNebula lifecycle actions for tenant operations: + +- `onevm terminate` deletes the NICo instance. +- `onevm reboot` requests a NICo reboot. +- `onevm show` displays the monitored state and NICo attributes reported by the driver. + +During a NICo reboot request, OpenNebula keeps the VM in the `RUNNING` state. Check the monitored `NICO_STATUS` value to inspect transient NICo states such as `Rebooting`. + +## Validation Checklist + +After the integration is complete, validate the service with the following checks: + +1. The NICo Host is monitored successfully in OpenNebula. +2. The Host capacity matches the expected NICo allocation. +3. A tenant can see only the published bare-metal service templates. +4. A tenant can instantiate a template and obtain access to a running NICo instance. +5. The OpenNebula VM `DEPLOY_ID` matches the NICo instance UUID. +6. Tenant quotas prevent deploying more instances than allowed. +7. Terminating the OpenNebula VM removes the corresponding NICo instance. + +## Troubleshooting + +- If the Host is in an error state, verify the NICo API endpoint, issuer URL, organization, client credentials, target scopes, and allocation ID. +- If instantiation fails before reaching NICo, check that the VM template includes: + * `NICO_INSTANCE_TYPE_ID` + * `NICO_OS_ID` + * `NICO_VPC_ID` + * `NIC` section + * `NIC/NICO_VPC_PREFIX_ID`. +- If the VM is scheduled to the wrong infrastructure, tighten `SCHED_REQUIREMENTS` to the NICo Host ID. +- If tenants can see the wrong service templates, review template ownership, permissions, groups, and VDC membership. diff --git a/content/product/virtual_machines_operation/metal_instances/overview.md b/content/product/virtual_machines_operation/metal_instances/overview.md new file mode 100644 index 000000000..1c74b5bef --- /dev/null +++ b/content/product/virtual_machines_operation/metal_instances/overview.md @@ -0,0 +1,18 @@ +--- +title: "Bare-metal Instances Overview" +linkTitle: "Overview" +date: "2026-07-01" +description: +categories: +pageintoc: "82" +tags: +weight: "1" +--- + +Metal Instances extend OpenNebula workload operation to dedicated physical servers, allowing cloud users and operators to consume bare-metal resources through controlled, automated service workflows. They are designed for environments where workloads need direct access to the underlying hardware, predictable performance, strong isolation, or specialized acceleration devices. + +This model is particularly useful for AI Factory, HPC, edge, sovereign cloud, and service-provider environments, where virtualized infrastructure may not always provide the required level of hardware control or performance. Metal Instances make it possible to manage these resources as part of a broader OpenNebula cloud, while preserving the benefits of automation, multi-tenancy, capacity control, and operational consistency. + +This section provides guides for deploying and operating Bare Metal as a Service and related metal workload services with OpenNebula. The first guide of this section covers integration with the [NVIDIA Infra Controller (NICo)]({{% relref "product/virtual_machines_operation/metal_instances/bare_metal_nico/" %}}), enabling automated bare-metal lifecycle management for accelerated infrastructure, including systems built around NVIDIA networking, GPUs, and DPUs. + +Future guides in this section will cover additional Metal Instance services and operational patterns as the OpenNebula bare-metal ecosystem expands. \ No newline at end of file diff --git a/content/software/release_information/release_notes/editions.md b/content/software/release_information/release_notes/editions.md index cd4fa13ba..d549360b2 100644 --- a/content/software/release_information/release_notes/editions.md +++ b/content/software/release_information/release_notes/editions.md @@ -11,6 +11,8 @@ weight: "7" OpenNebula offers a range of subscriptions and extensions to suit various operational and business requirements. Organizations can choose subscription models that provide support, maintenance, and access to additional software extensions. +The OpenNebula documentation uses the following suffixes in page titles to identify which features are extensions related to a specific subscription or software edition: + * **EE** - Refers to features that are Enterprise Extensions and are only available to customers with an Enterprise Subscription * **AE** - Refers to features that are AI Factory Extensions and are only available to customers with an AI Factory Subscription * **CE** - Refers to the Community Edition, available to all users diff --git a/content/software/release_information/release_notes/whats_new.md b/content/software/release_information/release_notes/whats_new.md index 438786328..5301face8 100644 --- a/content/software/release_information/release_notes/whats_new.md +++ b/content/software/release_information/release_notes/whats_new.md @@ -47,6 +47,9 @@ The OpenNebula team is excited to announce the availability of the **OpenNebula ## Packaging +## AI Factories + +Integration of the [NVIDIA Infra Controller (NICo)]({{% relref "product/virtual_machines_operation/metal_instances/bare_metal_nico/" %}}) introduces Bare Metal as a Service to OpenNebula, streamlining the lifecycle management of bare-metal instances within multi-tenant, AI Factory-scale infrastructures. ## OpenNebula Distributed Resource Scheduler * [OneDRS]({{% relref "product/cloud_system_administration/scheduler/drs#scheduler-drs" %}}) can now skip automatic migration for VMs whose user template sets `ONEDRS_BLOCKED` to `YES`. diff --git a/content/solutions/ai_factory_blueprints/overview.md b/content/solutions/ai_factory_blueprints/overview.md index 518d757f0..66544f340 100644 --- a/content/solutions/ai_factory_blueprints/overview.md +++ b/content/solutions/ai_factory_blueprints/overview.md @@ -32,7 +32,12 @@ Configuring, deploying and validating a high-performance AI infrastructure using

-3. Perform Validation: As a prerequisite, you must have an AI Factory ready to be validated after completing the above installation procedures. These are the options to validate your AI Factory: +3. Integrate external infrastructure services when required: + * [Bare Metal as a Service with NICo]({{% relref "product/virtual_machines_operation/metal_instances/bare_metal_nico" %}}): Offer multi-tenant bare metal instances from an existing OpenNebula cloud. +
+
+ +4. Perform Validation: As a prerequisite, you must have an AI Factory ready to be validated after completing the above installation procedures. These are the options to validate your AI Factory: * [Direct AI execution]({{% relref "solutions/ai_factory_blueprints/direct_ai_execution" %}}): * [LLM Inferencing with vLLM]({{% relref "solutions/ai_factory_blueprints/direct_ai_execution/llm_inference_certification" %}}): Using vLLM with two different models and two model sizes, running across both H100 and L40S GPUs. @@ -43,4 +48,4 @@ Configuring, deploying and validating a high-performance AI infrastructure using * [Containerized AI Execution]({{% relref "solutions/ai_factory_blueprints/containerized_ai_execution/ai_ready_k8s" %}}): * [Deployment of AI-Ready Kubernetes]({{% relref "solutions/ai_factory_blueprints/containerized_ai_execution/ai_ready_k8s" %}}): Use H100 and L40S deployment to run Kubernetes. * [LLM Inferencing with NVIDIA Dynamo]({{% relref "solutions/ai_factory_blueprints/containerized_ai_execution/nvidia_dynamo" %}}): Integrating the GPU-powered Kubernetes cluster with the NVIDIA Dynamo Cloud Platform to provision and manage AI workloads through the Dynamo framework for your AI workloads on top of the NVIDIA Dynamo framework. - * [Scheduling with NVIDIA KAI Scheduler]({{% relref "solutions/ai_factory_blueprints/containerized_ai_execution/nvidia_kai_scheduler" %}}): Use the NVIDIA KAI Scheduler to share GPU resources across different workloads within the AI-ready Kubernetes cluster. \ No newline at end of file + * [Scheduling with NVIDIA KAI Scheduler]({{% relref "solutions/ai_factory_blueprints/containerized_ai_execution/nvidia_kai_scheduler" %}}): Use the NVIDIA KAI Scheduler to share GPU resources across different workloads within the AI-ready Kubernetes cluster. From e7d77b2be505d24cb419707b8d8115878789bdce Mon Sep 17 00:00:00 2001 From: Jan Orel Date: Mon, 6 Jul 2026 12:35:12 +0200 Subject: [PATCH 09/38] F OpenNebula/one#7653: Add Ubuntu2604 repo configuration (#733) --- .../opennebula_repository_configuration_ce.md | 14 +++++++++++++ .../opennebula_repository_configuration_ee.md | 20 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/content/software/installation_process/frontend_installation/opennebula_repository_configuration_ce.md b/content/software/installation_process/frontend_installation/opennebula_repository_configuration_ce.md index 6dc6cf79f..16dada105 100644 --- a/content/software/installation_process/frontend_installation/opennebula_repository_configuration_ce.md +++ b/content/software/installation_process/frontend_installation/opennebula_repository_configuration_ce.md @@ -103,6 +103,20 @@ echo "deb [signed-by=/etc/apt/keyrings/opennebula.gpg] https://downloads.openneb apt-get update ``` +**Ubuntu 26.04** + +Ubuntu 26.04 ships Node.js 22 in its base repositories, but OpenNebula FireEdge requires Node.js 20, which is provided by the OpenNebula repository. Add an APT pin so that `apt` installs Node.js 20 from the OpenNebula repository instead of the newer version shipped by Ubuntu: + +```shell +cat << "EOT" > /etc/apt/preferences.d/opennebula-nodejs +Package: nodejs +Pin: release o=OpenNebula +Pin-Priority: 600 +EOT +echo "deb [signed-by=/etc/apt/keyrings/opennebula.gpg] https://downloads.opennebula.io/repo/{{< release >}}/Ubuntu/26.04 stable opennebula" > /etc/apt/sources.list.d/opennebula.list +apt-get update +``` + ### SUSE #### SUSE Linux Enterprise Server 15 SP7 diff --git a/content/software/installation_process/frontend_installation/opennebula_repository_configuration_ee.md b/content/software/installation_process/frontend_installation/opennebula_repository_configuration_ee.md index 4563588a6..0b7d30dea 100644 --- a/content/software/installation_process/frontend_installation/opennebula_repository_configuration_ee.md +++ b/content/software/installation_process/frontend_installation/opennebula_repository_configuration_ee.md @@ -138,6 +138,26 @@ echo "deb [signed-by=/etc/apt/keyrings/opennebula.gpg] https://enterprise.openne apt-get update ``` +**Ubuntu 26.04** + +Ubuntu 26.04 ships Node.js 22 in its base repositories, but OpenNebula FireEdge requires Node.js 20, which is provided by the OpenNebula repository. Add an APT pin so that `apt` installs Node.js 20 from the OpenNebula repository instead of the newer version shipped by Ubuntu: + +```shell +cat << "EOT" > /etc/apt/auth.conf.d/opennebula.conf +machine enterprise.opennebula.io +login +password +EOT +chmod 600 /etc/apt/auth.conf.d/opennebula.conf +cat << "EOT" > /etc/apt/preferences.d/opennebula-nodejs +Package: nodejs +Pin: release o=OpenNebula +Pin-Priority: 600 +EOT +echo "deb [signed-by=/etc/apt/keyrings/opennebula.gpg] https://enterprise.opennebula.io/repo/{{< release >}}/Ubuntu/26.04 stable opennebula" > /etc/apt/sources.list.d/opennebula.list +apt-get update +``` + ### SUSE #### SUSE Linux Enterprise Server 15 SP7 From c419d1a16df4ba0a126af08f2c1fbb07854899b1 Mon Sep 17 00:00:00 2001 From: mattrowe-opennebula Date: Mon, 6 Jul 2026 12:38:56 +0200 Subject: [PATCH 10/38] F OpenNebula/one#7782: 7.4 release notes 1st draft (#740) --- .../release_notes/compatibility.md | 2 +- .../release_notes/whats_new.md | 88 +++++++++++++++---- 2 files changed, 71 insertions(+), 19 deletions(-) diff --git a/content/software/release_information/release_notes/compatibility.md b/content/software/release_information/release_notes/compatibility.md index 99fdaa536..df59e44fa 100644 --- a/content/software/release_information/release_notes/compatibility.md +++ b/content/software/release_information/release_notes/compatibility.md @@ -20,7 +20,7 @@ Visit the [Features list](../../../getting_started/understand_opennebula/openneb OpenNebula systemd services no longer force a log rotation on start. The `ExecStartPre=-/usr/sbin/logrotate -f ...` directive has been removed from all services (`opennebula`, `opennebula-hem`, `opennebula-flow`, `opennebula-gate`, `opennebula-form`, `opennebula-fireedge`, and `opennebula-ks`). Logs under `/var/log/one/` are still rotated by the files in `/etc/logrotate.d/` via the system's own `logrotate` timer/cron, so no action is required. -To keep the old behaviour for a service, add a systemd drop-in, e.g. for `opennebula`: +To keep the old behavior for a service, add a systemd drop-in, e.g. for `opennebula`: ``` # /etc/systemd/system/opennebula.service.d/logrotate.conf diff --git a/content/software/release_information/release_notes/whats_new.md b/content/software/release_information/release_notes/whats_new.md index 5301face8..426f2e6f9 100644 --- a/content/software/release_information/release_notes/whats_new.md +++ b/content/software/release_information/release_notes/whats_new.md @@ -10,43 +10,78 @@ weight: "1" -The OpenNebula team is excited to announce the availability of the **OpenNebula 7.4**! +The OpenNebula team is excited to announce the availability of OpenNebula 7.4. This release introduces a broad set of usability, automation, and operational improvements across the platform, led by a redesigned Sunstone interface that makes day-to-day cloud management more modern and intuitive. +OpenNebula 7.4 also delivers important enhancements for operating virtualized infrastructure at scale, including OneSwap batch VMware migrations, improved OneDRS datastore selection, dynamic VM group management through the CLI, bulk operations for service VMs, Ubuntu 26.04 support, expanded backup capabilities with OneBEX, new VLAN group-level authorization policies, support for SR-IOV-capable PCI network interfaces in Switchdev mode with Open vSwitch, an enhanced Slurm appliance with out-of-the-box NVIDIA GPU support and LDAP identity integration, and a wide range of fixes and improvements across HA, networking, storage, monitoring, and vCenter compatibility. + +Together with this release, OpenNebula also introduces new extension capabilities for advanced infrastructure use cases, including automated AI Factory-scale Bare Metal as a Service with NVIDIA NICo and enhanced Kubernetes provisioning and pre-deployment diagnostics with OneKS. These extensions further expand OpenNebula’s role as a flexible, production-ready platform for private cloud, edge, HPC, and sovereign AI infrastructure. + +Key highlights of this release include: + +* Redesigned Sunstone interface, delivering a modern, highly intuitive user experience for cloud administrators. +* Optimized enterprise workload management with OneSwap batch VMware migrations, dynamic VM group management via the CLI, and bulk deletion of scheduled actions from all service VMs. +* Removed Veeam integration storage requirements using expanded backup capabilities via the OpenNebula Backup Exporter (OneBEX), allowing third-party tools to interactively pull full incremental changes on virtual disks — qcow2 and LVM based disks are supported in this first release. +* Enhanced Slurm appliance simplifies the creation of Slurm Clusters for AI and HPC workloads with out-of-the-box NVIDIA GPU support and LDAP identity integration. +* Improved OneDRS datastore selection during VM migrations, helping identify optimal datastores based on space and usage requirements. +* New VLAN group-level authorization policies, allowing cloud administrators to delegate VLAN management to tenants and enable Virtual Network self-provisioning in multi-tenant environments. +* Support for SR-IOV-capable PCI network interfaces in Switchdev mode with Open vSwitch. +* Updated OS compatibility with production-ready packages fully supporting Ubuntu 26.04 (Resolute Raccoon). +* Multiple fixes and stability improvements across the platform, and much more!... + +The Enterprise Subscription also includes advanced extensions designed for enterprise cloud and AI Factory deployments, including: + +* Enhanced Kubernetes management with multi-cluster deployment configuration options and pre-deployment diagnostics to validate cluster readiness and avoid time-consuming provisioning failures. +* Native integration with the NVIDIA Infrastructure Controller (NICo) to deliver automated Bare Metal as a Service (BMaaS) and AI Factory-scale provisioning and orchestration of accelerated infrastructure. + +Thank you to our incredible community and partners for your continued support in building the future of open-source cloud orchestration! ## OpenNebula Core +* Added the capacity to [batch delete scheduled actions from all service VMs]({{% relref "product/virtual_machines_operation/multi-vm_workflows/appflow_use_cli/#deleting-scheduled-actions-from-service-vms" %}}), negating the need to delete actions from each individual VM. + ## Storage & Backups * Added [interactive backup integration support]({{% relref "../../../product/integration_references/infrastructure_drivers_development/interactive_backup.md#interactive-backup-integration" %}}), enabling third-party backup integrations to pull full and CBT incremental `qcow2` VM backups directly from KVM hypervisors through the OpenNebula Backup Exporter (OneBEX). * Added [selected disk backups]({{% relref "../../../product/virtual_machines_operation/virtual_machine_backups/operations#vm-backups-selected-disks" %}}), allowing VM backup configurations and Backup Jobs to back up only a defined subset of eligible VM disks. Selected-disk backups can be restored as [individual disks]({{% relref "../../../product/virtual_machines_operation/virtual_machine_backups/operations#vm-backups-selected-disks-restore" %}}). -## Networking +## AI Factories + +* Integration of the NVIDIA Infra Controller (NICo) delivers automated AI Factory-scale provisioning of accelerated bare-metal hardware, with full lifecycle management including hardware discovery, firmware validation, DPU provisioning, and multi-tenant operation. ## Sunstone -* Added FSaaS (virtiofs) support in Sunstone, allowing users to manage shared storage file systems, create filesystem images, and attach disks directly from the GUI. +* Complete redesign of interface, improving useability. +* Added FSaaS (VirtioFS) support in Sunstone, allowing users to manage shared storage file systems, create filesystem images, and attach disks directly from the GUI. ## API and CLI -* **Dynamic VM Group Management**: New CLI commands `onevm vmgroup-add` and `onevm vmgroup-del` allow adding or removing VMs from a [VM Group]({{% relref "affinity.md#dynamic-vmg" %}}) dynamically. -* **OneGate Sinatra Configuration**: OneGate now exposes the Sinatra server configuration through the `:server` section in `onegate-server.conf`, allowing administrators to customize supported Sinatra settings such as Host authorization. +* New CLI commands `onevm vmgroup-add` and `onevm vmgroup-del` enable dynamic VM Group management, with the capacity to add or remove VMs from a [VM Group]({{% relref "affinity.md#dynamic-vmg" %}}) dynamically. +* OneGate now exposes the Sinatra server configuration through the `:server` section in `onegate-server.conf`, allowing administrators to customize supported Sinatra settings such as Host authorization. ## KVM * Enable filtering by OS ID/type/version/architecture in [QEMU Guest Agent Monitoring](/product/operation_references/hypervisor_configuration/kvm_driver/#qemu-guest-agent-monitoring). * Added support for [dummy interfaces]({{% relref "vm_templates#network-interfaces--alias" %}}), allowing KVM VMs to use guest NICs that are not attached to any OpenNebula Virtual Network. -* Gather network information using qemu-guest-agent when [QEMU Guest Agent Monitoring](/product/operation_references/hypervisor_configuration/kvm_driver/#qemu-guest-agent-monitoring) is enabled +* Gather network information using qemu-guest-agent when [QEMU Guest Agent Monitoring](/product/operation_references/hypervisor_configuration/kvm_driver/#qemu-guest-agent-monitoring) is enabled. -## LXC +## OpenNebula Elastic Kubernetes Service -## OpenNebula Form +* Added multi-cluster deployment support in OneKS, allowing users to select the target OpenNebula Cluster and deployment networks when creating Kubernetes Clusters. +* Added [pre-deployment diagnostics for OneKS provisioning]({{% relref "platform_services/oneks/management/configuration/#readiness-check-configuration" %}}), enabling users to validate the readiness a deployment placement option prior to deployment to avoid time-consuming provisioning failures. -## OpenNebula Elastic Kubernetes Service +## Networking -* Added multi-cluster deployment support in OneKS, allowing users to select the target OpenNebula cluster and deployment networks when creating Kubernetes Clusters. +* VLAN Groups enable cloud administrators fo delegate VLAN management to tenants in multi-tenant clouds, allowing tenant self-provisioning of Virtual Networks. +* Support for [SR-IOV capable PCI network interfaces in Switchdev mode]({{% relref "product/cluster_configuration/hosts_and_clusters/pci_passthrough/#usage-as-network-interfaces" %}}) with Open vSwitch. ## Packaging +* Added OpenNebula packages for for Ubuntu 26.04 (Resolute Raccoon). + +## OneSwap + +* Added Windows OS Profile/Best practices VM template options to oneswap Windows conversion. +* OneSwap batch VM conversion enables the migration of multiple VMs in a single execution ## AI Factories Integration of the [NVIDIA Infra Controller (NICo)]({{% relref "product/virtual_machines_operation/metal_instances/bare_metal_nico/" %}}) introduces Bare Metal as a Service to OpenNebula, streamlining the lifecycle management of bare-metal instances within multi-tenant, AI Factory-scale infrastructures. @@ -59,14 +94,31 @@ Integration of the [NVIDIA Infra Controller (NICo)]({{% relref "product/virtual_ Additionally, the following functionalities are present that were not in OpenNebula 7.2.0, although they debuted in subsequent maintenance releases of the 7.2.x series: * [Allow the customization of the favicon in FireEdge]({{% relref "product/operation_references/opennebula_services_configuration/fireedge.md#branding-fireedge" %}}). +* Added the capacity to [batch delete scheduled actions from all service VMs]({{% relref "product/virtual_machines_operation/multi-vm_workflows/appflow_use_cli/#deleting-scheduled-actions-from-service-vms" %}}), negating the need to delete actions from each individual VM. ## Other Issues Solved -* [Fix marketplace broken redirect link](https://github.com/OpenNebula/one/issues/7291). -* [Fix Improve live migration options for busy guests](https://github.com/OpenNebula/one/issues/5774). -* [Fix Units in "Size on instantiate" VM Template instantiation](https://github.com/OpenNebula/one/issues/7672). -* [Fix VM log is not showing up in the FireEdge if USE_VMS_LOCATION=YES](https://github.com/OpenNebula/one/issues/7680). -* [Fix VM CDROM hot-attach without target or dev-prefix](https://github.com/OpenNebula/one/issues/7736). -* [Fix API commands executed on HA follower, for full list of commands the GitHub issue](https://github.com/OpenNebula/one/issues/7725). -* [Fix VirtioFS filesystem image size reporting always `0`](https://github.com/OpenNebula/one/issues/7751). -* [Fix onehost failing on CLI-only installs due to an unconditional require of HostSyncManager](https://github.com/OpenNebula/one/issues/7768). +* Fix marketplace broken redirect link [#7291](https://github.com/OpenNebula/one/issues/7291). +* Fix improve live migration options for busy guests [#5774](https://github.com/OpenNebula/one/issues/5774). +* Fix missing units in "Size on instantiate" VM Template instantiation [#7672](https://github.com/OpenNebula/one/issues/7672). +* Fix VM log is not showing up in the FireEdge if `USE_VMS_LOCATION=YES` [#7680](https://github.com/OpenNebula/one/issues/7680). +* Fix VM CDROM hot-attach without target or dev-prefix [#7736](https://github.com/OpenNebula/one/issues/7736). +* Fix API commands executed on HA follower, for full list of commands the GitHub issue [#7725](https://github.com/OpenNebula/one/issues/7725). +* Fix onehost failing on CLI-only installs due to an unconditional require of HostSyncManager [#7768](https://github.com/OpenNebula/one/issues/7768). +* Fix AutoNFS bug where `NFX_AUTO_*` attributes are not correctly read, preventing the automatic mount [#7763](https://github.com/OpenNebula/one/issues/7763) +* Fix OneDRS placement failure for LVM SAN EE datastore with `KeyError` on Image DS ID [#7752](https://github.com/OpenNebula/one/issues/7752) +* Fix incorrect reporting of sizes for VirtioFS images [#7751](https://github.com/OpenNebula/one/issues/7751) +* Fix OneKS Clusters stuck in DEPROVISIONING state if a OneKS group becomes empty during the deprovisioning process [#7749](https://github.com/OpenNebula/one/issues/7749) +* Fix unrecoverable WARNING state of OneKS groups after recovery of OneKS Cluster [#7748](https://github.com/OpenNebula/one/issues/7748) +* Fix OneKS lifecycle operations after renaming a cluster by using stable Kubernetes identifiers [#7724](https://github.com/OpenNebula/one/issues/7724). +* Fix oneswap compatibility issue with vCenter 8.0.3 [#7698](https://github.com/OpenNebula/one/issues/7698). +* Fix `opennebula-exporter` crash when monitoring diskless VMs [#7703](https://github.com/OpenNebula/one/issues/7703). +* Fix PCI attach to prevent bus address collisions [#7695](https://github.com/OpenNebula/one/issues/7695). +* Fix lack of VLAN tags clearance in OVS when removing them from virtual network [#7707](https://github.com/OpenNebula/one/issues/7707) +* Fix LVM (EE) post-reboot activation silently skipping VM disks [#7720](https://github.com/OpenNebula/one/issues/7720). +* Fix OVS port QinQ vlan mode being overwritten with changes introduced in[#7657](https://github.com/OpenNebula/one/issues/7657). +* Fix MAC address range parsing for invalid MAD address ranges [#7233](https://github.com/OpenNebula/one/issues/7233). +* Fix file-based image cloning between two datastores with BRIDGE_LIST [#7762](https://github.com/OpenNebula/one/issues/7762). +* Fix AutoNFS not working correctly when used on System Datastores of type `shared` [#7763](https://github.com/OpenNebula/one/issues/7763). +* Fix LVM concurrency issue with parallel deployments from different hosts using the same VG [#7719](https://github.com/OpenNebula/one/issues/7719). +* Fix various logrotate issues [#7646](https://github.com/OpenNebula/one/issues/7646). From bcc532576cdbdcb0e8b83f73e39eecbbfe272e35 Mon Sep 17 00:00:00 2001 From: ArnauGabrielAtienza <97285545+ArnauGabrielAtienza@users.noreply.github.com> Date: Mon, 6 Jul 2026 16:11:35 +0200 Subject: [PATCH 11/38] M OpenNebula/one#7776: Update Veeam documentation (#744) Signed-off-by: ArnauGabrielAtienza --- .../interactive_backup_veeam_architecture.svg | 2 +- .../backup_system/veeam.md | 202 +++++------------- .../release_notes/platform_notes.md | 2 +- 3 files changed, 53 insertions(+), 153 deletions(-) diff --git a/assets/images/veeam/interactive_backup_veeam_architecture.svg b/assets/images/veeam/interactive_backup_veeam_architecture.svg index e4374a5ba..4ab64aceb 100644 --- a/assets/images/veeam/interactive_backup_veeam_architecture.svg +++ b/assets/images/veeam/interactive_backup_veeam_architecture.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/content/product/cluster_configuration/backup_system/veeam.md b/content/product/cluster_configuration/backup_system/veeam.md index 1175e4e17..9c97bbb3d 100644 --- a/content/product/cluster_configuration/backup_system/veeam.md +++ b/content/product/cluster_configuration/backup_system/veeam.md @@ -34,15 +34,19 @@ The following table summarizes the supported backup modes for each storage syste | LVM | Yes | Yes | | NetApp | No† | No† | - These backup modes were supported in previous OpenNebula versions, such as 7.0 and 7.2. From OpenNebula version 7.4 onwards, they are not supported by the current OneBEX-based integration. + These backup modes were supported in previous OpenNebula versions, such as 7.0 and 7.2. In OpenNebula version 7.4, they are not supported by the current OneBEX-based integration, but are planned to be supported in a future maintenance releases. + +### Volatile Disk Backups + +Volatile disks cannot be backed up by default. To back up volatile disks, enable this functionality in the OpenNebula Virtual Machine configuration by setting the `BACKUP_VOLATILE` parameter to `YES`. Otherwise, the disk is not listed in Veeam. For more information about volatile disk backups in OpenNebula, see the [backup documentation page]({{% relref "product/virtual_machines_operation/virtual_machine_backups/operations.md" %}}). ## Limitations The following is a list of the limitations affecting the Veeam integration with OpenNebula: -- The KVM appliance deployed by Veeam does not include context packages. To configure the appliance network, either manually choose the first available free IP in the management network or set up a DHCP service router. +- The KVM appliance deployed by Veeam does not include context packages. To configure the appliance network, either manually choose any available free IP in the management network or set up a DHCP service. - Alpine Virtual Machines cannot be backed up. -- During image transfers, you may see a warning message stating `Unable to use transfer URL for image transfer: Switched to proxy URL. Backup performance may be affected`. This is expected and shouldn't affect performance. +- During upload image transfers, you may see a warning message stating `Unable to use transfer URL for image transfer: Switched to proxy URL. Backup performance may be affected`. This is expected and shouldn't affect performance. - Spaces are not allowed in Virtual Machine names in the integration. Avoid using them, even if they are allowed in OpenNebula itself, to prevent issues when performing in-place restores. If you encounter other issues or bugs, check the [Known Issues page]({{% relref "software/release_information/release_notes/known_issues/" %}}) for Veeam-related issues. @@ -51,45 +55,20 @@ If you encounter other issues or bugs, check the [Known Issues page]({{% relref To ensure a compatible integration between OpenNebula and Veeam Backup, the following components and network configuration are required: -- **Backup Server**: Hosts the **OpenNebula oVirtAPI Server**. -- **Veeam Backup Appliance**: Automatically deployed by Veeam when OpenNebula is added as a hypervisor. +- **Veeam Workers**: Deployed from the Veeam server to process backups and restores. - **OpenNebula Backup Exporter (OneBEX)**: Runs on demand on the OpenNebula hypervisors and exposes VM backup data to Veeam. See [Interactive Backup Integrations]({{% relref "product/integration_references/infrastructure_drivers_development/interactive_backup.md#interactive-backup-integration" %}}) for implementation details. - **Veeam (interactive) Backup Datastore**: An OpenNebula `BACKUP_DS` using `DS_MAD="interactive"` and `VEEAM_DS="YES"`. This datastore coordinates Veeam backup operations and tracks backup metadata. The backup itself is stored in the Veeam repository. - **Management Network**: Provides connectivity between all of the following components: - OpenNebula Front-end - - OpenNebula oVirtAPI Server - OpenNebula OneBEX endpoint on each hypervisor - All OpenNebula Hosts running VMs to be backed up - Veeam Server - - Veeam Backup Appliance + - Veeam Workers

{{< image path="/images/veeam/interactive_backup_veeam_architecture.svg" alt="Architecture of the OpenNebula-Veeam Backup Integration" align="center" width="90%" mb="20px" border="false" >}} -## Backup Server Requirements - -To ensure full compatibility with the oVirtAPI module, the Backup Server must run one of the following operating systems: - -- AlmaLinux 9 -- Ubuntu 22.04 or 24.04 -- RHEL 9 -- Debian 12 - -The minimum hardware specifications are: - -- **CPU**: 8 cores -- **Memory**: 16 GB RAM -- **Disk**: No hard requirement for backup payload storage. Backup data is stored in the Veeam repository. - -## Veeam Backup Appliance Requirements - -When OpenNebula is added as a platform in Veeam, Veeam deploys a KVM appliance as a VM in OpenNebula. This appliance has the following minimum requirements: - -- **CPU**: 6 cores -- **Memory**: 6 GB RAM -- **Disk**: 100 GB - ## Installation and Configuration ### 1. Configure OneBEX @@ -112,9 +91,27 @@ onehost sync -f For OneBEX parameters and API details, see [Interactive Backup Integrations]({{% relref "product/integration_references/infrastructure_drivers_development/interactive_backup.md#interactive-backup-integration" %}}). -### 2. Prepare the Environment for the oVirtAPI Server +{{< alert title="High Availability" type="info" >}} +If using High Availability, any changes to ``/var/lib/one/remotes/etc/onebex/onebex-server.conf`` need to be performed on all frontends. +{{< /alert >}} + +### 2. Enable VM Guest Agent Monitoring + +The integration needs VM Guest Agent monitoring to be enabled. To do so set ``:enabled`` to ``true`` on the following file in the frontend: -A server should be configured to function as the oVirtAPI Server and expose the oVirtAPI. This server should be accessible from all the Clusters intended for backup via the management network shown in the architecture diagram. The oVirtAPI Server acts as the communication gateway between Veeam and OpenNebula. +```default +/var/lib/one/remotes/etc/im/kvm-probes.d/guestagent.conf +``` + +Then, in the same frontend server execute the following command to propagate the remote into the KVM hosts: + +```shell +onehost sync --force +``` + +{{< alert title="High Availability" type="info" >}} +If using High Availability, any changes to ``/var/lib/one/remotes/etc/im/kvm-probes.d/guestagent.conf`` need to be performed on all frontends. +{{< /alert >}} ### 3. Create the Veeam Backup Datastore @@ -152,11 +149,8 @@ To install the oVirtAPI module, configure the OpenNebula repository on the Backu The configuration file can be found at `/etc/one/ovirtapi-server.yml`. Change the following variables before starting the service: -* `one_xmlrpc`: Address of the OpenNebula Front-end. Please do not include any prefixes such as `http://`, only the IP address itself is needed. +* `public_ip`: IP address that Veeam will use to communicate with the frontend node. * `endpoint_port`: Port used by the OpenNebula RPC endpoint (defaults to 2633). -* `public_ip`: IP address that Veeam uses to communicate with the oVirtAPI server. -* `one_sshkey`: Path to the private key file used by the oVirtAPI server to reach the OpenNebula Front-end. -* `one_sshkey_host`: Path to the private key file used by the OpenNebula Front-end to reach hypervisor Hosts. Local path as seen on the Front-end. * `backup_freeze`: (Optional) Controls which filesystem freeze mode OpenNebula requests when performing backups initiated via the oVirtAPI/Veeam integration. Valid values are `NONE`, `AGENT`, and `SUSPEND`. For details on each mode see the Backup Modes section in the backup guide: [Backup Modes]({{% relref "product/virtual_machines_operation/virtual_machine_backups/operations/#backup-modes" %}}). In the same configuration file, configure the OneBEX port and the port range reserved for interactive restores: @@ -165,23 +159,11 @@ In the same configuration file, configure the OneBEX port and the port range res * `port_min` and `port_max`: Range of available ports reserved for interactive restores. * `ports_path`: File where the oVirtAPI Server tracks ports used for interactive restores. -{{< alert title="Important" type="info" >}} -You may see the 5554 port in the `public_ip` variable in the default settings, this is no longer needed so avoid using it. Leave only the IP address in the variable, no port needed. - -You may also have a variable named `instance_id`, which you should delete if you are running a version of the package >=7.0.1. -{{< /alert >}} - During installation a self-signed certificate is generated at `/etc/one/ovirtapi-ssl.crt` for encryption. You can replace this certificate with your own and change the `cert_path` configuration variable. -After installing the package, make sure that the `oneadmin` user in the Backup Server can perform passwordless SSH to the `oneadmin` user in the Front-end server. - Finally, start the service with either `systemctl start apache2` (Ubuntu/Debian) or `systemctl start httpd` (RHEL/Alma). -{{< alert title="Important" type="info" >}} -Once the package is installed, a `oneadmin` user is created. This user and the `oneadmin` user in the Front-end must be able to establish passwordless SSH connections in both directions. -{{< /alert >}} - -{{< alert title="Package dependency" type="info" >}} +{{< alert title="Package dependency" type="warning" >}} In RHEL and Alma environments, you may face issues with the passenger package dependencies (`mod_passenger` and `mod_ssl`). You may add the correct repository and install the packages with the following: ```shell @@ -191,128 +173,46 @@ dnf install -y passenger mod_passenger mod_ssl {{< /alert >}} -### 5. Add OpenNebula to Veeam - -To add OpenNebula as a hypervisor to Veeam, configure it as an oVirt KVM Manager in Veeam and choose the IP address of the oVirtAPI module. You can follow the [official Veeam documentation](https://helpcenter.veeam.com/docs/vbrhv/userguide/connecting_manager.html?ver=6) for this step or follow the next steps: - -#### 5.1. Add the New Virtualization Manager - -The first step is to add the oVirtAPI Backup Server to Veeam. Go to **Backup Infrastructure**, then **Managed Servers**, and click **Add Manager**: - -{{< image path="/images/veeam/add_manager.png" alt="Veeam Add Manager" align="center" width="90%" mb="20px" >}} - -Then, choose to add a new **Virtualization Platform**: - -{{< image path="/images/veeam/virtualization_platform.png" alt="Veeam Virtualization Platform" align="center" width="90%" mb="20px" >}} - -Then select **Oracle Linux Virtualization Manager**: - -{{< image path="/images/veeam/virtualization_platform_olvm.png" alt="Veeam Oracle Linux Virtualization Manager" align="center" width="90%" mb="20px" >}} +{{< alert title="High availability" type="info" >}} -This opens a new dialog box. In the **Address** field, use the IP address or DNS name of the server where the oVirtAPI module is installed: +If the ovirtapi module is going to be configured in High Availability mode, the ovirtapi package needs to be installed and configured in all frontends. Additionally, the `public_ip` must be the VIP address, which is also the one we will use when adding OpenNebula as a Virtualization Platform in Veeam. -{{< image path="/images/veeam/new_manager.png" alt="Veeam New Manager" align="center" width="90%" mb="20px" >}} - -On the **Credentials** tab, set the user and password used to access the OpenNebula Front-end. Use the `oneadmin` user or another OpenNebula user with equivalent privileges. This is an OpenNebula user, not a system user. The user should be listed in the System/Users tab of FireEdge or through the CLI with `oneuser list`. - -If the default certificate is used, Veeam may show an untrusted certificate warning. This warning can be accepted: - -{{< image path="/images/veeam/one_credentials.png" alt="One Credentials" align="center" width="90%" mb="20px" >}} - -Click **Finish**. The new oVirtAPI server should be listed under Managed Servers as an **oVirt KVM** hypervisor. - -{{< image path="/images/veeam/hypervisor_added.png" alt="Hypervisor Added" align="center" width="90%" mb="20px" >}} - -#### 5.2. Deploy the KVM appliance - -For Veeam to perform backup and restore operations, it must deploy a dedicated Virtual Machine to act as a worker. To deploy it, go to the **Backup Infrastructure** tab, then **Backup Proxies**, and click **Add Proxy**: - -{{< image path="/images/veeam/add_proxy.png" alt="Veeam Add Proxy" align="center" width="90%" mb="20px" >}} - -A new dialog box will open. Select the **Oracle Linux Virtualization Manager**: - -{{< image path="/images/veeam/add_proxy_olvm.png" alt="Veeam Add Proxy OLVM" align="center" width="90%" mb="20px" >}} - -The select the **Oracle Linux Virtualization Manager backup appliance** to deploy: - -{{< image path="/images/veeam/add_proxy_app.png" alt="Veeam Add Proxy OLVM Appliance" align="center" width="90%" mb="20px" >}} - -This opens a new wizard to deploy the appliance. You should choose to deploy a new appliance: - -{{< image path="/images/veeam/new_appliance.png" alt="Veeam New Appliance" align="center" width="90%" mb="20px" >}} +{{< /alert >}} -Next choose the Cluster on which to deploy the appliance, as well as a name and the storage domain where the appliance image should be stored: +### 5. Add OpenNebula to Veeam -{{< image path="/images/veeam/appliance_virtual_machine.png" alt="Veeam Appliance Machine" align="center" width="90%" mb="20px" >}} +This section will address the necessary steps to add OpenNebula as a Virtualization Platform into Veeam and deploy the necessary workers. -For the appliance credentials, choose the same ones that you set up when configuring the virtualization manager in the previous steps: +#### 5.1. Add the New Virtualization Manager -{{< image path="/images/veeam/appliance_credentials.png" alt="Veeam Appliance Credentials" align="center" width="90%" mb="20px" >}} +First you need to add OpenNebula as an oVirt platform. To do so, follow the [Adding oVirt KVM Manager to Backup Infrastructure](https://helpcenter.veeam.com/docs/vbr/userguide/ovirt_add_rhv_manager.html?ver=13) Veeam guide with the following considerations: -In the **Network Settings** tab, choose the management network that the appliance will use. It is recommended to manually choose the IP address configuration. If no DHCP service is setup, use the first available free IP in the address range of the management network. +- When selecting the DNS name or the IP address, it should match the `public_ip` configured in the ovirtapi module. +- On the **Credentials** tab, set the user and password used to access the OpenNebula Front-end. Use the `oneadmin` user or another OpenNebula user with equivalent privileges. This is an OpenNebula user, not a system user. The user should be listed in the System/Users tab of FireEdge or through the CLI with `oneuser list`. +- If the default certificate is used, Veeam may show an untrusted certificate warning. This is expected and will not affect the integration. -{{< image path="/images/veeam/appliance_network.png" alt="Veeam Appliance Network" align="center" width="90%" mb="20px" >}} +#### 5.2. Deploy a KVM Worker -In the next step, Veeam will take care of deploying the appliance. Once finished, you should see it listed in the same tab: +Next you need to deploy at least one KVM Worker. To do so, follow the [Adding Workers](https://helpcenter.veeam.com/docs/vbr/userguide/ovirt_workers_add.html?ver=13) Veeam guide with the following considerations: -{{< image path="/images/veeam/appliance_listed.png" alt="Veeam Appliance in List" align="center" width="90%" mb="20px" >}} +- If you are not using a DHCP service, you will need to use a static address. You can set it to any free IP address in the management network. +- The DNS server used must be able to resolve the hostnames of all KVM hosts. -#### 5.3. Verification +{{< alert title="Hostnames and DNS" type="info" >}} -If the integration is configured correctly, the available Virtual Machines appear in the **Inventory** tab under the **Virtual Infrastructure -> oVirt KVM** section. +For backups to work, the HOSTNAME attribute inside each OpenNebula Host must be a FQDN, not a shortname, and the DNS used by the workers and frontend must be able to resolve that FQDN. -{{< image path="/images/veeam/verification.png" alt="Veeam Verification" align="center" width="90%" mb="20px" >}} +{{< /alert >}} ## Logging Information -The oVirtAPI server writes logs in the following directory depending on the operating system: +The oVirtAPI server writes logs in the following paths depending on the operating system: -* Ubuntu/Debian: `/var/log/apache2` -* Alma/RHEL: `/var/log/httpd` +* Ubuntu/Debian: `/var/log/apache2/error.log` +* Alma/RHEL: `/var/log/httpd/error.log` Additional logs for interactive backups are available on the hypervisors: * OneBEX logs: `/var/log/one/onebex.log` -## Performance Improvements - -Backup data is transferred from the OpenNebula hypervisors through OneBEX. The oVirtAPI server handles inventory, authentication, and orchestration requests from Veeam. - -If oVirtAPI requests are queued under load, increase the number of Passenger processes available to the oVirtAPI service. This is controlled by the `PassengerMaxPoolSize` parameter in the Apache configuration file. After changing `PassengerMaxPoolSize`, balance the value with the available RAM and CPU in the Backup Server. - -### Adjusting the Process Pool - -The configuration file is available in the following locations depending on your distribution: - -* Debian/Ubuntu: `/etc/apache2/sites-available/ovirtapi-server.conf` -* Alma/RHEL: `/etc/httpd/conf.d/ovirtapi-server.conf` - -After editing and saving the file, you must restart the web server for the change to take effect: - -* Debian/Ubuntu: `sudo systemctl restart apache2` -* Alma/RHEL: `sudo systemctl restart httpd` - - -**Memory** - -Each active Passenger process consumes approximately 150-200 MB of RAM. You can use the following formula as a starting point to determine a safe maximum, leaving a 30% buffer for the OS and other services: - -`(TOTAL_SERVER_RAM_MB * 0.70) / 200 = Recommended MaxPoolSize` - -**CPU** - -While increasing the pool size, monitor CPU usage. If the CPU load becomes the bottleneck, adding more processes will not increase throughput and may reduce performance. In that case, increase the number of CPUs or vCPUs assigned to the Backup Server. - -OneBEX concurrency is controlled separately in `/var/lib/one/remotes/etc/onebex/onebex-server.conf` through the Puma settings. Increase these values only when the hypervisor, storage, and network can handle the additional concurrent requests. - -### Interpreting Veeam Job Statistics - -The Veeam job statistics window shows a breakdown of the load, which is crucial for identifying the true bottleneck in your backup chain. - -* **Source**: This represents the OpenNebula side serving the backup data, typically the hypervisor and OneBEX endpoint. A high load here indicates that the source is the active bottleneck. -* **Proxy**: This is the KVM appliance deployed by Veeam. If its load is consistently high (e.g., >90%), it is the bottleneck and requires more resources (vCPU/RAM). -* **Network**: This indicates that the transfer speed is being limited by the available bandwidth on the management network connecting the components. - -## Volatile Disk Backups -To back up volatile disks, enable this functionality in the OpenNebula Virtual Machine configuration by setting the `BACKUP_VOLATILE` parameter to `YES`. Otherwise, the disk is not listed in Veeam. For more information about volatile disk backups in OpenNebula, see the [backup documentation page]({{% relref "product/virtual_machines_operation/virtual_machine_backups/operations.md" %}}). diff --git a/content/software/release_information/release_notes/platform_notes.md b/content/software/release_information/release_notes/platform_notes.md index 914860f57..1fc47eefe 100644 --- a/content/software/release_information/release_notes/platform_notes.md +++ b/content/software/release_information/release_notes/platform_notes.md @@ -117,7 +117,7 @@ More information: [one-apps wiki](https://github.com/OpenNebula/one-apps/wiki) | SMART exporter | 0.14.0 | [Optional Exporters]({{% relref "../../../product/cloud_system_administration/prometheus/install.md#monitor-alert-extra-exporters" %}}) | | LVM exporter | 0.6.2 | [Optional Exporters]({{% relref "../../../product/cloud_system_administration/prometheus/install.md#monitor-alert-extra-exporters" %}}) | | Restic backup backend | 0.17.3 | [Backup Datastore: Restic]({{% relref "../../../product/cluster_configuration/backup_system/restic.md#vm-backups-restic" %}}) | -| Veeam B&R | 12.3.1 | [Veeam Backup (EE)]({{% relref "../../../product/cluster_configuration/backup_system/veeam.md" %}}) | +| Veeam B&R | >=13.0 | [Veeam Backup (EE)]({{% relref "../../../product/cluster_configuration/backup_system/veeam.md" %}}) | ### Sunstone From 46eaa4036160793efd407a97d4ff5bbd75c0337d Mon Sep 17 00:00:00 2001 From: Rostyslav Yatsyshyn Date: Mon, 6 Jul 2026 17:58:45 +0300 Subject: [PATCH 12/38] F #7474: Document OneSwap dry-run and staged delta flow (#745) Signed-off-by: Rostyslav Yatsyshyn --- .../software/migration_from_vmware/oneswap.md | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/content/software/migration_from_vmware/oneswap.md b/content/software/migration_from_vmware/oneswap.md index 7495c9955..8ae57f82c 100644 --- a/content/software/migration_from_vmware/oneswap.md +++ b/content/software/migration_from_vmware/oneswap.md @@ -404,6 +404,99 @@ oneswap convert --vms vm-web-01,vm-db-01,vm-app-01 $VOPTS [--fallback|--custom|- The VMs are converted one at a time; if a conversion fails, the batch continues with the remaining VMs. At the end, a summary is printed with the total number of VMs requested, the successful conversions and the list of failed VMs. The command exits with code `0` if all the VMs were converted successfully and `1` otherwise. The positional VM name, `--vms` and `--vm-list` are mutually exclusive. +#### Estimating Migration Time with Dry Run + +OneSwap can estimate the expected duration of a migration without converting the VM: + +```bash +oneswap convert VM_NAME --dry-run +``` + +The dry-run estimate reports the expected time for the main phases: + +* source export +* disk conversion +* OpenNebula image import +* total estimated duration + +By default, OneSwap uses configured fallback transfer rates. The estimate becomes more accurate when benchmark data or previous conversion metrics are available. + +To measure the OpenNebula image import speed, run: + +```bash +oneswap convert VM_NAME --dry-run --benchmark-import +``` + +This creates a temporary raw file and imports it as a temporary OpenNebula Image to measure the real import speed. The temporary image and local benchmark file are removed automatically after the benchmark finishes. + +To measure the source export speed from the VMware datastore, run: + +```bash +oneswap convert VM_NAME --dry-run --benchmark-export +``` + +This creates a temporary benchmark file on the VMware datastore, downloads it through the same source transfer path, records the measured speed, and removes the temporary file afterward. + +The benchmark results are stored in the OneSwap work directory and reused by later dry-run estimates. For HTTP transfers, OneSwap uses import benchmark metrics or configured fallback values for future estimates; real HTTP import timings from full conversions are not reused as trusted metrics. + +#### Staged Delta Migration + +Delta mode can be executed as a single command: + +```bash +oneswap convert VM_NAME --delta +``` + +For planned maintenance windows, the same workflow can also be split into explicit stages. + +First, prepare the base disk while the source VM keeps running: + +```bash +oneswap convert VM_NAME --delta --delta-prepare +``` + +This creates a VMware snapshot, clones and transfers the base disk, converts it locally, and writes the prepared delta state. The source VM keeps running, but the VMware snapshot remains active until the migration is committed or cleaned up. + +After the prepare phase, estimate the final downtime/import-ready time: + +```bash +oneswap convert VM_NAME --dry-run --delta +``` + +This refreshes the current delta size from the active VMware snapshot and estimates the final phase, including: + +* copying the remaining delta +* applying the delta to the prepared disk +* guest OS morph/customization +* OpenNebula image import +* template creation + +For a more accurate OpenNebula import estimate, the import benchmark can also be used with the delta dry-run: + +```bash +oneswap convert VM_NAME --dry-run --delta --benchmark-import +``` + +When ready for the maintenance window, commit the prepared migration: + +```bash +oneswap convert VM_NAME --delta --delta-commit +``` + +This applies the final delta to the prepared disk, performs the remaining guest customization, imports the image into OpenNebula, creates the VM Template, and removes the OneSwap VMware snapshot. + +If the prepared migration should be cancelled, clean it up with: + +```bash +oneswap convert VM_NAME --delta --delta-cleanup +``` + +This removes the OneSwap-created VMware snapshot, the temporary ESXi clone directory, and the local prepared delta state. Do not leave the prepared snapshot active indefinitely, because the delta can continue growing while the source VM is running. + +{{< alert color="warning" title="Delta prepare snapshot" >}} +After `--delta --delta-prepare`, the source VM keeps running with an active VMware snapshot. Always finish with either `--delta --delta-commit` or `--delta --delta-cleanup`. +{{< /alert >}} + #### Prechecks Before starting a conversion, OneSwap runs a set of prechecks against the destination OpenNebula cloud and the conversion host, and aborts early when: @@ -477,3 +570,7 @@ When `oneswap` runs on a server different from the OpenNebula frontend, the conv - `--http-port port`: port of the temporary HTTP server. Default: `29869`. Using an alternative OpenNebula endpoint (`--endpoint`) requires HTTP transfer to be enabled. Make sure the OpenNebula frontend can reach the OneSwap server on the configured port. + +For dry-run import benchmarks and real image imports from a dedicated OneSwap server, the OpenNebula frontend must be able to reach the OneSwap server on `--http-host` and `--http-port`. + +Local path image registration is only safe when OneSwap runs on the OpenNebula frontend or when the work directory is shared with the frontend. Use HTTP transfer for dedicated OneSwap servers. From 51396c22ae94df8b0c75ba69eec54995a66fd58b Mon Sep 17 00:00:00 2001 From: Jan Orel Date: Tue, 7 Jul 2026 13:23:52 +0200 Subject: [PATCH 13/38] M #-: Add log truncation note (#747) --- .../release_information/release_notes/compatibility.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/content/software/release_information/release_notes/compatibility.md b/content/software/release_information/release_notes/compatibility.md index df59e44fa..999ae263f 100644 --- a/content/software/release_information/release_notes/compatibility.md +++ b/content/software/release_information/release_notes/compatibility.md @@ -16,6 +16,10 @@ This guide is aimed at OpenNebula 7.2.x users and administrators who want to upg Visit the [Features list](../../../getting_started/understand_opennebula/opennebula_concepts/key_features) and the [What’s New guide](whats_new#whats-new) for a comprehensive list of what’s new in OpenNebula 7.4. +## Daemon Logs Are No Longer Truncated on Start + +The OpenNebula daemons (`oned`, the monitor, and the scheduler) now open their log files in append mode instead of truncating them on start. Previously the log was reset on every service start and relied on the forced log rotation (see below) to preserve its contents; with that rotation no longer triggered on start, restarts would otherwise have discarded the existing log. No action is required. + ## Log Rotation No Longer Triggered on Service Start OpenNebula systemd services no longer force a log rotation on start. The `ExecStartPre=-/usr/sbin/logrotate -f ...` directive has been removed from all services (`opennebula`, `opennebula-hem`, `opennebula-flow`, `opennebula-gate`, `opennebula-form`, `opennebula-fireedge`, and `opennebula-ks`). Logs under `/var/log/one/` are still rotated by the files in `/etc/logrotate.d/` via the system's own `logrotate` timer/cron, so no action is required. From 3239b09f61edc05aa94bbca484a614c410dff2f4 Mon Sep 17 00:00:00 2001 From: Neal <92747003+onenhansen@users.noreply.github.com> Date: Tue, 7 Jul 2026 10:20:29 -0600 Subject: [PATCH 14/38] F OpenNebula/one#7777: add what's new line (#748) Signed-off-by: Neal Hansen --- content/software/release_information/release_notes/whats_new.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/software/release_information/release_notes/whats_new.md b/content/software/release_information/release_notes/whats_new.md index 426f2e6f9..31c3ca644 100644 --- a/content/software/release_information/release_notes/whats_new.md +++ b/content/software/release_information/release_notes/whats_new.md @@ -122,3 +122,4 @@ Additionally, the following functionalities are present that were not in OpenNeb * Fix AutoNFS not working correctly when used on System Datastores of type `shared` [#7763](https://github.com/OpenNebula/one/issues/7763). * Fix LVM concurrency issue with parallel deployments from different hosts using the same VG [#7719](https://github.com/OpenNebula/one/issues/7719). * Fix various logrotate issues [#7646](https://github.com/OpenNebula/one/issues/7646). +* Fix Datastores rounding off capacity values [#7777](https://github.com/OpenNebula/one/issues/7777). From dee77960b91cda2cdbce092da76494c8fe56eb37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mirko=20Stojiljkovi=C4=87?= <155116476+ms4ons@users.noreply.github.com> Date: Thu, 9 Jul 2026 10:44:49 +0200 Subject: [PATCH 15/38] F OpenNebula/one#7753: Add Storage DRS (#743) Explains the behavior of OneDRS now that the storage migrations are considered. Signed-off-by: ms4ons Co-authored-by: mattrowe-opennebula --- .../scheduler/drs.md | 45 ++++++++++++------- .../release_notes/whats_new.md | 25 ++++++----- 2 files changed, 42 insertions(+), 28 deletions(-) diff --git a/content/product/cloud_system_administration/scheduler/drs.md b/content/product/cloud_system_administration/scheduler/drs.md index 7caf12e24..064aa1ab9 100644 --- a/content/product/cloud_system_administration/scheduler/drs.md +++ b/content/product/cloud_system_administration/scheduler/drs.md @@ -12,34 +12,36 @@ weight: "6" -The **OpenNebula Distributed Resource Scheduler (DRS)** optimizes resource allocation and prevents resource contention within a single OpenNebula [cluster]({{% relref "../../cluster_configuration/hosts_and_clusters/cluster_guide#cluster-guide" %}}). It integrates with OpenNebula’s built-in monitoring and forecasting systems, considering real-time Virtual Machine (VM) and Host usage metrics as well as predictions of future resource consumption. +The **OpenNebula Distributed Resource Scheduler (DRS)** optimizes resource allocation and prevents resource contention within a single OpenNebula [Cluster]({{% relref "product/cluster_configuration/hosts_and_clusters/cluster_guide#cluster-guide" %}}). It integrates with OpenNebula’s built-in monitoring and forecasting systems, considering real-time Virtual Machine (VM) and Host usage metrics as well as predictions of future resource consumption. OpenNebula DRS offers flexible automation levels, allowing recommendations to be generated and applied either automatically or manually. Administrators can review and execute migration suggestions through the OpenNebula Sunstone GUI. ## Overview -OpenNebula DRS employs an integer linear programming (ILP) solver to optimize cluster workload distribution. Key features include: +OpenNebula DRS employs an integer linear programming (ILP) solver to optimize Cluster workload distribution. Key features include: - **Cluster Load Balancing**: Distributes VM workloads across Hosts to balance resource usage, reducing contention and improving performance. - **Predictive DRS**: Uses resource usage forecasts to provide proactive migration recommendations. - **Migration Recommendations**: Generates migration suggestions, allowing administrators to manually approve or automate actions. +A VM might be migrated to another Host or another datastore, but can't change both Host and datastore simultaneously. + ## Configuration and Usage -To enable OneDRS: In Sunstone, select the **Cluster** tab, then enable **OneDRS**. Alternatively, in the Cluster template set the `ONE_DRS` configuration attribute. +**To enable OneDRS**: In Sunstone, go to **Ifrastructure -> Clusters**, select the relevant Cluster then click **Enable OneDRS** in the **OneDRS** tab. Alternatively, in the Cluster template set the `ONE_DRS` configuration attribute. -Configuring OneDRS for the cluster requires setting the following options: +Configuring OneDRS for the Cluster requires setting the following options: -- **Policies**: Defines how workloads are distributed across Hosts. +- **Policies**: Defines how workloads are distributed across Hosts and datastores. - **Usage Metrics and Predictions**: Specifies which resource metrics (CPU, Memory, Network, Disk) to consider for balancing. - **Migration Threshold**: Limits the number of migrations generated in an optimization cycle. ### Policy Configuration -OneNebula DRS migrates VMs according to the defined policy: +OneDRS migrates VMs according to the defined policy: - **Packing**: Minimizes the number of active Hosts to save energy or prepare for maintenance. -- **Load Balancing**: Distributes VMs across available Hosts to prevent resource contention. +- **Load Balancing**: Distributes VMs across available Hosts or datastores to prevent resource contention. #### Load Balancing Objectives @@ -51,7 +53,7 @@ The load balancing goal can combine multiple performance indicators: - **Disk I/O**: Consideration of read/write operations. - **Network Traffic**: Optimization based on network throughput. -For example, you can balance CPU and disk usage equally, setting CPU- and disk-associated weights to 50% each. +For example, you can balance CPU and disk usage equally, setting CPU and disk-associated weights to 50% each. #### Predictive DRS @@ -65,9 +67,9 @@ By default, DRS uses only monitored values. #### Migration Threshold Configuration -Since migrations add overhead, administrators can set a **migration threshold** to limit the number of migrations per optimization cycle. You need to balance this setting: an aggressive threshold may negatively impact performance, while a conservative approach could overlook opportunities for improving the performance of the cluster. +Since migrations add overhead, administrators can set a **migration threshold** to limit the number of migrations per optimization cycle. You need to balance this setting: an aggressive threshold may negatively impact performance, while a conservative approach could overlook opportunities for improving the performance of the Cluster. -By default, the number of migrations is not limited (i.e., the migration threshold is `-1`). +By default, the number of migrations is not limited (i.e. the migration threshold is `-1`). #### Automation Levels @@ -75,11 +77,11 @@ Administrators can choose between different automation levels: - **Manual**: Recommendations are displayed, but migrations must be manually approved. - **Partial**: Migrations are periodically generated and require approval before execution. -- **Fulld**: Migrations are generated and applied automatically based on recommendations. +- **Full**: Migrations are generated and applied automatically based on recommendations. ## Initial Placement -OneDRS can also handle the **initial placement** of pending VMs, selecting the most suitable Hosts. Unlike the default Rank Scheduler, which considers one VM at a time, OneDRS evaluates all pending VMs together for optimal placement. +OneDRS can also handle the **initial placement** of pending VMs, selecting the most suitable Hosts and datastores. Unlike the default Rank Scheduler, which considers one VM at a time, OneDRS evaluates all pending VMs together for optimal placement. Initial placement is configured in `/etc/one/oned.conf` by modifying the `SCHED_MAD` section: @@ -92,13 +94,13 @@ SCHED_MAD = [ When using OneDRS for placement, the following differences from workload optimization apply: -- Only **CPU** and **Memory** balancing is available. There are no monitoring data for pending VMs. +- Only **CPU** and **Memory** balancing is available. There is no monitoring data for pending VMs. - Predictive DRS is **not applicable** (forecasts are unavailable for pending VMs). - Migration threshold settings **do not apply**. ## OneDRS Configuration -The main DRS configuration file is `/etc/one/schedulers/one_drs.conf`. This file defines default behavior, which can be overridden per cluster. The following options can be defined: +The main DRS configuration file is `/etc/one/schedulers/one_drs.conf`. This file defines default behavior, which can be overridden per Cluster. The following options can be defined: - `DEFAULT_SCHED`: Defines the ILP solver used. - `PLACE`: Configures initial VM placement policies. @@ -109,7 +111,7 @@ The main DRS configuration file is `/etc/one/schedulers/one_drs.conf`. This file ### Solver Configuration -OneDRS uses the **PuLP** library for ILP solvers, supporting: +OneDRS uses the [**PuLP** library](https://pypi.org/project/PuLP/) for ILP solvers, supporting: - **CBC Solver** (default) - **GLPK** @@ -125,7 +127,7 @@ Configuration: Scheduling policies define optimization objectives: - `PACK`: Consolidates VMs on fewer Hosts to minimize active hardware. -- `BALANCE`: Distributes VMs across Hosts to reduce resource contention. +- `BALANCE`: Distributes VMs across Hosts or datastores to reduce resource contention. Example: @@ -146,8 +148,16 @@ PLACE: MEMORY: 0.4 ``` +### Migration Configuration + +Migration configuration options are relevant only for workload optimization. + `MIGRATION_THRESHOLD` limits the number of migrations per cycle. +`PRIORITIZE_STORAGE_MIGRATIONS` decides if storage migrations will be prioritized over host migrations (value `"YES"`), when they bring the same improvement with respect to the selected policy. + +### Complete Configuration Example + The following shows a complete configuration file for the OneDRS scheduler: ```yaml @@ -161,6 +171,7 @@ PLACE: OPTIMIZE: POLICY: "BALANCE" MIGRATION_THRESHOLD: 10 + PRIORITIZE_STORAGE_MIGRATIONS: "YES" WEIGHTS: CPU_USAGE: 0.2 CPU: 0.2 @@ -175,6 +186,6 @@ MEMORY_SYSTEM_DS_SCALE: 0 DIFFERENT_VNETS: YES ``` -### Blocking VM Migrations +## Blocking VM Migrations It is possible to avoid the migrations for specific VMs, by setting `ONEDRS_BLOCKED` to `YES` in its user template. diff --git a/content/software/release_information/release_notes/whats_new.md b/content/software/release_information/release_notes/whats_new.md index 31c3ca644..72c5355ad 100644 --- a/content/software/release_information/release_notes/whats_new.md +++ b/content/software/release_information/release_notes/whats_new.md @@ -10,7 +10,7 @@ weight: "1" -The OpenNebula team is excited to announce the availability of OpenNebula 7.4. This release introduces a broad set of usability, automation, and operational improvements across the platform, led by a redesigned Sunstone interface that makes day-to-day cloud management more modern and intuitive. +The OpenNebula team is excited to announce the availability of OpenNebula 7.4! This release introduces a broad set of usability, automation, and operational improvements across the platform, led by a redesigned Sunstone interface that makes day-to-day cloud management more modern and intuitive. OpenNebula 7.4 also delivers important enhancements for operating virtualized infrastructure at scale, including OneSwap batch VMware migrations, improved OneDRS datastore selection, dynamic VM group management through the CLI, bulk operations for service VMs, Ubuntu 26.04 support, expanded backup capabilities with OneBEX, new VLAN group-level authorization policies, support for SR-IOV-capable PCI network interfaces in Switchdev mode with Open vSwitch, an enhanced Slurm appliance with out-of-the-box NVIDIA GPU support and LDAP identity integration, and a wide range of fixes and improvements across HA, networking, storage, monitoring, and vCenter compatibility. @@ -80,14 +80,17 @@ Thank you to our incredible community and partners for your continued support in ## OneSwap -* Added Windows OS Profile/Best practices VM template options to oneswap Windows conversion. -* OneSwap batch VM conversion enables the migration of multiple VMs in a single execution +* Added Windows OS Profile/Best practices VM template options to OneSwap Windows conversion. +* OneSwap batch VM conversion enables the migration of multiple VMs in a single execution. + ## AI Factories -Integration of the [NVIDIA Infra Controller (NICo)]({{% relref "product/virtual_machines_operation/metal_instances/bare_metal_nico/" %}}) introduces Bare Metal as a Service to OpenNebula, streamlining the lifecycle management of bare-metal instances within multi-tenant, AI Factory-scale infrastructures. +* Integration of the [NVIDIA Infra Controller (NICo)]({{% relref "product/virtual_machines_operation/metal_instances/bare_metal_nico/" %}}) introduces Bare Metal as a Service to OpenNebula, streamlining the lifecycle management of bare-metal instances within multi-tenant, AI Factory-scale infrastructures. + ## OpenNebula Distributed Resource Scheduler -* [OneDRS]({{% relref "product/cloud_system_administration/scheduler/drs#scheduler-drs" %}}) can now skip automatic migration for VMs whose user template sets `ONEDRS_BLOCKED` to `YES`. +* [OneDRS]({{% relref "product/cloud_system_administration/scheduler/drs" %}}) now supports storage migrations in addition to migrations across hosts when optimizing Cluster workloads. +* [OneDRS]({{% relref "product/cloud_system_administration/scheduler/drs" %}}) can now skip automatic migration for VMs whose user template sets `ONEDRS_BLOCKED` to `YES`. ## Features Backported to 7.2.x @@ -105,16 +108,16 @@ Additionally, the following functionalities are present that were not in OpenNeb * Fix VM CDROM hot-attach without target or dev-prefix [#7736](https://github.com/OpenNebula/one/issues/7736). * Fix API commands executed on HA follower, for full list of commands the GitHub issue [#7725](https://github.com/OpenNebula/one/issues/7725). * Fix onehost failing on CLI-only installs due to an unconditional require of HostSyncManager [#7768](https://github.com/OpenNebula/one/issues/7768). -* Fix AutoNFS bug where `NFX_AUTO_*` attributes are not correctly read, preventing the automatic mount [#7763](https://github.com/OpenNebula/one/issues/7763) -* Fix OneDRS placement failure for LVM SAN EE datastore with `KeyError` on Image DS ID [#7752](https://github.com/OpenNebula/one/issues/7752) -* Fix incorrect reporting of sizes for VirtioFS images [#7751](https://github.com/OpenNebula/one/issues/7751) -* Fix OneKS Clusters stuck in DEPROVISIONING state if a OneKS group becomes empty during the deprovisioning process [#7749](https://github.com/OpenNebula/one/issues/7749) -* Fix unrecoverable WARNING state of OneKS groups after recovery of OneKS Cluster [#7748](https://github.com/OpenNebula/one/issues/7748) +* Fix AutoNFS bug where `NFX_AUTO_*` attributes are not correctly read, preventing the automatic mount [#7763](https://github.com/OpenNebula/one/issues/7763). +* Fix OneDRS placement failure for LVM SAN EE datastore with `KeyError` on Image DS ID [#7752](https://github.com/OpenNebula/one/issues/7752). +* Fix incorrect reporting of sizes for VirtioFS images [#7751](https://github.com/OpenNebula/one/issues/7751). +* Fix OneKS Clusters stuck in DEPROVISIONING state if a OneKS group becomes empty during the deprovisioning process [#7749](https://github.com/OpenNebula/one/issues/7749). +* Fix unrecoverable WARNING state of OneKS groups after recovery of OneKS Cluster [#7748](https://github.com/OpenNebula/one/issues/7748). * Fix OneKS lifecycle operations after renaming a cluster by using stable Kubernetes identifiers [#7724](https://github.com/OpenNebula/one/issues/7724). * Fix oneswap compatibility issue with vCenter 8.0.3 [#7698](https://github.com/OpenNebula/one/issues/7698). * Fix `opennebula-exporter` crash when monitoring diskless VMs [#7703](https://github.com/OpenNebula/one/issues/7703). * Fix PCI attach to prevent bus address collisions [#7695](https://github.com/OpenNebula/one/issues/7695). -* Fix lack of VLAN tags clearance in OVS when removing them from virtual network [#7707](https://github.com/OpenNebula/one/issues/7707) +* Fix lack of VLAN tags clearance in OVS when removing them from virtual network [#7707](https://github.com/OpenNebula/one/issues/7707). * Fix LVM (EE) post-reboot activation silently skipping VM disks [#7720](https://github.com/OpenNebula/one/issues/7720). * Fix OVS port QinQ vlan mode being overwritten with changes introduced in[#7657](https://github.com/OpenNebula/one/issues/7657). * Fix MAC address range parsing for invalid MAD address ranges [#7233](https://github.com/OpenNebula/one/issues/7233). From fc30974ddc6c7877ca3fc28c20f46294c02181e8 Mon Sep 17 00:00:00 2001 From: Neal <92747003+onenhansen@users.noreply.github.com> Date: Thu, 9 Jul 2026 03:08:40 -0600 Subject: [PATCH 16/38] M #-: add note about WHMCS versions (#750) Signed-off-by: Neal Hansen --- .../product/integration_references/billing_extensions/whmcs.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/product/integration_references/billing_extensions/whmcs.md b/content/product/integration_references/billing_extensions/whmcs.md index ac55edec4..c3ebd39c1 100644 --- a/content/product/integration_references/billing_extensions/whmcs.md +++ b/content/product/integration_references/billing_extensions/whmcs.md @@ -19,6 +19,7 @@ weight: "2" {{< alert title = "Warning" color = "warning" >}} You must use PHP 7.4; currently PHP 8.x will cause an error when creating the user. +WHMCS Version 9.x has dropped support for PHP 7.x, so please also use the LTS 8.x version of WHMCS {{< /alert >}} The install and update process are essentially identical. The module files can be found in `/usr/share/one/whmcs` after you have installed the `opennebula-whmcs-tenants` package via your package manager. You will just need to merge the `modules` directory to the main WHMCS directory on the server hosting WHMCS. When updating the module just copy the files on top of the existing files and overwrite them. An example command for copying the files is here: From 6a3343508eb3282dfc992d32ccd57519e7e205fd Mon Sep 17 00:00:00 2001 From: Rostyslav Yatsyshyn Date: Thu, 9 Jul 2026 12:33:21 +0300 Subject: [PATCH 17/38] F #7788: Document OneSwap vSAN VDDK requirement (#751) Signed-off-by: Rostyslav Yatsyshyn --- .../software/migration_from_vmware/oneswap.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/content/software/migration_from_vmware/oneswap.md b/content/software/migration_from_vmware/oneswap.md index 8ae57f82c..85b088bf8 100644 --- a/content/software/migration_from_vmware/oneswap.md +++ b/content/software/migration_from_vmware/oneswap.md @@ -216,6 +216,22 @@ Ubuntu 24.04 and AlmaLinux/RHEL 9 provide up to date versions of the packages. The script builds the nbdkit version matching the installed distro package and copies only the VDDK plugin into nbdkit's plugin directory. It requires internet access, or an internal mirror via the `NBDKIT_REPO_URL` environment variable. +VDDK mode is also required for VMware vSAN-backed VMDKs. vSAN disks are object-backed and are not available through the classic vCenter datastore `*-flat.vmdk` download path used by the non-VDDK and hybrid transfer modes. + +To convert VMs stored on a vSAN datastore, configure VDDK in `/etc/one/oneswap.yaml`: + +```yaml +:vddk_path: '/opt/vmware-vix-disklib-distrib/' +``` + +or pass it on the command line: + +```bash +oneswap convert VM_NAME --vddk /opt/vmware-vix-disklib-distrib/ +``` + +Delta and hybrid modes are currently not supported for vSAN-backed disks. Use full conversion with VDDK for vSAN-backed VMs. + ### Required software for migrating Windows Virtual machines There are two requirements to convert Windows Virtual Machines: From 02e24ac97792d89f4c1b860698f58cf6e4560633 Mon Sep 17 00:00:00 2001 From: MarioRobres Date: Thu, 9 Jul 2026 15:36:39 +0200 Subject: [PATCH 18/38] B OpenNebula/one#7590, OpenNebula/one#7586, OpenNebula/one#7588: add release notes (#749) Add release notes --- .../software/release_information/release_notes/whats_new.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/content/software/release_information/release_notes/whats_new.md b/content/software/release_information/release_notes/whats_new.md index 72c5355ad..c752435f0 100644 --- a/content/software/release_information/release_notes/whats_new.md +++ b/content/software/release_information/release_notes/whats_new.md @@ -126,3 +126,6 @@ Additionally, the following functionalities are present that were not in OpenNeb * Fix LVM concurrency issue with parallel deployments from different hosts using the same VG [#7719](https://github.com/OpenNebula/one/issues/7719). * Fix various logrotate issues [#7646](https://github.com/OpenNebula/one/issues/7646). * Fix Datastores rounding off capacity values [#7777](https://github.com/OpenNebula/one/issues/7777). +* Fix `SD_DISK_BUS` not taken in account when attaching a disk[#7590](https://github.com/OpenNebula/one/issues/7590) +* Fix `queues` attribute in disk driver element is only supported for virtio bus[#7586](https://github.com/OpenNebula/one/issues/7586) +* Fix default `IOTHREAD` no applied when attaching a virtio disk[#7588](https://github.com/OpenNebula/one/issues/7588) From 57722b0d5996d3d30c8e64a903036ae77515721f Mon Sep 17 00:00:00 2001 From: Rostyslav Yatsyshyn Date: Fri, 10 Jul 2026 11:11:10 +0300 Subject: [PATCH 19/38] F #7336: Document OneSwap non-root libguestfs appliance setup (#752) --- .../software/migration_from_vmware/oneswap.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/content/software/migration_from_vmware/oneswap.md b/content/software/migration_from_vmware/oneswap.md index 85b088bf8..157a4caf2 100644 --- a/content/software/migration_from_vmware/oneswap.md +++ b/content/software/migration_from_vmware/oneswap.md @@ -232,6 +232,59 @@ oneswap convert VM_NAME --vddk /opt/vmware-vix-disklib-distrib/ Delta and hybrid modes are currently not supported for vSAN-backed disks. Use full conversion with VDDK for vSAN-backed VMs. +### Non-root libguestfs appliance + +When OneSwap is executed as a non-root user, for example `oneadmin`, libguestfs may invoke `supermin` to build an appliance from the host kernel. If the active kernel image under `/boot/vmlinuz-*` is readable only by root, `supermin` can fail with: + +```text +cp: cannot open '/boot/vmlinuz-...-generic' for reading: Permission denied +libguestfs: error: /usr/bin/supermin exited with error status 1 +``` + +To avoid relying on local kernel image permissions, configure OneSwap to use a prebuilt libguestfs appliance: + +```bash +cd /var/lib/one +wget https://download.libguestfs.org/binaries/appliance/appliance-1.56.0.tar.xz +tar -xJf appliance-1.56.0.tar.xz +mv appliance libguestfs-appliance +chown -R oneadmin:oneadmin libguestfs-appliance +``` + +The appliance version can be adjusted to a newer available version from the [libguestfs appliance directory](https://download.libguestfs.org/binaries/appliance/). + +Configure the appliance path in `/etc/one/oneswap.yaml`: + +```yaml +:libguestfs_path: /var/lib/one/libguestfs-appliance +``` + +Alternatively, pass the path on the command line: + +```bash +oneswap convert VM_NAME --libguestfs-path /var/lib/one/libguestfs-appliance +``` + +Validate that libguestfs can start with the prebuilt appliance as the OneSwap user: + +```bash +sudo -u oneadmin -H bash -lc 'LIBGUESTFS_PATH=/var/lib/one/libguestfs-appliance libguestfs-test-tool' +``` + +The expected result is: + +```text +===== TEST FINISHED OK ===== +``` + +If `/dev/kvm` exists, add the OneSwap user to the `kvm` group to allow libguestfs to use hardware virtualization: + +```bash +usermod -aG kvm oneadmin +``` + +If `/dev/kvm` is not present, hardware virtualization or nested virtualization must be enabled. Otherwise libguestfs may fall back to TCG and run much slower. + ### Required software for migrating Windows Virtual machines There are two requirements to convert Windows Virtual Machines: From 83353a69c9399e9ac22df903cc8cdb93d471864d Mon Sep 17 00:00:00 2001 From: Jan Orel Date: Fri, 10 Jul 2026 11:27:54 +0200 Subject: [PATCH 20/38] M #~: Platform notes update (#753) --- .../release_notes/platform_notes.md | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/content/software/release_information/release_notes/platform_notes.md b/content/software/release_information/release_notes/platform_notes.md index 1fc47eefe..7a0a3b581 100644 --- a/content/software/release_information/release_notes/platform_notes.md +++ b/content/software/release_information/release_notes/platform_notes.md @@ -28,7 +28,7 @@ OpenNebula is certified over all the following platforms, taking into account th | Red Hat Enterprise Linux | 9, 10 | [Front-end Installation]({{% relref "frontend_install" %}}) | | AlmaLinux | 9, 10 | [Front-end Installation]({{% relref "frontend_install" %}}) | | Rocky Linux | 9, 10 | [Front-end Installation]({{% relref "frontend_install" %}}).
Available through Red Hat packages. | -| Ubuntu Server | 22.04 (LTS), 24.04 (LTS) | [Front-end Installation]({{% relref "frontend_install" %}}) | +| Ubuntu Server | 24.04 (LTS), 26.04 (LTS) | [Front-end Installation]({{% relref "frontend_install" %}}) | | Debian | 12, 13 | [Front-end Installation]({{% relref "frontend_install" %}}) | | SUSE Linux Enterprise | 15 | [Front-end Installation]({{% relref "frontend_install" %}}) | | openSUSE | 16 | [Front-end Installation]({{% relref "frontend_install" %}}) | @@ -45,7 +45,7 @@ Support for nodes’ operating system ensures that the latest two LTS releases f | Red Hat Enterprise Linux | 9, 10 | [KVM Driver]({{% relref "../../../product/operation_references/hypervisor_configuration/kvm_driver#kvmg" %}}) | | AlmaLinux | 9, 10 | [KVM Driver]({{% relref "../../../product/operation_references/hypervisor_configuration/kvm_driver#kvmg" %}}) | | Rocky Linux | 9, 10 | [KVM Driver]({{% relref "../../../product/operation_references/hypervisor_configuration/kvm_driver#kvmg" %}}).
Available through Red Hat packages. | -| Ubuntu Server | 22.04 (LTS), 24.04 (LTS) | [KVM Driver]({{% relref "../../../product/operation_references/hypervisor_configuration/kvm_driver#kvmg" %}}) | +| Ubuntu Server | 24.04 (LTS), 26.04 (LTS) | [KVM Driver]({{% relref "../../../product/operation_references/hypervisor_configuration/kvm_driver#kvmg" %}}) | | Debian | 12, 13 | [KVM Driver]({{% relref "../../../product/operation_references/hypervisor_configuration/kvm_driver#kvmg" %}}) | | SUSE Linux Enterprise | 15 | [KVM Driver]({{% relref "../../../product/operation_references/hypervisor_configuration/kvm_driver#kvmg" %}}) | | openSUSE | 16 | [KVM Driver]({{% relref "../../../product/operation_references/hypervisor_configuration/kvm_driver#kvmg" %}}) | @@ -55,7 +55,7 @@ Support for nodes’ operating system ensures that the latest two LTS releases f | **Component** | **Version** | **More information** | |---------------|--------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------| -| Ubuntu Server | 22.04 (LTS), 24.04 (LTS) | [LXC Driver]({{% relref "product/operation_references/hypervisor_configuration/lxc_driver#lxcmg" %}}) | +| Ubuntu Server | 24.04 (LTS), 26.04 (LTS) | [LXC Driver]({{% relref "product/operation_references/hypervisor_configuration/lxc_driver#lxcmg" %}}) | | Debian | 12, 13 | [LXC Driver]({{% relref "product/operation_references/hypervisor_configuration/lxc_driver#lxcmg" %}}) | | AlmaLinux | 9, 10 | [LXC Driver]({{% relref "product/operation_references/hypervisor_configuration/lxc_driver#lxcmg" %}}) | | Rocky Linux | 9, 10 | [LXC Driver]({{% relref "product/operation_references/hypervisor_configuration/lxc_driver#lxcmg" %}}).
Available through Red Hat packages. | @@ -92,13 +92,13 @@ More information: [one-apps wiki](https://github.com/OpenNebula/one-apps/wiki) ### Accelerated Infrastructure -| **Component** | **Models/Generations** | +| **Component** | **Models/Generations** | |-----------|--------------------------------------------| -| Ampere GPUs | A10, A30, A40, A100 | -| Ada Lovelace GPUs | L4, L40, L40S | -| Hopper GPUs | H100, H200, GH200 | -| Blackwell GPUs | B200, B300, GB200, GB300 | -| BlueField DPUs | 2, 3 | +| Ampere GPUs | A10, A30, A40, A100 | +| Ada Lovelace GPUs | L4, L40, L40S | +| Hopper GPUs | H100, H200, GH200 | +| Blackwell GPUs | B200, B300, GB200, GB300 | +| BlueField DPUs | 2, 3 | ### Authentication @@ -167,10 +167,3 @@ The following items apply to all distributions: ```default DISK = [ driver = "qcow2", cache = "writethrough" ] ``` - -### AlmaLinux 9 Platform Notes - -#### Disable Libvirtd’s SystemD Socket Activation - -OpenNebula currently works only with the legacy `livirtd.service`. You should disable libvirt’s modular daemons and systemd socket activation for the `libvirtd.service`. -You can take a look at [this](https://github.com/OpenNebula/one/issues/6143) bug report, for a detailed workaround procedure. From 5ffd89b99806c40c1ff25ff0bf9f2765ac79adda Mon Sep 17 00:00:00 2001 From: mattrowe-opennebula Date: Fri, 10 Jul 2026 16:26:29 +0200 Subject: [PATCH 21/38] M #~: Release notes updates for 7.4 (#754) This PR includes the final release notes updates for OpenNebula 7.4 Helix. --- .../opennebula_concepts/comparison.md | 2 +- .../opennebula_concepts/key_features.md | 1 + .../release_notes/acknowledgements.md | 2 ++ .../release_notes/compatibility.md | 6 ++-- .../release_notes/whats_new.md | 4 +-- .../upgrade_guide/upgrading_single.md | 28 +++++++++---------- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/content/getting_started/understand_opennebula/opennebula_concepts/comparison.md b/content/getting_started/understand_opennebula/opennebula_concepts/comparison.md index 25cbe0548..9a653297f 100644 --- a/content/getting_started/understand_opennebula/opennebula_concepts/comparison.md +++ b/content/getting_started/understand_opennebula/opennebula_concepts/comparison.md @@ -56,7 +56,7 @@ Thousands of organizations worldwide already rely on OpenNebula as an open alter | **HA and Disaster Recovery** |

HA for front-end and host nodes; redundant database and failover mechanisms for service continuity across data centers.

| | **Hybrid & Edge Cloud** |

Automatic provisioning on AWS, Scaleway and remote OpenNebula zones; optimized for edge deployments.

| | **Enhanced Platform Awareness (EPA) Integration** |

Support for NUMA\-aware CPU pinning, SR-IOV, and HugePages to provide precise hardware-level optimization and secure, performance-aware orchestration of virtualized workloads.

| -| **AI and Accelerated Computing** |

Support for NVIDIA Hopper and Blackwell GPU architectures, MIG scheduling, NVLink, Infiniband, Spectrum-X, and DPU offloading for accelerated networking, storage, and AI workloads.

| +| **AI and Accelerated Computing** |

Support for NVIDIA Hopper and Blackwell GPU architectures, NVIDIA NICo Infrastructure management, MIG scheduling, NVLink, Infiniband, Spectrum-X, and DPU offloading for accelerated networking, storage, and AI workloads.

| | **Networking Models** |

Comprehensive networking support, including DPDK, software-defined networking (SDN), virtual, and physical appliances, including Linux Bridge, 802.1Q VLAN, VXLAN, Open vSwitch; SDN integration with BlueField DPUs and Spectrum-X fabrics; IP Leasing for VM Groups.

| | **Storage Backends** |

Full support for both software-defined storage (SDS) and appliance-based storage solutions, including local storage, NFS/NAS, Disaggregated and HCI Ceph, iSCSI/FC, LVM, and specific NetApp ONTAP and Everpure FlashArray integration; support for encrypted datastores.

| | **Backup Options** |

Built\-in incremental backup system, with integration with Veeam for agentless, image-level backups, providing enterprise-grade backup and restore capabilities.

| diff --git a/content/getting_started/understand_opennebula/opennebula_concepts/key_features.md b/content/getting_started/understand_opennebula/opennebula_concepts/key_features.md index f2fc6190e..7713e0834 100644 --- a/content/getting_started/understand_opennebula/opennebula_concepts/key_features.md +++ b/content/getting_started/understand_opennebula/opennebula_concepts/key_features.md @@ -80,6 +80,7 @@ Native integration with NVIDIA technologies to deliver GPU and DPU-accelerated N * GPU Passthrough: Secure, high-performance GPU access for multi-tenant environments. * DPU Integration (BF-3): Hardware offload for networking, security, and encryption tasks. * GPU Telemetry: Real-time GPU monitoring via NVIDIA DCGM and gpu-tools. +* NVIDIA Infrastructure Controller Integration: Multi-tenant, AI Factory-scale bare-metal infrastructure management with NICo. * Inference Applications: Pre-built apps optimized for fast inference, with native integration of vLLM and Hugging Face frameworks for efficient deployment of AI and LLM workloads. * NVIDIA Ecosystem Integration: Seamless integration with the NVIDIA AI software stack, including platforms such as Run:ai and Dynamo, enabling unified orchestration, scheduling, and monitoring of AI workloads. diff --git a/content/software/release_information/release_notes/acknowledgements.md b/content/software/release_information/release_notes/acknowledgements.md index 23561f401..fc9113952 100644 --- a/content/software/release_information/release_notes/acknowledgements.md +++ b/content/software/release_information/release_notes/acknowledgements.md @@ -13,3 +13,5 @@ weight: "7" The OpenNebula project would like to thank the [community members](https://github.com/OpenNebula/one/graphs/contributors) and [users](http://opennebula.io/featuredusers/) who have contributed to this software release by being active in discussions, answering user questions, or providing patches for bugfixes, features, and documentation. + +Some of the new functionality in OpenNebula 7.2 has been made possible through funding from [ONEnextgen](http://onenextgen.eu). Funded by the Spanish Ministry for Digital Transformation and Civil Service through the ONEnextgen Project: Next-Generation European Platform for the Datacenter-Cloud-Edge Continuum (UNICO IPCEI-2023-003) and co-funded by the European Union’s NextGenerationEU instrument through the Recovery and Resilience Facility (RRF). diff --git a/content/software/release_information/release_notes/compatibility.md b/content/software/release_information/release_notes/compatibility.md index 999ae263f..3de5f2a25 100644 --- a/content/software/release_information/release_notes/compatibility.md +++ b/content/software/release_information/release_notes/compatibility.md @@ -12,9 +12,9 @@ weight: "5" -This guide is aimed at OpenNebula 7.2.x users and administrators who want to upgrade to the latest version. The following sections summarize the new features and usage changes that should be taken into account or could perhaps cause confusion. You can check the upgrade process in the [corresponding section](../../upgrade_process). If upgrading from previous versions, please make sure you read all the intermediate versions’ Compatibility Guides for possible pitfalls. +This guide is aimed at OpenNebula 7.2.x users and administrators who want to upgrade to the latest version. The following sections summarize the new features and usage changes that should be taken into account or could perhaps cause confusion. You can check the upgrade process in the [corresponding section]({{% relref "software/upgrade_process/" %}}). If upgrading from previous versions, please make sure you read all the intermediate versions’ Compatibility Guides for possible pitfalls. -Visit the [Features list](../../../getting_started/understand_opennebula/opennebula_concepts/key_features) and the [What’s New guide](whats_new#whats-new) for a comprehensive list of what’s new in OpenNebula 7.4. +Visit the [Features list]({{% relref "/getting_started/understand_opennebula/opennebula_concepts/key_features" %}}) and the [What’s New guide]({{% relref "whats_new#whats-new" %}}) for a comprehensive list of what’s new in OpenNebula 7.4. ## Daemon Logs Are No Longer Truncated on Start @@ -26,7 +26,7 @@ OpenNebula systemd services no longer force a log rotation on start. The `ExecSt To keep the old behavior for a service, add a systemd drop-in, e.g. for `opennebula`: -``` +```default # /etc/systemd/system/opennebula.service.d/logrotate.conf [Service] ExecStartPre=-/usr/sbin/logrotate -f /etc/logrotate.d/opennebula -s /var/lib/one/.logrotate.status diff --git a/content/software/release_information/release_notes/whats_new.md b/content/software/release_information/release_notes/whats_new.md index c752435f0..c004525ae 100644 --- a/content/software/release_information/release_notes/whats_new.md +++ b/content/software/release_information/release_notes/whats_new.md @@ -10,7 +10,7 @@ weight: "1" -The OpenNebula team is excited to announce the availability of OpenNebula 7.4! This release introduces a broad set of usability, automation, and operational improvements across the platform, led by a redesigned Sunstone interface that makes day-to-day cloud management more modern and intuitive. +The OpenNebula team is excited to announce the availability of **OpenNebula 7.4 "Helix"**! This release introduces a broad set of usability, automation, and operational improvements across the platform, led by a redesigned Sunstone interface that makes day-to-day cloud management more modern and intuitive. OpenNebula 7.4 also delivers important enhancements for operating virtualized infrastructure at scale, including OneSwap batch VMware migrations, improved OneDRS datastore selection, dynamic VM group management through the CLI, bulk operations for service VMs, Ubuntu 26.04 support, expanded backup capabilities with OneBEX, new VLAN group-level authorization policies, support for SR-IOV-capable PCI network interfaces in Switchdev mode with Open vSwitch, an enhanced Slurm appliance with out-of-the-box NVIDIA GPU support and LDAP identity integration, and a wide range of fixes and improvements across HA, networking, storage, monitoring, and vCenter compatibility. @@ -96,7 +96,7 @@ Thank you to our incredible community and partners for your continued support in Additionally, the following functionalities are present that were not in OpenNebula 7.2.0, although they debuted in subsequent maintenance releases of the 7.2.x series: -* [Allow the customization of the favicon in FireEdge]({{% relref "product/operation_references/opennebula_services_configuration/fireedge.md#branding-fireedge" %}}). +* [Enabled the customization of the favicon in FireEdge]({{% relref "product/operation_references/opennebula_services_configuration/fireedge.md#branding-fireedge" %}}). * Added the capacity to [batch delete scheduled actions from all service VMs]({{% relref "product/virtual_machines_operation/multi-vm_workflows/appflow_use_cli/#deleting-scheduled-actions-from-service-vms" %}}), negating the need to delete actions from each individual VM. ## Other Issues Solved diff --git a/content/software/upgrade_process/upgrade_guide/upgrading_single.md b/content/software/upgrade_process/upgrade_guide/upgrading_single.md index 97eb45b9f..71d1f4cfb 100644 --- a/content/software/upgrade_process/upgrade_guide/upgrading_single.md +++ b/content/software/upgrade_process/upgrade_guide/upgrading_single.md @@ -93,9 +93,9 @@ Before proceeding, back up the `/etc/one/sunstone-views.yaml` file. After comple Before upgrading OpenNebula, ensure that the configuration state is clean, with no pending migrations from previous or outdated configurations. To verify this, run `onecfg status`. A clean state should produce output similar to: ```default -$ onecfg status +onecfg status --- Versions ------------------------------ -OpenNebula: 7.0.0 +OpenNebula: 7.4.0 Config: 6.10.0 --- Backup to Process --------------------- @@ -103,9 +103,9 @@ Snapshot: /var/lib/one/backups/config/2025-06-27_11:05:47-v6.10.0 (will be used as one-shot source for next update) --- Available Configuration Updates ------- -New config: 7.0.0 +New config: 7.4.0 - from 6.10.0 to 6.10.2 (YAML, Ruby) -- from 6.10.2 to 7.0.0 (YAML, Ruby) +- from 6.10.2 to 7.4.0 (YAML, Ruby) ``` {{< alert title="Note" type="info" >}} @@ -118,11 +118,11 @@ After running `onecfg status`, you might encounter one of the following messages After confirming the configuration state, in most cases you can proceed with the following command, which uses OpenNebula's internal version tracking to apply the appropriate configuration updates: ```default -# onecfg upgrade +onecfg upgrade ANY : Found backed up configuration to process! ANY : Snapshot to update from '/var/lib/one/backups/config/2025-06-27_11:05:47-v6.10.0' ANY : Backup stored in '/var/lib/one/backups/config/2025-06-27_11:39:36_30392' -ANY : Configuration updated to 7.0.0 +ANY : Configuration updated to 7.4.0 ``` If you get conflicts when running the `onecfg` upgrade, refer to the [onecfg upgrade basic usage documentation]({{% relref "../configuration_management_ee/usage#cfg-usage" %}}) on how to upgrade and troubleshoot the configurations, in particular the [onecfg upgrade doc]({{% relref "../configuration_management_ee/usage#cfg-upgrade" %}}) and the [Troubleshooting section]({{% relref "../configuration_management_ee/conflicts#cfg-conflicts" %}}). @@ -131,8 +131,8 @@ Finally, check the configuration state via `onecfg status`. There should be no e ```default --- Versions ------------------------------ -OpenNebula: 7.0.0 -Config: 7.0.0 +OpenNebula: 7.4.0 +Config: 7.4.0 --- Available Configuration Updates ------- No updates available. @@ -145,8 +145,8 @@ If you have backed up `/etc/one/sunstone-views.yaml` restore the file to `/etc/o Simply run the `onedb upgrade -v` command. The connection parameters are automatically retrieved from `/etc/one/oned.conf`. Example: -```default -$ onedb upgrade -v +```shell +onedb upgrade -v Version read: Shared tables 6.10.0 : OpenNebula 6.10.0 (5d6b8571) daemon bootstrap Local tables 6.10.0 : OpenNebula 6.10.0 (5d6b8571) daemon bootstrap @@ -155,16 +155,16 @@ Sqlite database backup stored in /var/lib/one/one.db_2025-6-27_11:45:51.bck Use 'onedb restore' to restore the DB. >>> Running migrators for shared tables - > Running migrator /usr/lib/one/ruby/onedb/shared/6.10.0_to_7.0.0.rb + > Running migrator /usr/lib/one/ruby/onedb/shared/6.10.0_to_7.4.0.rb > Done in 0.00s -Database migrated from 6.10.0 to 7.0.0 (OpenNebula 7.0.0) by onedb command. +Database migrated from 6.10.0 to 7.4.0 (OpenNebula 7.4.0) by onedb command. >>> Running migrators for local tables - > Running migrator /usr/lib/one/ruby/onedb/local/6.10.0_to_7.0.0.rb + > Running migrator /usr/lib/one/ruby/onedb/local/6.10.0_to_7.4.0.rb > Done in 0.08s -Database migrated from 6.10.0 to 7.0.0 (OpenNebula 7.0.0) by onedb command. +Database migrated from 6.10.0 to 7.4.0 (OpenNebula 7.4.0) by onedb command. Total time: 0.12s ``` From ed432c8de6142e4117bc0047741765fdca691d5d Mon Sep 17 00:00:00 2001 From: Jan Orel Date: Mon, 13 Jul 2026 11:48:19 +0200 Subject: [PATCH 22/38] M #-: Add SLES/openSUSE upgrade instructions (#757) --- .../upgrade_guide/upgrading_single.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/content/software/upgrade_process/upgrade_guide/upgrading_single.md b/content/software/upgrade_process/upgrade_guide/upgrading_single.md index 71d1f4cfb..1ea039b58 100644 --- a/content/software/upgrade_process/upgrade_guide/upgrading_single.md +++ b/content/software/upgrade_process/upgrade_guide/upgrading_single.md @@ -76,10 +76,18 @@ apt-get install --only-upgrade opennebula opennebula-gate opennebula-flow openne RHEL ```bash -yum upgrade opennebula opennebula-gate opennebula-flow opennebula-fireedge opennebula-migration python3-pyone +yum upgrade opennebula opennebula-gate opennebula-flow opennebula-fireedge opennebula-form opennebula-guacd opennebula-migration python3-pyone ``` - +SLES/openSUSE + +```bash +zypper refresh +zypper update opennebula opennebula-gate opennebula-flow opennebula-fireedge opennebula-form opennebula-guacd opennebula-migration python313-pyone +``` + +{{< alert title="Warning" type="warning" >}} +The Python bindings package is named after the Python version of the distribution: use `python313-pyone` on openSUSE 16 and `python311-pyone` on SLES 15. {{< /alert >}} ### Step 7. Update Configuration Files @@ -226,7 +234,12 @@ RHEL yum upgrade opennebula-node- ``` - +SLES/openSUSE + +```bash +zypper refresh +zypper update opennebula-node- +``` {{< alert title="Note" type="info" >}} Note that the `` tag should be replaced by the name of the corresponding hypervisor (i.e., `kvm` or `lxc`).{{< /alert >}} From 91fd5053728f3eb2bdd934893c2403cf18bdc340 Mon Sep 17 00:00:00 2001 From: Dmitrii Gilev Date: Mon, 13 Jul 2026 12:36:25 +0200 Subject: [PATCH 23/38] F OpenNebula-one#7609: Document S3 support for Restic backup datastore (#758) Signed-off-by: Dmitrii Gilev --- .../backup_system/restic.md | 151 +++++++++++++++--- 1 file changed, 126 insertions(+), 25 deletions(-) diff --git a/content/product/cluster_configuration/backup_system/restic.md b/content/product/cluster_configuration/backup_system/restic.md index a67e3fa2b..bec372f0b 100644 --- a/content/product/cluster_configuration/backup_system/restic.md +++ b/content/product/cluster_configuration/backup_system/restic.md @@ -13,23 +13,30 @@ weight: "2" -[Restic](https://restic.net/) is an open source (BSD 2-Clause License) backup tool designed for speed, security, and efficiency. The current implementation of the driver uses the SFTP storage type. Restic offers interesting features to store backups, like deduplication (only transferring image blobs not already present in the repository) or compression (enabled by default). +[Restic](https://restic.net/) is an open source (BSD 2-Clause License) backup tool designed for speed, security, and efficiency. The current implementation of the driver supports SFTP and S3 storage types. Restic offers interesting features to store backups, like deduplication (only transferring image blobs not already present in the repository) or compression (enabled by default). In both the Enterprise and Community editions of OpenNebula, the correct version of restic is included as a dependency. In this guide we will use the following terminology (introduced by restic): -- *Repository*: This is the storage volume where the disk images backups will be stored. Restic creates a specific interval structure to store the backups efficiently. The restic driver accesses the repository through the sftp. protocol. OpenNebula will create a separate restic repository for each VM or backup job. +- *Repository*: This is the storage location where VM disk backups will be stored. Depending on the selected backend, it can be a directory on an SFTP backup server or a path inside an S3 bucket. Restic creates a specific internal structure to store the backups efficiently. OpenNebula will create a separate restic repository for each VM or backup job. - *Snapshot*: It represents a backup and it is referenced by a unique hash (e.g., `eda52f34`). Each snapshot stores a VM backup and includes the backed up disks and the metadata description of the VM at the time you make the backup. -- *Backup Server*: A Host that will store the VM backups and the restic repositories. +- *Backup Server*: A Host that stores VM backups and restic repositories when using the SFTP backend. +- *S3 Bucket*: An AWS S3 or S3-compatible bucket that stores the restic repositories when using the S3 backend. -## Step 1. [Backup Server] Set up the backup server +## Step 1. Backend Configuration -The first thing you need to do is set up a server to hold the restic repository. Typically the server will have a dedicated storage medium dedicated to store the backups (e.g., iSCSI volume). Also, the Hosts and Front-end need to reach the server IP. +The first thing you need to do is prepare the storage backend that will hold the restic repositories. The required setup depends on the backend selected for the datastore. -To set up the server perform the following steps: +The restic repository itself does not need to be created manually. OpenNebula initializes the repository automatically during the first backup, using the datastore configuration. + +### SFTP Backend + +For the SFTP backend, set up a backup server to hold the restic repositories. Typically the server will have a dedicated storage medium to store the backups (e.g., iSCSI volume). Also, the Hosts and Front-end need to reach the server IP. + +To set up the backup server perform the following steps: - Create a user account with username `oneadmin`. This account will be used to connect to the server. - Copy the SSH public key of existing `oneadmin` from the OpenNebula Front-end to this new `oneadmin` account. -- Check that `oneadmin` can SSH access the server **without being prompt for a password** from the Front-end and Hosts. +- Check that `oneadmin` can SSH access the server **without being prompted for a password** from the Front-end and Hosts. - Create the following folder in the backup server `/var/lib/one/datastores`, change the ownership to `oneadmin`. - Mount the storage volume in `/var/lib/one/datastores`. - Finally make sure **rsync** and **qemu-img** commands are installed in the backup server. @@ -53,9 +60,23 @@ $ ls -ld /var/lib/one/datastores/ drwxrwxr-x 2 oneadmin oneadmin 4096 Sep 3 12:04 /var/lib/one/datastores/ ``` +### S3 Backend + +For the S3 backend, prepare an AWS S3 bucket or an S3-compatible bucket before creating the OpenNebula Backup Datastore. The bucket must be reachable from the Front-end and Hosts. + +The S3 credentials configured in the datastore must allow OpenNebula to list the bucket and to create, read, and delete objects in it. + +For AWS S3, use an access key and secret access key with permissions for the target bucket. For S3-compatible backends, use the equivalent credentials and enable path-style access if required by the service. + +If the S3 endpoint uses a private CA certificate, make the CA certificate file available on the KVM Hosts where restic commands run. For lab or debugging environments, TLS verification can also be disabled in the datastore configuration. + ## Step 2. [Front-end] Create a Restic Datastore -Now that we have the backup server prepared, let’s create an OpenNebula Backup Datastore. We just need to pick a password to access our repository and create a datastore template: +Create an OpenNebula Backup Datastore with the attributes required by the selected backend. The `RESTIC_PASSWORD` attribute is used by restic to encrypt and access the repository. + +### SFTP Backend + +For SFTP, create a datastore template with the backup server address. `RESTIC_BACKEND` can be omitted because SFTP is the default backend. ```default $ cat ds_restic.txt @@ -65,11 +86,12 @@ TYPE = "BACKUP_DS" DS_MAD = "restic" TM_MAD = "-" +RESTIC_BACKEND = "SFTP" RESTIC_PASSWORD = "opennebula" RESTIC_SFTP_SERVER = "192.168.1.8" ``` -*Note*: The `RESTIC_SFTP_SERVER` is the IP address of the backup server, it needs to be reachable from the Front-end and Hosts. +*Note*: The `RESTIC_SFTP_SERVER` is the IP address of the backup server. It needs to be reachable from the Front-end and Hosts. ```default $ onedatastore create ds_restic.txt @@ -91,7 +113,65 @@ ID NAME SIZE AVA CLUSTERS IMAGES TYPE D 0 system - - 0 0 sys - local on ``` -That’s it, we are all set to make VM backups! +### AWS S3 Backend + +For AWS S3, use `RESTIC_BACKEND="S3"`. The endpoint can be omitted, in which case it defaults to `s3.amazonaws.com`, and path-style access is normally not required. + +```default +$ cat ds_restic_aws_s3.txt +NAME = "RBackups-AWS-S3" +TYPE = "BACKUP_DS" + +DS_MAD = "restic" +TM_MAD = "-" + +RESTIC_BACKEND = "S3" +RESTIC_PASSWORD = "opennebula" +RESTIC_S3_BUCKET = "opennebula-backups" +RESTIC_S3_REGION = "us-west-1" +RESTIC_S3_ACCESS_KEY_ID = "S3ACCESSKEYID" +RESTIC_S3_SECRET_ACCESS_KEY = "S3SECRETACCESSKEY" +TOTAL_MB = "512000" +``` + +```default +$ onedatastore create ds_restic_aws_s3.txt +ID: 101 +``` + +### S3-Compatible Backend + +For non-AWS S3-compatible backends, create a datastore template with `RESTIC_BACKEND="S3"` and set the S3 endpoint explicitly. The endpoint can include the scheme; for plain HTTP endpoints, specify it explicitly, for example `http://s3-storage:8080`. Many S3-compatible backends require path-style access. In that case set `RESTIC_S3_FORCE_PATH_STYLE="YES"`. + +```default +$ cat ds_restic_s3.txt +NAME = "RBackups-S3" +TYPE = "BACKUP_DS" + +DS_MAD = "restic" +TM_MAD = "-" + +RESTIC_BACKEND = "S3" +RESTIC_PASSWORD = "opennebula" +RESTIC_S3_ENDPOINT = "http://s3-storage:8080" +RESTIC_S3_BUCKET = "opennebula-backups" +RESTIC_S3_ACCESS_KEY_ID = "S3ACCESSKEYID" +RESTIC_S3_SECRET_ACCESS_KEY = "S3SECRETACCESSKEY" +RESTIC_S3_FORCE_PATH_STYLE = "YES" +TOTAL_MB = "512000" +``` + +```default +$ onedatastore create ds_restic_s3.txt +ID: 102 +``` + +For S3 datastores, OpenNebula does not discover the bucket quota automatically. The total capacity is taken from the `TOTAL_MB` datastore attribute. The examples above set `TOTAL_MB="512000"` to configure a custom `500G` capacity. If `TOTAL_MB` is omitted, the driver uses `1048576` MB (`1024G`) as the default capacity. Used capacity is computed from backup images registered in OpenNebula. + +OpenNebula creates a separate restic repository inside the SFTP path or S3 bucket for each VM or backup job. + +{{< alert title="Note" type="info" >}} +At this time, S3 Restic datastore creation is expected to be performed through the CLI, or through the standard XML-RPC datastore allocation API by passing the datastore template attributes shown above. No new XML-RPC method is required for the driver itself: once the Backup Datastore exists, backup and restore operations use the regular OpenNebula backup APIs. FireEdge configuration support for S3-specific attributes will be added in future releases.{{< /alert >}} ## Repository Maintenance and Troubleshooting @@ -153,9 +233,8 @@ This feature is only supported for **shared system datastores** (currently only All Hosts listed in `BRIDGE_LIST` must meet the following requirements: - Must have **network access** to the Backup Datastore. -- Must be able to establish **passwordless SSH connections** to: - - The **OpenNebula Frontend** - - The **Backup Server** +- Must be able to establish **passwordless SSH connections** to the **OpenNebula Front-end**. +- For the SFTP backend, must be able to establish **passwordless SSH connections** to the **Backup Server**. During the backup process: @@ -167,19 +246,41 @@ During the backup process: ## Reference: Restic Datastore Attributes +### Common Attributes + | Attribute | Description | |----------------------|-------------------------------------------------------------------------------------------------------------| -| `RESTIC_SFTP_USER` | User to connect to the backup server (default `oneadmin`) | -| `RESTIC_SFTP_SERVER` | IP address of the backup server | -| `RESTIC_PASSWORD` | Password to access the restic repository | -| `RESTIC_IONICE` | Run backups under a given ionice priority (best-effort, class 2). Value: 0 (high) - 7 (low) | -| `RESTIC_NICE` | Run backups under a given nice. Value: -19 (high) to 19 (low) | -| `RESTIC_MAX_RIOPS` | Run backups in a systemd slice, limiting the max number of read iops | -| `RESTIC_MAX_WIOPS` | Run backups in a systemd slice, limiting the max number of write iops | -| `RESTIC_CPU_QUOTA` | Run backups in a systemd slice with a given cpu quota (percentage). Use > 100 for using several CPUs | -| `RESTIC_BWLIMIT` | Limit restic upload/download bandwidth | -| `RESTIC_COMPRESSION` | Compression (three modes:off, auto, max), default is `auto` (average compression without to much CPU usage) | +| `RESTIC_BACKEND` | Restic backend to use. Allowed values: `SFTP`, `S3`. Defaults to `SFTP` when omitted. | +| `RESTIC_PASSWORD` | Password to access the restic repository. | +| `RESTIC_IONICE` | Run backups under a given ionice priority (best-effort, class 2). Value: 0 (high) - 7 (low). | +| `RESTIC_NICE` | Run backups under a given nice. Value: -19 (high) to 19 (low). | +| `RESTIC_MAX_RIOPS` | Run backups in a systemd slice, limiting the max number of read IOPS. | +| `RESTIC_MAX_WIOPS` | Run backups in a systemd slice, limiting the max number of write IOPS. | +| `RESTIC_CPU_QUOTA` | Run backups in a systemd slice with a given CPU quota (percentage). Use > 100 for using several CPUs. | +| `RESTIC_BWLIMIT` | Limit restic upload/download bandwidth. | +| `RESTIC_COMPRESSION` | Compression (three modes: off, auto, max), default is `auto` (average compression without too much CPU use). | | `RESTIC_CONNECTIONS` | Number of concurrent connections (default 5). For high-latency backends this number can be increased. | | `RESTIC_MAXPROC` | Sets `GOMAXPROCS` for restic to limit the OS threads that execute user-level Go code simultaneously. | -| `RESTIC_SPARSIFY` | Runs `virt-sparsify` on flatten backups to reduce backup size. It requires `libguestfs` package. | -| `BRIDGE_LIST` | List of hosts responsible for transferring VM backups from the hypervisor to the Backup Datastore | +| `RESTIC_SPARSIFY` | Runs `virt-sparsify` on flatten backups to reduce backup size. It requires the `libguestfs` package. | +| `BRIDGE_LIST` | List of hosts responsible for transferring VM backups from the hypervisor to the Backup Datastore. | + +### SFTP Backend Attributes + +| Attribute | Description | +|----------------------|-----------------------------------------------------------------| +| `RESTIC_SFTP_USER` | User to connect to the backup server (default `oneadmin`). | +| `RESTIC_SFTP_SERVER` | IP address of the backup server. Mandatory for the SFTP backend. | + +### S3 Backend Attributes + +| Attribute | Description | +|-------------------------------|-------------------------------------------------------------------------------------------------------------| +| `RESTIC_S3_ACCESS_KEY_ID` | S3 access key ID. Mandatory for the S3 backend. | +| `RESTIC_S3_SECRET_ACCESS_KEY` | S3 secret access key. Mandatory for the S3 backend. Stored encrypted in OpenNebula. | +| `RESTIC_S3_BUCKET` | S3 bucket name only, without endpoint URL. Mandatory for the S3 backend. | +| `RESTIC_S3_REGION` | S3 region. Optional, defaults to `us-east-1` when omitted. | +| `RESTIC_S3_ENDPOINT` | S3 endpoint. Defaults to `s3.amazonaws.com` for AWS S3. Mandatory for non-AWS S3-compatible backends. Can include a scheme, e.g. `http://s3-storage:8080`. | +| `RESTIC_S3_FORCE_PATH_STYLE` | Use `YES` to force path-style S3 access. Needed for many non-AWS S3-compatible backends. | +| `RESTIC_S3_CACERT` | Path to a custom CA certificate file available on the KVM Hosts where restic commands run. | +| `RESTIC_S3_INSECURE_TLS` | Use `YES` to disable TLS certificate verification. Intended for lab or debug environments only. | +| `TOTAL_MB` | Datastore capacity in MB for S3 monitoring. Defaults to `1048576` MB (`1024G`). | From ebc6449d489da6fea5ebeab887b084d1461e29f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20Czern=C3=BD?= Date: Mon, 13 Jul 2026 13:07:12 +0200 Subject: [PATCH 24/38] M #-: Update one.vmpool.info filter description (#759) --- content/product/integration_references/system_interfaces/api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/product/integration_references/system_interfaces/api.md b/content/product/integration_references/system_interfaces/api.md index 8c70727da..64d09e284 100644 --- a/content/product/integration_references/system_interfaces/api.md +++ b/content/product/integration_references/system_interfaces/api.md @@ -1441,7 +1441,7 @@ Some attributes e.g. `TEMPLATE`, `USER_TEMPLATE` are limited in this call, see a | IN | Int | When the next parameter is >= -1 this is the Range start ID.
Can be -1. For smaller values this is the offset used for pagination. | | IN | Int | For values >= -1 this is the Range end ID. Can be -1 to get until the
last ID. For values < -1 this is the page size used for pagination. | | IN | Int | VM state to filter by. | -| IN | String | Filter in KEY=VALUE format. | +| IN | String | Filter using [json syntax]({{% relref "vm_instances.md#vm-search" %}}): `VM.KEY1=VALUE1&VM.KEY2=VALUE2`. | | OUT | Boolean | true or false whenever is successful or not | | OUT | String | Version of the VM Pool with a short VM body documents. | | OUT | Int | Error code. | From ed424f5fe6c278ddbb13a3c9cd112a65ca19ea7a Mon Sep 17 00:00:00 2001 From: mattrowe-opennebula Date: Mon, 13 Jul 2026 13:14:07 +0200 Subject: [PATCH 25/38] M #~: Release notes fixes after feedback (#760) This PR introduces fixes and updates to the 7.4 release notes after feedback. --- .../common/dark/sunstone_dashboard.png | Bin 0 -> 412521 bytes .../common/light/sunstone_dashboard.png | Bin 0 -> 411719 bytes .../frontend_installation/automated.md | 5 +++ .../release_notes/acknowledgements.md | 2 +- .../release_notes/compatibility.md | 4 +++ .../release_notes/whats_new.md | 33 +++++++++++------- 6 files changed, 31 insertions(+), 13 deletions(-) create mode 100644 assets/images/sunstone/common/dark/sunstone_dashboard.png create mode 100644 assets/images/sunstone/common/light/sunstone_dashboard.png diff --git a/assets/images/sunstone/common/dark/sunstone_dashboard.png b/assets/images/sunstone/common/dark/sunstone_dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..e2e41718fa185034b6b65aa3f66287e84bfeb894 GIT binary patch literal 412521 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%0Dy8|!J$pQD3fHu5o;MkiYcwu7|) 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%0AQX+- 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 Wo{Fv4@&EQ`Om14-C^xwC@P7fXCGleb literal 0 HcmV?d00001 diff --git a/assets/images/sunstone/common/light/sunstone_dashboard.png b/assets/images/sunstone/common/light/sunstone_dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..c16dfc32d6c7f1148e82578073e354ece41079df GIT binary patch literal 411719 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