Volume Snapshot

1. Overview

ZStack allows user to create snapshots from VM's root volume and data volumes. Unlike majority of IaaS software only allowing users to create at most one snapshot chain, ZStack allows users to create a snapshot tree that each branch is a snapshot chain.

In this example, we will create a snapshot tree with two branches from a VM's root volume.

Only CentOS supports live snapshot, Ubuntu doesn't

2. Prerequisites

We assume you have followed Quick Installation Guide to install ZStack on a single Linux machine, and the ZStack management node is up and running. To use the command line tool, type below command in your shell terminal:


Connect to a remote management node

By default, zstack-cli connects to the ZStack management node on the local machine. To connect to a remote node, using option '-H ZSTACK_NODE_HOST_IP'; for example: zstack-cli -H

To make things simple, we assume you have only one Linux machine with one network card that can access the internet; besides, there are some other requirements:

  • At least 20G free disk that can be used as primary storage and backup storage
  • Several free IPs that can access the internet
  • NFS server is enabled on the machine (done in Quick Installation Guide)
  • SSH credentials for user root (done in Quick Installation Guide)

Configure root user

The KVM host will need root user credentials of SSH, to allow Ansible to install necessary packages and to give the KVM agent full control of the host. As this tutorial use a single machine for both ZStack management node and KVM host, you will need to configure credentials for the root user.
sudo su
passwd root

Based on those requirements, we assume below setup information:

  • ethernet device names: eth0 (The default route will use eth0)
  • eth0 IP:
  • free IP range: ~ (these IPs can access the internet)
  • primary storage folder: /zstack_ps
  • backup storage folder: /zstack_bs

Slow VM stopping due to lack of ACPID:

Though we don't show the example of stopping VM, you may find stopping a VM takes more than 60s. That's because the VM image doesn't support ACPID that receives KVM's shutdown event, ZStack has to wait for 60 seconds timeout then destroy it. It's not a problem for regular Linux distributions which have ACPID installed.

Avoid DHCP conflict

Please make sure you don't have a DHCP server in the network because ZStack will spawn its own DHCP server; if you have a DHCP server in the network and cannot remove it, please use an IP range that is unlikely used by your DHCP server, otherwise the VM may not receive an IP from ZStack's DHCP server but from yours.

3. LogIn

open zstack-cli and login with admin/password:

>>> LogInByAccount accountName=admin password=password  

4. Create Zone

create a zone with name 'ZONE1' and description 'zone 1':

>>> CreateZone name=ZONE1 description='zone 1'

Substitute your UUIDs for those in this tutorial

Resources are all referred by UUIDs in CLI tutorials. The UUIDs are generated by ZStack when you create a resource, so they may vary from what you see in tutorials. UUIDs of resources will be printed out in a JSON object to the screen after resources are created; however, it's inconvenient to scroll up screen to find UUIDs of resources that are created very early. We add buttons to sections, which will show you commands of retrieving UUIDs of resources, so please make sure you replace UUIDs in tutorials with yours.

5. Create Cluster

create a cluster with name 'CLUSTER1' and hypervisorType 'KVM' under zone 'ZONE1':

QueryZone fields=uuid, name=ZONE1
>>> CreateCluster name=CLUSTER1 hypervisorType=KVM zoneUuid=b5ba18197f7843308cd26f87eab933c5

6. Create Host

add KVM Host 'HOST1' under 'CLUSTER1' with correct host IP address and root username and password:

QueryCluster fields=uuid, name=CLUSTER1
>>> AddKVMHost name=HOST1 managementIp= username=root password=password clusterUuid=e630ebdb5f7742f3818fd998e91d35a8

A little slow when first time adding a host

It may take a few minutes to add a host because Ansible will install all dependent packages, for example, KVM, on the host.

7. Add Primary Storage

add Primary Storage 'PRIMAYR-STORAGE1' with NFS URI '/zstack_ps' under zone 'ZONE1':

QueryZone fields=uuid, name=ZONE1
>>> AddLocalPrimaryStorage name=PRIMARY-STORAGE1 url=/zstack_ps zoneUuid=b5ba18197f7843308cd26f87eab933c5

Format of URL

The format of URL is exactly the same to the one used by Linux mount command.


QueryCluster fields=uuid, name=CLUSTER1
QueryPrimaryStorage fields=uuid, name=PRIMARY-STORAGE1
>>> AttachPrimaryStorageToCluster primaryStorageUuid=1b952f1e74a747dfb89ef3bdb9e8a821 clusterUuid=e630ebdb5f7742f3818fd998e91d35a8

8. Add Backup Storage

add sftp Backup Storage 'BACKUP-STORAGE1' with backup storage host IP address(''), root username('root'), password('password') and sftp folder path('/zstack_bs'):

>>> AddSftpBackupStorage name=BACKUP-STORAGE1 hostname= username=root password=password url=/zstack_bs

attach new created Backup Storage('BACKUP-STORAGE1') to zone('ZONE1'):

QueryZone fields=uuid, name=ZONE1
QueryBackupStorage fields=uuid, name=BACKUP-STORAGE1
>>> AttachBackupStorageToZone backupStorageUuid=ccc8214bfc2344e5a58c2ec23de3b348 zoneUuid=b5ba18197f7843308cd26f87eab933c5

It may take a few minutes to complete because Ansible will install necessary packages and deploy ZStack SFTP backup storage agent.

9. Add Image

add Image('image') with format 'qcow2', 'RootVolumeTemplate' type, 'Linux' platform and image URL('http://cdn.zstack.io/product_downloads/images/zstack-image.qcow2') to backup storage ('BACKUP-STORAGE1'):

QueryBackupStorage fields=uuid, name=BACKUP-STORAGE1
>>> AddImage name=image mediaType=RootVolumeTemplate platform=Linux url= backupStorageUuids=ccc8214bfc2344e5a58c2ec23de3b348 format=qcow2

this image will be used as user VM image.

Add another Image('VRImage') with format 'qcow2' and image URL('http://cdn.zstack.io/product_downloads/images/zstack-image.qcow2') to backup storage ('BACKUP-STORAGE1'):

QueryBackupStorage fields=uuid, name=BACKUP-STORAGE1

Fast link for users of Mainland China

>>> AddImage name=VRImage url= backupStorageUuids=ccc8214bfc2344e5a58c2ec23de3b348 format=qcow2

Cache images in your local HTTP server

The virtual router image is about 432M that takes a little of time to download. We suggest you use a local HTTP server to storage it and images created by yourself.

10. Create L2 Network

create No Vlan L2 Network 'FLAT-L2' with physical interface as 'eth0' under 'ZONE1':

QueryZone fields=uuid, name=ZONE1
>>> CreateL2NoVlanNetwork name=FLAT-L2 physicalInterface=eth0 zoneUuid=b5ba18197f7843308cd26f87eab933c5

attach 'FLAT-L2' to 'CLUSTER1':

QueryCluster fields=uuid, name=CLUSTER1
QueryL2Network fields=uuid, name=FLAT-L2
>>> AttachL2NetworkToCluster l2NetworkUuid=ea5d8266bd4e4c2bb3ebf5cf5509b136 clusterUuid=e630ebdb5f7742f3818fd998e91d35a8

11. Create L3 Network

create 'FLAT-L3' L3 network on FLAT-L2 L2 network:

QueryL2Network fields=uuid, name=FLAT-L2
>>> CreateL3Network name=FLAT-L3 l2NetworkUuid=ea5d8266bd4e4c2bb3ebf5cf5509b136

create IP Range for 'FLAT-L3':

QueryL3Network fields=uuid, name=FLAT-L3
>>> AddIpRange name=FLAT-IP-RANGE l3NetworkUuid=23f3a0fde8744a699f86b27899be3183 startIp= endIp= netmask= gateway=

add DNS for 'FLAT-L3':

QueryL3Network fields=uuid, name=FLAT-L3
>>> AddDnsToL3Network l3NetworkUuid=23f3a0fde8744a699f86b27899be3183 dns=

we need to get available network service provider UUID, before add any virtual router service to L3 network:

>>> QueryNetworkServiceProvider

there are 2 available network service providers. The 'VirtualRouter' could provide 'DHCP', 'SNAT', 'DNS', 'PortForwarding' and 'Eip' services. The 'SecurityGroup' could provide 'SecurityGroup' service.

attach VirtualRouter services 'DHCP', 'DNS' to 'FLAT-L3':

QueryL3Network fields=uuid, name=FLAT-L3
QueryNetworkServiceProvider fields=uuid, name=VirtualRouter

Structure of parameter networkServices

It's a JSON object of map that key is UUID of network service provider and value is a list of network service types.
>>> AttachNetworkServiceToL3Network networkServices="{'1b93ca42c7bb47d9a6295e58ad8ef1b7':['Userdata','DHCP','Eip']}" l3NetworkUuid=23f3a0fde8744a699f86b27899be3183

12. Create Instance Offering

create a guest VM instance offering 'small-instance' with 1 512Mhz CPU and 128MB memory:

>>> CreateInstanceOffering name=small-instance memorySize=134217728 cpuNum=1

13. Create Virtual Machine

create a new guest VM instance with instance offering 'small-instance', image 'zs-sample-image', L3 network 'FLAT-L3', name 'VM1' and hostname 'vm1'

QueryInstanceOffering fields=uuid, name=small-instance
QueryImage fields=uuid, name=zs-sample-image
QueryL3Network fields=uuid, name=FLAT-L3
>>> CreateVmInstance name=VM1 instanceOfferingUuid=ce994286008d41f6be75e0f804bce47c imageUuid=6874474809df4d2292d3503884e0096e l3NetworkUuids=23f3a0fde8744a699f86b27899be3183

The first user VM takes more time to create

For the first user VM, ZStack needs to download the image from the backup storage to the primary storage and create a virtual router VM on the private L3 network, so it takes about 1 ~ 2 minutes to finish.

from VM creation result, you can get the new created VM IP address is

15. Create Volume Snapshot

first of all, we are going to create a flag file in VM1, so later on we can use this file to confirm that we revert to the correct snapshot. You can ssh to Login onto it through any machine that can reach subnet and use touch flag1 to create the flag:

QueryVmNic fields=ip vmInstance.name=VM1
# ssh root@ 'touch flag1'

then, since we are using CentOS6.x, we need to stop VM1, before create snapshot:

QueryVmInstance fields=uuid, name=VM1
>>> StopVmInstance uuid=c55dc43bd0344c48931cbf08102647a9

Again it's slow only because the zs-sample-image doesn't support ACPID

Because the image zs-sample-image doesn't support ACPID, the VM cannot be gracefully stopped. ZStack has to wait 60s stopping timeout then kill it, you won't encounter this problem in regular Linux distributions.

create snapshot 'sp1' for VM1's root volume: 81732342589546e9b80363e504556fdc:

QueryVolume fields=uuid vmInstance.name=VM1
>>> CreateVolumeSnapshot name=sp1 volumeUuid=81732342589546e9b80363e504556fdc

repeat above step to create two more snapshots: sp2 and sp3:

use VM1's volume uuid to query Volume Snapshot Tree, we can see 3 snapshots' details:

QueryVolume fields=uuid vmInstance.name=VM1
>>> QueryVolumeSnapshotTree volumeUuid=81732342589546e9b80363e504556fdc

start VM1, before doing later operations:

QueryVmInstance fields=uuid name=VM1
>>> StartVmInstance uuid=c55dc43bd0344c48931cbf08102647a9

use instructions in the beginning of this section to ssh VM1 and delete the flag file 'flag1':

# ssh root@ '/bin/rm -f flag1; ls'

to revert the root volume to a prior snapshot, we need to stop the VM1 again:

QueryVmInstance fields=uuid name=VM1
>>> StopVmInstance uuid=c55dc43bd0344c48931cbf08102647a9

revert volume to snapshot 1:

QueryVolumeSnapshot fields=uuid name=sp1
>>> RevertVolumeFromSnapshot uuid=9c2ab564bbe04181997f2cce64b46a27

now start the VM again:

QueryVmInstance fields=uuid name=VM1
>>> StartVmInstance uuid=c55dc43bd0344c48931cbf08102647a9

once VM1 startup, use ssh to check the flag file 'flag1', you should see the file we deleted before now comes back, which confirms we have successfully reverted the root volume to the snapshot 'sp1':

# ssh root@ 'ls flag*'

stop VM1:

QueryVmInstance fields=uuid name=VM1
>>> StopVmInstance uuid=c55dc43bd0344c48931cbf08102647a9

use former instructions to create two more snapshots: 'sp1.1' and 'sp1.2':

QueryVolume fields=uuid vmInstance.name=VM1
>>> CreateVolumeSnapshot name=sp1.1 volumeUuid=81732342589546e9b80363e504556fdc

QueryVolume fields=uuid vmInstance.name=VM1
>>> CreateVolumeSnapshot name=sp1.2 volumeUuid=81732342589546e9b80363e504556fdc

query the snapshot tree again, now you should see two branches that are both derived from snapshot 'sp1':


In this tutorial, we showed you how to create volume snapshot in ZStack. Besides reverting a volume to an old snapshot, you can also create image template and volumes from snapshots. For details, please visit Volume Snapshot in user manual.