QEMU3 – 使用ceph来存储QEMU镜像

ceph简介

Ceph是一个PB级别的分布式软件定义存储系统,为用户提供了块存储、对象存储以及符合POSIX标准的文件系统接口。目前,Ceph已经成为Openstack最受欢迎的后端存储系统。下图为ceph的架构图。

ceph架构图

RADOS本身是一个对象存储系统,实现了ceph的核心功能。Librados是ceph提供给各种编程语言的接口。RADOSGW,RBD,CEPH FS分别为用户提供了对象存储、块存储及文件系统的功能。Ceph集群及客户端的安装配置请参考Ceph官方文档

使用Ceph来存储QEMU镜像

QEMU会假定ceph配置文件存放在默认位置/etc/ceph/$cluster.conf,也会使用client.admin作为默认的ceph用户。如果要指定其他的配置文件或者用户,可以在ceph RBD的选项中添加conf=/home/ceph.conf或者id=admin选项。qemu-img使用ceph块存储RBD时,需要使用下面的格式:

qemu-img {command} [options] rbd:{pool-name}/{image-name}[@snapshot-name][:option1=value1][:option2=value2…] 

例如:

qemu-img {command} [options] rbd:glance-pool/maipo:id=glance:conf=/etc/ceph/ceph.conf 

创建一个镜像

可以使用qemu-img命令在ceph集群中创建一个虚拟机镜像。需要指定rbd, pool,以及镜像名。

qemu-img create -f raw rbd:{pool-name}/{image-name} {size} 

例如:

[root@ltczhp20 ~]# qemu-img create -f raw rbd:rbd/vmdisk1 4G

Formatting 'rbd:rbd/vmdisk1', fmt=raw size=4294967296
[root@ltczhp20 ~]# rbd ls
vmdisk1

qemu-img通常会指定RBD存储的镜像格式是RAW,这样可以减少其他格式带来的性能开销,也会防止虚拟机热迁移时缓存带来的问题。

调整镜像的大小

要调整镜像大小,必须指定rbd,pool name,以及镜像名。

qemu-img resize rbd:{pool-name}/{image-name} {size} 

例如:

[root@ltczhp20 ~]# qemu-img resize -f raw rbd:rbd/vmdisk1 2G

Image resized.
[root@ltczhp20 ~]# rbd ls
vmdisk1
[root@ltczhp20 ~]# rbd info vmdisk1
rbd image 'vmdisk1':
    size 2048 MB in 512 objects
    order 22 (4096 kB objects)
    block_name_prefix: rbd_data.fa802ae8944a
    format: 2
    features: layering, exclusive-lock, object-map, fast-diff, deep-flatten
    flags:

如果不指定镜像格式(-f raw),qemu会给出警告信息:

[root@ltczhp20 ~]# qemu-img resize rbd:rbd/vmdisk1 4G
WARNING: Image format was not specified for 'rbd:rbd/vmdisk1' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
Image resized.

获取镜像信息

获取镜像信息同样需要指定rbd,pool name以及镜像名:

qemu-img info rbd:{pool-name}/{image-name} 

例如:

[root@ltczhp20 ~]# qemu-img info rbd:rbd/vmdisk1

image: rbd:rbd/vmdisk1
file format: raw
virtual size: 4.0G (4294967296 bytes)
disk size: unavailable
cluster_size: 4194304

使用qemu命令运行虚拟机

从QEMU0.15后,虚拟机使用ceph块设备就不需要使用rbd map命令将RBD镜像映射到本地了,QEMU可以通过librados直接访问一个虚拟块设备。这样避免了额外的上下文切换,也充分利用了RBD的缓存功能。

在运行虚拟机之前,我们可以把一个已经存在的虚拟机镜像转化为ceph RBD存储,然后直接从RBD启动虚拟机。

qemu-img convert -c -f fmt -O out_fmt -o options  fname out_fname 

例如:

[root@ltczhp20 ~]# qemu-img convert -f qcow2 -O raw /srv/fedora24/fedora24.qcow2 rbd:rbd/fedora

然后使用qemu命令运行虚拟机。

[root@ltczhp20 ~]# qemu-system-s390x -nographic -enable-kvm -m 4G -drive format=raw,file=rbd:rbd/fedora

RBD缓存会极大的提高虚拟机的性能。QEMU1.2之后,cache选项可以直接控制librbd:

[root@ltczhp20 ~]# qemu-system-s390x -nographic -enable-kvm -m 4G -drive format=raw,file=rbd:rbd/fedora,cache=writeback

在QEMU1.2之前,如果要使用RBD缓存,需要额外添加rbd_cache=true选项:

[root@ltczhp20 ~]# qemu-system-s390x -nographic -enable-kvm -m 4G -drive format=raw,file=rbd:rbd/fedora,cache=writeback,rbd_cache=true

如果指定了rbd_cache=true,一定要指定cache=writeback,否则QEMU不会给librbd发送flush请求,RBD之上的文件系统可能会被破坏。

使用ceph RBD的快照功能

创建一个镜像快照sp0:

[root@ltczhp20 ~]# qemu-img snapshot -l rbd:rbd/fedora
[root@ltczhp20 ~]# qemu-img snapshot -c sp0 rbd:rbd/fedora
WARNING: Image format was not specified for 'rbd:rbd/fedora' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
[root@ltczhp20 ~]# qemu-img snapshot -l rbd:rbd/fedora
Snapshot list:
ID        TAG                 VM SIZE                DATE       VM CLOCK
sp0       sp0                     20G 1970-01-01 01:00:00   00:00:00.000

启动虚拟机,创建文件/root/hello.txt并写入字符串”hello world”,然后关闭虚拟机。

[root@ltczhp20 ~]# qemu-system-s390x -nographic -enable-kvm -m 4G -drive format=raw,file=rbd:rbd/fedora

In VM:

[root@localhost ~]# echo "hello world" >> /root/hello.txt
[root@localhost ~]# cat /root/hello.txt
hello world

[root@localhost ~]# halt

将虚拟机回滚到快照sp0,然后检查是否存在/root/hello.txt文件,如果不存在则说明快照已经成功回滚。

[root@ltczhp20 ~]# qemu-img snapshot -a sp0 rbd:rbd/fedora

[root@ltczhp20 ~]# qemu-system-s390x -nographic -enable-kvm -m 4G -drive format=raw,file=rbd:rbd/fedora

In VM:

[root@localhost ~]# ls /root/hello.txt
ls: cannot access '/root/hello.txt': No such file or directory

[root@localhost ~]# halt

删除快照:

[root@ltczhp20 ~]# rbd snap ls rbd/fedora
SNAPID NAME     SIZE
    22 sp0  20480 MB
[root@ltczhp20 ~]# qemu-img snapshot -d sp0 rbd:rbd/fedora
WARNING: Image format was not specified for 'rbd:rbd/fedora' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
[root@ltczhp20 ~]# rbd snap ls rbd/fedora
[root@ltczhp20 ~]# qemu-img snapshot -l rbd:rbd/fedora

阅读原文

QEMU 1: 使用QEMU创建虚拟机

一、QEMU简介#

QEMU是一款开源的模拟器及虚拟机监管器(Virtual Machine Monitor, VMM)。QEMU主要提供两种功能给用户使用。一是作为用户态模拟器,利用动态代码翻译机制来执行不同于主机架构的代码。二是作为虚拟机监管器,模拟全系统,利用其他VMM(Xen, KVM, etc)来使用硬件提供的虚拟化支持,创建接近于主机性能的虚拟机。

用户可以通过不同Linux发行版所带有的软件包管理器来安装QEMU。如在Debian系列的发行版上可以使用下面的命令来安装:

sudo apt-get install qemu

或者在红帽系列的发行版上使用如下命令安装:

sudo yum install qemu -y

除此之外,也可以选择从源码安装。

##获取QEMU源码##

可以从QEMU官网上下载QEMU源码的tar包,以命令行下载2.0版本的QEMU为例:

$wget http://wiki.qemu-project.org/download/qemu-2.0.0.tar.bz2
$tar xjvf qemu-2.0.0.tar.bz2

如果需要参与到QEMU的开发中,最好使用Git获取源码:

$git clone git://git.qemu-project.org/qemu.git

##编译及安装##

获取源码后,可以根据需求来配置和编译QEMU。

$cd qemu-2.0.0 //如果使用的是git下载的源码,执行cd qemu
$./configure --enable-kvm --enable-debug --enable-vnc --enable-werror  --target-list="x86_64-softmmu"
$make -j8
$sudo make install

configure脚本用于生成Makefile,其选项可以用./configure --help查看。这里使用到的选项含义如下:

--enable-kvm:编译KVM模块,使QEMU可以利用KVM来访问硬件提供的虚拟化服务。
--enable-vnc:启用VNC。
--enalbe-werror:编译时,将所有的警告当作错误处理。
--target-list:选择目标机器的架构。默认是将所有的架构都编译,但为了更快的完成编译,指定需要的架构即可。

#二、基本原理#

QEMU作为系统模拟器时,会模拟出一台能够独立运行操作系统的虚拟机。如下图所示,每个虚拟机对应主机(Host)中的一个QEMU进程,而虚拟机的vCPU对应QEMU进程的一个线程。

QEMU结构图

系统虚拟化最主要是虚拟出CPU、内存及I/O设备。虚拟出的CPU称之为vCPU,QEMU为了提升效率,借用KVM、XEN等虚拟化技术,直接利用硬件对虚拟化的支持,在主机上安全地运行虚拟机代码(需要硬件支持)。虚拟机vCPU调用KVM的接口来执行任务的流程如下(代码源自QEMU开发者Stefan的技术博客):

open("/dev/kvm")
ioctl(KVM_CREATE_VM)
ioctl(KVM_CREATE_VCPU)
for (;;) {
     ioctl(KVM_RUN)
     switch (exit_reason) {
     case KVM_EXIT_IO:  /* ... */
     case KVM_EXIT_HLT: /* ... */
     }
}

QEMU发起ioctrl来调用KVM接口,KVM则利用硬件扩展直接将虚拟机代码运行于主机之上,一旦vCPU需要操作设备寄存器,vCPU将会停止并退回到QEMU,QEMU去模拟出操作结果。

虚拟机内存会被映射到QEMU的进程地址空间,在启动时分配。在虚拟机看来,QEMU所分配的主机上的虚拟地址空间为虚拟机的物理地址空间。

QEMU在主机用户态模拟虚拟机的硬件设备,vCPU对硬件的操作结果会在用户态进行模拟,如虚拟机需要将数据写入硬盘,实际结果是将数据写入到了主机中的一个镜像文件中。

#三、创建及使用虚拟机#

##命令行创建及启动虚拟机##

成功安装QEMU之后便可创建自己的虚拟机。具体步骤如下:

1, 使用qemu-img创建虚拟机镜像。虚拟机镜像用来模拟虚拟机的硬盘,在启动虚拟机之前需要创建镜像文件。

[kelvin@kelvin tmp]$ qemu-img create -f qcow2 fedora.img 10G
Formatting 'fedora.img', fmt=qcow2 size=10737418240 encryption=off cluster_size=65536 lazy_refcounts=off 
[kelvin@kelvin tmp]$ ls
fedora.img

-f选项用于指定镜像的格式,qcow2格式是QEMU最常用的镜像格式,采用写时复制技术来优化性能。fedora.img是镜像文件的名字,10G是镜像文件大小。镜像文件创建完成后,可使用qemu-system-x86来启动x86架构的虚拟机:

qemu-system-x86_64 fedora.img

此时会弹出一个窗口来作为虚拟机的显示器,显示内容如下:

QEMU虚拟机显示器输出

因为fedora.img中并未给虚拟机安装操作系统,所以会提示“No bootable device”,无可启动设备。

2, 准备操作系统镜像。

可以从不同Linux发行版的官方网站上获取安装镜像,以fedora20为例:

[kelvin@kelvin tmp]$ wget http://ftp6.sjtu.edu.cn/fedora/linux/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso

3, 检查KVM是否可用。

QEMU使用KVM来提升虚拟机性能,如果不启用KVM会导致性能损失。要使用KVM,首先要检查硬件是否有虚拟化支持:

[kelvin@kelvin ~]$ grep -E 'vmx|svm' /proc/cpuinfo

如果有输出则表示硬件有虚拟化支持。其次要检查kvm模块是否已经加载:

[kelvin@kelvin ~]$ lsmod | grep kvm
kvm_intel             142999  0 
kvm                   444314  1 kvm_intel

如果kvm_intel/kvm_amd、kvm模块被显示出来,则kvm模块已经加载。最后要确保qemu在编译的时候使能了KVM,即在执行configure脚本的时候加入了–enable-kvm选项。

4, 启动虚拟机安装操作系统。

执行下面的命令启动带有cdrom的虚拟机:

[kelvin@kelvin tmp]$ qemu-system-x86_64 -m 2048 -enable-kvm fedora.img -cdrom ./Fedora-Live-Desktop-x86_64-20-1.iso

-m 指定虚拟机内存大小,默认单位是MB, -enable-kvm使用KVM进行加速,-cdrom添加fedora的安装镜像。可在弹出的窗口中操作虚拟机,安装操作系统,安装完成后重起虚拟机便会从硬盘(fedora.img)启动。之后再启动虚拟机只需要执行:

[kelvin@kelvin tmp]$ qemu-system-x86_64 -m 2048 -enable-kvm fedora.img

即可。

##图形界面创建及启动虚拟机##

命令行启动虚拟机比较繁琐,适合开发者,但对于普通用户来说,采用图形界面管理虚拟机则更为方便。采用图形界面管理QEMU虚拟机需要安装virt-manager,红帽系列的发行版只需要执行命令:

$sudo yum install virt-manager -y

安装完成后用root用户启动virt-manager:

$su -
#virt-manager

启动后的界面如下图所示:

virt-manager界面

点击左上角电脑图标即可创建虚拟机。按照步骤操作即可完成对虚拟机的创建。

为虚拟机vCPU绑定物理CPU

为了提高缓存命中率,提高虚拟机性能,可以将vCPU绑定到指定的物理CPU去执行。具体设置步骤如下:

  1. 在宿主机操作系统启动时将用于虚拟机的CPU独立出来,使其上只运行vCPU线程,QEMU进程和少数的管理进程。设置方法即是在内核启动参数中加入: isolcpus=0,1 例如在grub.cfg下面的配置如下:
        menuentry 'Fedora (3.13.6-200.fc20.x86_64) 20 (Heisenbug)' --class fedora --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-3.13.4-200.fc20.x86_64-advanced-5bcef32f-430b-4d74-beaa-4fcfccc438f9' {
                ......
        	linux	/vmlinuz-3.13.6-200.fc20.x86_64 root=UUID=5bcef32f-430b-4d74-beaa-4fcfccc438f9 ro vconsole.font=latarcyrheb-sun16  rhgb quiet LANG=zh_CN.UTF-8 isolcpus=0,1
        	initrd /initramfs-3.13.6-200.fc20.x86_64.img
        }
  1. 使用taskset命令将vCPU线程绑定到指定的物理CPU。例如,某虚拟机的qemu进程及两个vCPU线程如下:
        ​[root@kelvin ~]# ps -eLo ruser,pid,ppid,lwp,psr,args | grep qemu | grep -v grep
        root      4706  3629  4706   1 qemu-system-x86_64 -m 2G -smp 2 /var/lib/libvirt/images/fedora.img -enable-kvm
        root      4706  3629  4708   1 qemu-system-x86_64 -m 2G -smp 2 /var/lib/libvirt/images/fedora.img -enable-kvm
        root      4706  3629  4709   0 qemu-system-x86_64 -m 2G -smp 2 /var/lib/libvirt/images/fedora.img -enable-kvm

若要将线程ID为4709的vCPU从CPU0绑定到CPU2上执行,可使用如下命令: #taskset -p 0x4 4709 -p后面接的是物理CPU的掩码,其二进制表示从最低位到最高位分别表示第0个物理CPU到最后一个物理CPU,若二进制表示为1,则表示某线程可以在该物理CPU上运行,若为0,则不能。上面的命令的含义就是,线程ID为4709的线程(vCPU)只能在第2个(从0开始编号)物理CPU上运行。执行上述命令的结果如下:

        [root@kelvin ~]# taskset -p 0x4 4709
        pid 4709's current affinity mask: f
        pid 4709's new affinity mask: 4
        [root@kelvin ~]# ps -eLo ruser,pid,ppid,lwp,psr,args | grep qemu | grep -v grep
        root      4706  3629  4706   3 qemu-system-x86_64 -m 2G -smp 2 /var/lib/libvirt/images/fedora.img -enable-kvm
        root      4706  3629  4708   0 qemu-system-x86_64 -m 2G -smp 2 /var/lib/libvirt/images/fedora.img -enable-kvm
        root      4706  3629  4709   2 qemu-system-x86_64 -m 2G -smp 2 /var/lib/libvirt/images/fedora.img -enable-kvm

线程ID为4709的vCPU已经在编号为2的物理CPU上运行了。