Create a KVM VM on Ceph RBD

This follow-up shows the cleanest, minimal path to put a Libvirt/QEMU VM disk on Ceph RBD and create the VM with Cockpit.

This post is a follow-up to:

If you finished those posts, the only extra package needed on the KVM/libvirt host is:

sudo apt install -y libvirt-daemon-driver-storage-rbd
sudo systemctl restart libvirtd   # important: loads the RBD backend

What you’ll end up with

  • A Ceph RBD pool ready for VM disks
  • A client.libvirt user + key (used by libvirt as a secret)
  • A Libvirt storage pool mapped to your Ceph RBD pool
  • A KVM VM created with its disk on RBD

Tip: Replace placeholders like <pool-name>, <mon-ip>, <SECRET_UUID> with your values.


  1. Create an RBD pool (on a Ceph host)
ceph osd pool create <pool-name> 8
ceph osd pool application enable <pool-name> rbd
rbd pool init <pool-name>

  1. Create the libvirt user and copy its key (Ceph host)
ceph auth get-or-create client.libvirt \
  mon 'allow r' \
  osd 'allow rwx pool=<pool-name>'

# Immediately print the Base64 key for this user and copy it:
ceph auth get-key client.libvirt

You’ll paste this Base64 key later when creating the libvirt secret on the KVM host.


  1. Create a libvirt secret with the Base64 key (KVM host)

In libvirt/QEMU, the username/id is libvirt (no client. prefix).

SECRET_UUID=$(uuidgen)
CEPH_KEY_B64='<paste the Base64 from: ceph auth get-key client.libvirt>'

cat >/tmp/ceph-secret.xml <<EOF
<secret ephemeral='no' private='no'>
  <uuid>${SECRET_UUID}</uuid>
  <usage type='ceph'>
    <name>client.libvirt secret</name>
  </usage>
</secret>
EOF

sudo virsh secret-define /tmp/ceph-secret.xml
# Works-first: setting via CLI will warn it's insecure; that's OK for now
sudo virsh secret-set-value --secret ${SECRET_UUID} --base64 "${CEPH_KEY_B64}"

sudo virsh secret-list

About the warning you’ll see:

virsh secret-set-value often prints

error: Passing secret value as command-line argument is insecure!
Secret value set

The first line is just a warning about using CLI args for secrets. The second line confirms it succeeded.


  1. Define a Ceph RBD storage pool in libvirt (single MON)

Point it at your single Ceph node’s MON IP. If you omit the port, libvirt defaults to msgr1 :6789, which is reliable for a first run.

MON=<mon-ip>                # e.g., 192.168.0.82
POOL_NAME=<pool-name>       # e.g., vm

sudo virsh pool-define-as ceph-vm rbd \
  --source-host ${MON} \
  --source-name ${POOL_NAME} \
  --auth-type ceph \
  --auth-username libvirt \
  --secret-uuid ${SECRET_UUID}

sudo virsh pool-start ceph-vm
sudo virsh pool-autostart ceph-vm
virsh pool-info ceph-vm

Expected XML (what the CLI produces):

<pool type='rbd'>
  <name>ceph-vm</name>
  <source>
    <host name='<your-ceph-node-ip>'/>  <!-- no port => default 6789 (msgr1) -->
    <name><pool-name></name>
    <auth type='ceph' username='libvirt'>
      <secret uuid='<SECRET_UUID>'/>
    </auth>
  </source>
</pool>

  1. Pre-create the RBD volume (so Cockpit can select it)

Some Cockpit builds show Create new raw volume in the VM wizard, but that action is file-backed (dir pool), not RBD. For RBD, create the volume first, then select it:

sudo virsh vol-create-as ceph-vm myvm-root 10G --format raw
sudo virsh pool-refresh ceph-vm   # if Cockpit doesn’t see it yet

Use raw on RBD (don’t layer qcow2 on top of RBD unless you truly need qcow2 features).


  1. Create the VM in Cockpit using the RBD volume

That’s it — a tidy, repeatable path to build a KVM VM backed by Ceph RBD using Cockpit, tailored for a single-node Ceph and requiring just one extra package on the KVM host.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top