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
oneadminuser credentials or appropriate CLI access - Sufficient storage in your image datastore (at least 10 GB free per image)
wgetorcurlinstalled 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:
- Rocky Linux 10 – https://dl.rockylinux.org/pub/rocky/10/images/x86_64/
- AlmaLinux 10 – https://repo.almalinux.org/almalinux/10/cloud/x86_64/images/
- Debian 13 (Trixie) – https://cloud.debian.org/images/cloud/trixie/daily/latest/
- Ubuntu (latest LTS) – https://cloud-images.ubuntu.com/
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.
- Log into Sunstone at
http://your-opennebula-host:9869 - Navigate to Storage > Images in the left sidebar
- Click the + (Create) button
- 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
- 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.qcow2if the file is already on the front-end
- Under Advanced Options, set:
- Driver: qcow2
- Format: qcow2
- 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
- In Sunstone, go to Templates > VMs
- Click the + (Create) button
- On the General tab:
- Name: Rocky Linux 10 VM
- Memory: 2048 MB
- CPU: 1
- VCPU: 2
- On the Storage tab:
- Click + Add disk
- Select the “Rocky Linux 10 Cloud” image
- Set Size to 20 GB
- On the Network tab:
- Click + Add NIC
- Select your virtual network
- 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(oralmalinux/debiandepending on the image)
- On the Input/Output tab:
- Add a VNC graphics device for console access
- 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
- Go to Templates > VMs
- Select the template you want to use
- Click Instantiate
- Optionally set a name for the VM
- Adjust any parameters if needed
- Click Instantiate
- 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:
- Use the VNC console in Sunstone to access the VM directly and check if it booted properly
- Check that your SSH public key was injected correctly:
cat /home/rocky/.ssh/authorized_keys
- Verify the network is configured inside the VM:
ip addr show
- Check that cloud-init ran without errors:
cat /var/log/cloud-init.log | tail -30
- 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.































































