OpenNebula: Erstellen von Snapshots mit Ceph als Storage-System
Beim Versuch, unter ONe ein Snapshot von einer VM zu erstellen, erscheint im Log, dass das Format raw für VM-Snapshots nicht kompatibel sei, obwohl die Images als qcow2 angelegt wurden. Dieser Schein trügt, denn in der jeweiligen Datei mit den Eigenschaften einer VM steht, dass das Image als raw vorliegt. Grund dafür ist, dass Ceph derzeit keine native Unterstützung für qcow2 enthält und somit alle Images automatisch als raw anlegt. Ein Snapshot ist unter der Verwendung von Ceph nur für Images und nicht für VMs möglich. Ein Rollback eines solchen Snapshots ist zudem nur im ausgeschalteten Zustand der VM möglich. Außerdem bietet ONe bisher keine Möglichkeit, einen scheduled task für Image-Snapshots zu erstellen. Eine Möglichkeit, sich dagegen Abhilfe zu verschaffen, wäre, ein (Ana)cron-Job (zeitgesteuerte Skripts unter Linux) mithilfe eines Shell-Skriptes zu erstellen. Die Programmierung eines solchen Skriptes erfordert zwar erweiterte Programmierkenntnisse, jedoch lassen sich so die Snapshot-Aufgaben sehr detailliert formulieren, da jegliche Tools des Betriebssystems zur Verfügung stehen. Z.B. lassen sich die Snapshots direkt auf ein externes Medium, wie einem NAS, als Image-Datei exportieren, um später wieder – auch in einem anderem Cluster – importiert zu werden. Hier ein Beispiel für ein solches Skript:
#!/bin/bash
# Create VM snapshots weekly
set -e
#Disk IDs must match VM IDs!
vmids=(1 2 3) #space separated VM IDs
diskids=(0 1 0) #space separated Disk IDs
if [ "${#vmids[@]}" != "${#diskids[@]}" ]
then
echo "Disk IDs don't equal VM IDs! Aborting..."
exit 1
fi
tmppath="/home/cephadmin" #path to store Imagess before moving to destination path
destpath="/mnt/nas/vmbackups" #final destination path
datenow=$(date +%Y%m%d)
for i in "${!vmids[@]}"; do #walk through the array above
vmexist=$(onevm list -l ID | grep ${vmids[$i]} | tr -s ' ')
if [ -z $vmexist ] || [ ${vmids[$i]} != $vmexist ] #check whether VM ID exists with given Disk ID
then
echo "VM with ID ${vmids[$i]} doesn't exist. Skipping..."
else
vmstate=$(onevm list -l ID,STAT | grep ${vmids[$i]} | tr -s ' ' | cut -d ' ' -f3)
#ensure snapshot can or needs to be created
if [ -z "$(onevm show ${vmids[$i]} | awk '/VM DISKS/' RS= | tail -n +2 | awk '{ print $1$2 }' | grep ${diskids[$i]}cephds)" ] || [ -n "$(oneimage list -x | grep ${vmids[$i]}-${diskids[$i]}-IMG$datenow)" ] || [ $vmstate == "unde" ]
then
echo "VM ${vmids[$i]} not valid or necessary, skipping..."
else
onevm disk-snapshot-create ${vmids[$i]} ${diskids[$i]} "Snap$datenow"
vmstate=$(onevm list -l ID,STAT | grep ${vmids[$i]} | tr -s ' ' | cut -d ' ' -f3)
while [ $vmstate == "snap" ]
do
sleep 1
echo "Waiting for snap to be created..."
vmstate=$(onevm list -l ID,STAT | grep ${vmids[$i]} | tr -s ' ' | cut -d ' ' -f3)
done
imgout=$(onevm disk-saveas ${vmids[$i]} ${diskids[$i]} "${vmids[$i]}-${diskids[$i]}-IMG$datenow")
vmstate=$(onevm list -l ID,STAT | grep ${vmids[$i]} | tr -s ' ' | cut -d ' ' -f3)
while [ $vmstate == "hotp" ]
do
sleep 1
echo "Waiting for image to be created..."
vmstate=$(onevm list -l ID,STAT | grep ${vmids[$i]} | tr -s ' ' | cut -d ' ' -f3)
done
imgid=$(echo $imgout | cut -d ' ' -f3)
imgstate=$(oneimage list -l ID,STAT | grep ${vmids[$i]} | tr -s ' ' | cut -d ' ' -f3)
while [ $vmstate == "lock" ]
do
sleep 1
echo "Waiting for image to get finished..."
imgstate=$(oneimage list -l ID,STAT | grep ${vmids[$i]} | tr -s ' ' | cut -d ' ' -f3)
done
qemu-img convert -f raw rbd:one/one-$imgid -O raw $tmppath/${vmids[$i]}-${diskids[$i]}-IMG$datenow.raw
#copy to destination
cp $tmppath/${vmids[$i]}-${diskids[$i]}-IMG$datenow.raw $destpath/${vmids[$i]}-${diskids[$i]}-IMG$datenow.raw
#remove temporary file
rm -rf $tmppath/${vmids[$i]}-${diskids[$i]}-IMG$datenow.raw
fi
fi
done
exit 0