OpenNebula is an open-source cloud computing platform designed to manage virtualized data centers. It supports KVM, LXC, Firecracker, and VMware hypervisors, giving you a flexible foundation for building private and hybrid clouds. One of its practical strengths is the ability to import pre-built qcow2 cloud images directly into its image datastore, so you can spin up virtual machines in minutes without going through a full OS installation.

In this guide, we will walk through downloading official cloud images for Rocky Linux 10, AlmaLinux 10, Debian 13 (Trixie), and Ubuntu, then importing them into OpenNebula. We will cover both the Sunstone web UI and the CLI approach using oneimage and onetemplate commands. Every step includes verification so you can confirm things are working before moving on.

Prerequisites

  • A running OpenNebula installation (version 6.x or later) with at least one KVM host
  • SSH access to the OpenNebula front-end node
  • The oneadmin user credentials or appropriate CLI access
  • Sufficient storage in your image datastore (at least 10 GB free per image)
  • wget or curl installed on the front-end

Step 1 – Download Official Cloud Images

All major Linux distributions publish cloud-ready qcow2 images that include cloud-init out of the box. These images are minimal, pre-configured for cloud environments, and ready to accept contextualization data on first boot.

Where to Find Official Cloud Images

Here are the official download locations for each distribution:

Download Rocky Linux 10 Qcow2 Image

Log into your OpenNebula front-end node and download the Rocky Linux 10 GenericCloud image:

wget https://dl.rockylinux.org/pub/rocky/10/images/x86_64/Rocky-10-GenericCloud-Base.latest.x86_64.qcow2 -O /var/tmp/Rocky-10-GenericCloud.qcow2

Alternatively, use curl:

curl -L -o /var/tmp/Rocky-10-GenericCloud.qcow2 https://dl.rockylinux.org/pub/rocky/10/images/x86_64/Rocky-10-GenericCloud-Base.latest.x86_64.qcow2

Download AlmaLinux 10 Qcow2 Image

wget https://repo.almalinux.org/almalinux/10/cloud/x86_64/images/AlmaLinux-10-GenericCloud-latest.x86_64.qcow2 -O /var/tmp/AlmaLinux-10-GenericCloud.qcow2

Download Debian 13 (Trixie) Qcow2 Image

wget https://cloud.debian.org/images/cloud/trixie/daily/latest/debian-13-genericcloud-amd64-daily.qcow2 -O /var/tmp/Debian-13-GenericCloud.qcow2

Verify Downloads

Check the file sizes and format to confirm you have valid qcow2 images:

ls -lh /var/tmp/*.qcow2
qemu-img info /var/tmp/Rocky-10-GenericCloud.qcow2

The qemu-img info output should show file format: qcow2 and the virtual size of the disk. If you see anything different, the download may be incomplete or corrupted – download it again.

Step 2 – Import Qcow2 Images into OpenNebula (CLI Method)

OpenNebula uses the oneimage command to manage images in its datastore. We will create an image template file and register each image.

Create Image Template for Rocky Linux 10

First, create an image template file:

cat <<EOF > /var/tmp/rocky10-image.tpl
NAME = "Rocky Linux 10 Cloud"
PATH = "/var/tmp/Rocky-10-GenericCloud.qcow2"
TYPE = OS
PERSISTENT = NO
DRIVER = qcow2
FORMAT = qcow2
DESCRIPTION = "Rocky Linux 10 GenericCloud qcow2 image for OpenNebula"
EOF

Key attributes explained:

  • TYPE = OS – Marks this as an operating system disk image (as opposed to DATABLOCK or CDROM)
  • PERSISTENT = NO – Each VM gets its own copy of the image, keeping the original clean for reuse
  • DRIVER = qcow2 – Tells the hypervisor which disk driver to use
  • FORMAT = qcow2 – Specifies the image format so OpenNebula handles it correctly

Now register the image in the default datastore (datastore ID 1):

oneimage create /var/tmp/rocky10-image.tpl -d 1

You should see output like:

ID: 0

Create Image Template for AlmaLinux 10

cat <<EOF > /var/tmp/alma10-image.tpl
NAME = "AlmaLinux 10 Cloud"
PATH = "/var/tmp/AlmaLinux-10-GenericCloud.qcow2"
TYPE = OS
PERSISTENT = NO
DRIVER = qcow2
FORMAT = qcow2
DESCRIPTION = "AlmaLinux 10 GenericCloud qcow2 image for OpenNebula"
EOF

oneimage create /var/tmp/alma10-image.tpl -d 1

Create Image Template for Debian 13

cat <<EOF > /var/tmp/debian13-image.tpl
NAME = "Debian 13 Trixie Cloud"
PATH = "/var/tmp/Debian-13-GenericCloud.qcow2"
TYPE = OS
PERSISTENT = NO
DRIVER = qcow2
FORMAT = qcow2
DESCRIPTION = "Debian 13 Trixie GenericCloud qcow2 image for OpenNebula"
EOF

oneimage create /var/tmp/debian13-image.tpl -d 1

Verify Image Registration

Check that all images have been registered and are in the READY state:

oneimage list

Expected output:

  ID USER     GROUP    NAME                        DATASTORE  SIZE TYPE PER STAT  RVMS
   0 oneadmin oneadmin Rocky Linux 10 Cloud        default    10G OS    No rdy      0
   1 oneadmin oneadmin AlmaLinux 10 Cloud          default    10G OS    No rdy      0
   2 oneadmin oneadmin Debian 13 Trixie Cloud      default    10G OS    No rdy      0

The STAT column should show rdy (ready). If it shows lock, the image is still being copied to the datastore – wait a moment and check again. If it shows err, check the image log:

oneimage show <IMAGE_ID>

Step 3 – Import Qcow2 Images via Sunstone Web UI

If you prefer a graphical interface, OpenNebula’s Sunstone UI makes the import process straightforward.

  1. Log into Sunstone at http://your-opennebula-host:9869
  2. Navigate to Storage > Images in the left sidebar
  3. Click the + (Create) button
  4. Fill in the image details:
    • Name: Rocky Linux 10 Cloud
    • Type: OS
    • Datastore: Select your image datastore (usually “default”)
    • Persistent: Leave unchecked for non-persistent
  5. Under Image location, choose one of:
    • Upload – Browse and select the qcow2 file from your local machine
    • Path in OpenNebula server – Enter /var/tmp/Rocky-10-GenericCloud.qcow2 if the file is already on the front-end
  6. Under Advanced Options, set:
    • Driver: qcow2
    • Format: qcow2
  7. Click Create

Repeat for AlmaLinux 10 and Debian 13 images. Watch the image list until the state changes from LOCKED to READY.

Step 4 – Configure Image Attributes

After importing, you may want to adjust image attributes depending on your environment. Here are some common adjustments.

Make an Image Persistent

If you want changes made inside the VM to persist back to the image (useful for golden image workflows):

oneimage persistent <IMAGE_ID>

To revert to non-persistent:

oneimage nonpersistent <IMAGE_ID>

Change Image Permissions

To allow other users in your OpenNebula installation to use the image:

oneimage chmod <IMAGE_ID> 644

Resize the Image

Cloud images typically ship with small virtual disks (around 2-10 GB). You can resize them in the VM template later, or resize the image itself:

oneimage resize <IMAGE_ID> 20480

The size is specified in megabytes. The example above sets it to 20 GB.

Step 5 – Create a VM Template (CLI Method)

With the images registered, the next step is creating a VM template that references the image and includes contextualization settings for cloud-init.

Rocky Linux 10 VM Template

cat <<EOF > /var/tmp/rocky10-vm.tpl
NAME = "Rocky Linux 10 VM"
CPU = 1
VCPU = 2
MEMORY = 2048
OS = [
  ARCH = "x86_64",
  BOOT = "disk0"
]
DISK = [
  IMAGE = "Rocky Linux 10 Cloud",
  IMAGE_UNAME = "oneadmin",
  SIZE = 20480,
  DRIVER = "qcow2"
]
NIC = [
  NETWORK = "vnet",
  NETWORK_UNAME = "oneadmin"
]
GRAPHICS = [
  TYPE = "VNC",
  LISTEN = "0.0.0.0"
]
CONTEXT = [
  NETWORK = "YES",
  SSH_PUBLIC_KEY = "\$USER[SSH_PUBLIC_KEY]",
  USERNAME = "rocky",
  SET_HOSTNAME = "\$NAME"
]
EOF

Register the template:

onetemplate create /var/tmp/rocky10-vm.tpl

AlmaLinux 10 VM Template

cat <<EOF > /var/tmp/alma10-vm.tpl
NAME = "AlmaLinux 10 VM"
CPU = 1
VCPU = 2
MEMORY = 2048
OS = [
  ARCH = "x86_64",
  BOOT = "disk0"
]
DISK = [
  IMAGE = "AlmaLinux 10 Cloud",
  IMAGE_UNAME = "oneadmin",
  SIZE = 20480,
  DRIVER = "qcow2"
]
NIC = [
  NETWORK = "vnet",
  NETWORK_UNAME = "oneadmin"
]
GRAPHICS = [
  TYPE = "VNC",
  LISTEN = "0.0.0.0"
]
CONTEXT = [
  NETWORK = "YES",
  SSH_PUBLIC_KEY = "\$USER[SSH_PUBLIC_KEY]",
  USERNAME = "almalinux",
  SET_HOSTNAME = "\$NAME"
]
EOF

onetemplate create /var/tmp/alma10-vm.tpl

Debian 13 VM Template

cat <<EOF > /var/tmp/debian13-vm.tpl
NAME = "Debian 13 Trixie VM"
CPU = 1
VCPU = 2
MEMORY = 2048
OS = [
  ARCH = "x86_64",
  BOOT = "disk0"
]
DISK = [
  IMAGE = "Debian 13 Trixie Cloud",
  IMAGE_UNAME = "oneadmin",
  SIZE = 20480,
  DRIVER = "qcow2"
]
NIC = [
  NETWORK = "vnet",
  NETWORK_UNAME = "oneadmin"
]
GRAPHICS = [
  TYPE = "VNC",
  LISTEN = "0.0.0.0"
]
CONTEXT = [
  NETWORK = "YES",
  SSH_PUBLIC_KEY = "\$USER[SSH_PUBLIC_KEY]",
  USERNAME = "debian",
  SET_HOSTNAME = "\$NAME"
]
EOF

onetemplate create /var/tmp/debian13-vm.tpl

Verify Templates

onetemplate list

You should see all three templates listed with their IDs.

Step 6 – Create a VM Template via Sunstone UI

  1. In Sunstone, go to Templates > VMs
  2. Click the + (Create) button
  3. On the General tab:
    • Name: Rocky Linux 10 VM
    • Memory: 2048 MB
    • CPU: 1
    • VCPU: 2
  4. On the Storage tab:
    • Click + Add disk
    • Select the “Rocky Linux 10 Cloud” image
    • Set Size to 20 GB
  5. On the Network tab:
    • Click + Add NIC
    • Select your virtual network
  6. On the Context tab:
    • Check Add Network Contextualization
    • Under SSH Public Key, select “Add SSH contextualization” and paste your public key or choose to use the user’s stored key
    • Set USERNAME to rocky (or almalinux / debian depending on the image)
  7. On the Input/Output tab:
    • Add a VNC graphics device for console access
  8. Click Create

Step 7 – Configure Contextualization (Cloud-Init and Networking)

OpenNebula supports two contextualization methods: its native contextualization packages and cloud-init. The cloud images we downloaded already include cloud-init, so both approaches work.

OpenNebula Native Contextualization

The CONTEXT section in our templates above uses OpenNebula’s native approach. When NETWORK = "YES" is set, OpenNebula generates network configuration scripts and injects them into the VM via a virtual CD-ROM. The cloud image picks this up on boot and configures networking automatically.

For this to work with cloud images that do not have the OpenNebula contextualization packages pre-installed, you may need to add them. On RHEL-based images (Rocky, Alma), you can include a start script:

CONTEXT = [
  NETWORK = "YES",
  SSH_PUBLIC_KEY = "$USER[SSH_PUBLIC_KEY]",
  USERNAME = "rocky",
  SET_HOSTNAME = "$NAME",
  START_SCRIPT = "yum install -y https://github.com/OpenNebula/addon-context-linux/releases/download/v6.10.0/one-context-6.10.0-1.el9.noarch.rpm"
]

Cloud-Init Contextualization

If you prefer cloud-init, OpenNebula can generate cloud-init compatible data. Add the following to your template’s CONTEXT section:

CONTEXT = [
  NETWORK = "YES",
  SSH_PUBLIC_KEY = "$USER[SSH_PUBLIC_KEY]",
  USERNAME = "rocky",
  SET_HOSTNAME = "$NAME",
  USER_DATA = "#cloud-config
packages:
  - qemu-guest-agent
runcmd:
  - systemctl enable --now qemu-guest-agent
"
]

This lets you pass arbitrary cloud-config YAML to the instance at boot time, which is useful for installing extra packages, running setup scripts, or customizing the system.

Network Configuration

Make sure your OpenNebula virtual network is properly configured before launching VMs. Verify your network exists:

onevnet list

If you need to create a basic bridged network:

cat <<EOF > /var/tmp/vnet.tpl
NAME = "vnet"
VN_MAD = "bridge"
BRIDGE = "br0"
AR = [
  TYPE = "IP4",
  IP = "192.168.1.100",
  SIZE = "50"
]
DNS = "8.8.8.8"
GATEWAY = "192.168.1.1"
NETWORK_MASK = "255.255.255.0"
EOF

onevnet create /var/tmp/vnet.tpl

Adjust the IP range, gateway, and bridge name to match your actual network setup.

Step 8 – Launch a VM Instance

Launch via CLI

Instantiate a VM from the Rocky Linux 10 template:

onetemplate instantiate "Rocky Linux 10 VM" --name rocky10-test-01

This returns the VM ID. Check its status:

onevm list

Wait until the STAT column shows runn (running). If it shows pend, the scheduler has not placed it yet – this usually resolves within a few seconds. If it stays in pend, check that your host has enough resources:

onehost list

Get full details about the running VM, including its IP address:

onevm show rocky10-test-01

Look for the ETH0_IP field in the output to find the assigned IP address.

Launch via Sunstone UI

  1. Go to Templates > VMs
  2. Select the template you want to use
  3. Click Instantiate
  4. Optionally set a name for the VM
  5. Adjust any parameters if needed
  6. Click Instantiate
  7. Navigate to Instances > VMs to monitor the deployment

Step 9 – Verify SSH Access

Once the VM is in the RUNNING state, give it about 30-60 seconds for cloud-init to finish its first-boot configuration, then try connecting via SSH.

For Rocky Linux 10:

ssh rocky@<VM_IP_ADDRESS>

For AlmaLinux 10:

ssh almalinux@<VM_IP_ADDRESS>

For Debian 13:

ssh debian@<VM_IP_ADDRESS>

After logging in, run a few checks to confirm the VM is working properly:

# Check OS release
cat /etc/os-release

# Check disk space (confirm disk was resized)
df -h /

# Check network connectivity
ip addr show
ping -c 3 8.8.8.8

# Check cloud-init status
cloud-init status

If the disk shows the original small size instead of the 20 GB you configured, cloud-init may not have run the disk resize module. You can grow the partition manually:

# For RHEL-based (Rocky, Alma)
sudo growpart /dev/vda 1
sudo xfs_growfs /

# For Debian
sudo growpart /dev/vda 1
sudo resize2fs /dev/vda1

Troubleshooting

Image Stuck in LOCKED State

If an image stays in the LOCKED state for more than a few minutes, check the OpenNebula logs:

tail -50 /var/log/one/oned.log

Common causes include insufficient disk space in the datastore or file permission problems. Verify the oneadmin user can read the source qcow2 file:

ls -la /var/tmp/*.qcow2
# Files should be readable by oneadmin

Image Shows ERROR State

Get the error message from the image details:

oneimage show <IMAGE_ID> | grep ERROR

If the error is related to format, make sure you specified DRIVER = qcow2 and FORMAT = qcow2 in the image template. To fix an existing image, delete it and re-create with the correct attributes:

oneimage delete <IMAGE_ID>
oneimage create /var/tmp/rocky10-image.tpl -d 1

VM Stays in PENDING State

This means the scheduler cannot find a suitable host. Check host availability:

onehost list
tail -50 /var/log/one/sched.log

Make sure at least one host is in the on state and has enough free CPU and memory for the VM.

Cannot SSH into VM

If the VM is running but you cannot connect via SSH:

  1. Use the VNC console in Sunstone to access the VM directly and check if it booted properly
  2. Check that your SSH public key was injected correctly:
    cat /home/rocky/.ssh/authorized_keys
  3. Verify the network is configured inside the VM:
    ip addr show
  4. Check that cloud-init ran without errors:
    cat /var/log/cloud-init.log | tail -30
  5. Make sure your OpenNebula virtual network has the correct gateway and that routing works between your client and the VM network

Cloud-Init Not Running

Some cloud images require the contextualization data to be presented in a specific format. If cloud-init is not picking up your configuration:

# Check cloud-init datasource
cloud-init query ds

# Check what cloud-init detected
cloud-init status --long

# Re-run cloud-init manually
sudo cloud-init clean
sudo cloud-init init

You may need to install the OpenNebula contextualization packages alongside cloud-init for best results. These packages translate OpenNebula’s context data into a format cloud-init can consume.

Disk Performance Issues

If you notice slow disk I/O inside the VM, check the disk cache and I/O settings in your template. Adding cache and I/O tuning to the DISK section can help:

DISK = [
  IMAGE = "Rocky Linux 10 Cloud",
  IMAGE_UNAME = "oneadmin",
  SIZE = 20480,
  DRIVER = "qcow2",
  CACHE = "writeback",
  IO = "threads",
  DISCARD = "unmap"
]

Clean Up Downloaded Files

Once all images are registered and in the READY state, you can safely remove the downloaded qcow2 files from the front-end to free up space:

rm -f /var/tmp/*.qcow2 /var/tmp/*-image.tpl /var/tmp/*-vm.tpl /var/tmp/vnet.tpl

Verify the images are still intact in the datastore:

oneimage list

Summary

We covered the full workflow for importing qcow2 cloud images into OpenNebula – from downloading official Rocky Linux 10, AlmaLinux 10, and Debian 13 images to registering them in the datastore, creating VM templates with proper contextualization, and launching instances. Both the CLI and Sunstone UI methods were demonstrated. The key points to remember: always set DRIVER and FORMAT to qcow2, configure the CONTEXT section for SSH key injection and networking, and verify each step before moving to the next. With these images in your datastore, spinning up new VMs takes seconds instead of the 20-30 minutes a traditional installation would require.

LEAVE A REPLY

Please enter your comment!
Please enter your name here