Skip to content

Latest commit

 

History

History
230 lines (126 loc) · 26.5 KB

KVM虚拟机存储管理实战(上篇).md

File metadata and controls

230 lines (126 loc) · 26.5 KB

我们上一篇介绍了KVM虚拟机的全生命周期管理实战,如果与OpenStack的实操对应,正好与nova服务的实操相符。在云计算体系中,运维管理主要涉及计算nova、存储cinder和网络neutron三部分。因此,本篇文章我们主要介绍KVM的存储管理实战。KVM的存储选项有多种,包括虚拟磁盘文件、基于文件系统的存储和基于设备的存储。同样,也有对应的virsh管理命令。

KVM的存储选项和常用管理命令

为实现KVM存储管理,可以使用LVM逻辑卷和创建存储池。储存池Storage Pool 是宿主机上可以看到的一片存储空间,可以是多种型。而逻辑卷Volume 是在 存储池Storage Pool 中划分出的一块空间,宿主机将 Volume 分配给虚拟机,Volume 在虚拟机中看到的就是一块硬盘。

虚拟磁盘文件

当系统创建KVM虚拟机的时候,默认使用虚拟磁盘文件作为后端存储。安装后,虚拟机认为在使用真实的磁盘,但实际上看到的是用于模拟硬盘的虚拟磁盘文件。就是因为加了一层额外的文件系统层,所以系统的I/O读写性能会降低,但是基于文件系统的虚拟磁盘可以用于其他虚拟机,且具备快照、链接克隆、弹性扩缩容等特性,方便虚拟机的迁移。因此,可以说是各有利弊,根据实际使用场景来选择。

基于文件系统的KVM存储

在安装KVM宿主机时,**可选文件系统为dir(directory)或fs(formatted block storage)**作为初始KVM存储格式。默认为dir,通过指定本地文件系统中的一个目录用于创建磁盘镜像文件。而fs选项可以允许指定某个格式化文件系统的分区,把它作为专用的磁盘镜像文件存储。**两种KVM存储选项之间最主要的区别在于:fs文件系统不需要挂载到某个特定的目录。**两种选项所指定的文件系统,都可以是本地文件系统或位于SAN上某个物理宿主机上的网络文件系统。后者具备数据共享的优势,可以很轻易地实现多个主机同时访问。

还有一种基于文件的磁盘存储方式是netfs,可以指定一个网络文件系统的名称,如NFS,用这种方式作为KVM存储与SAN类似,可以访问到位于其它服务器上的虚拟磁盘,同时也可以多台宿主机共享访问磁盘文件。

但是,所有的这些基于文件系统的KVM存储方式都有一个缺点:**文件系统固有缺陷。**因为虚拟机的磁盘文件不能直接读取或写入KVM存储设备,而是写入宿主机OS之上的文件系统。这也就意味着在访问和写入文件时中间增加了额外一层,因此会降低性能。所以,如果只是单纯要求性能好,就需要考虑考虑基于设备的存储。

基于设备的KVM存储

另外一种KVM存储的方式就是使用基于设备的方式。共支持四种不同的物理存储:磁盘、iSCSI、SCSI和lvm逻辑盘。磁盘方式指直接读写硬盘设备。iSCSI和SCSI方式可选,取决于通过SCSI或iSCSI地址与磁盘设备连接。这种KVM存储方式的优势在于磁盘的名称固定,不依赖宿主机OS搜索到磁盘设备的顺序。但是,这种连接磁盘的方式也有缺点:灵活性不足。虚拟磁盘的大小很难改变,而且这种连接方式的KVM存储不支持快照。

**如果要提升基于设备的KVM存储灵活性,可以使用LVM。**LVM的优势在于可以使用快照,但是快照并不是KVM虚拟化的特性,而是LVM自带的特性。

LVM可以把所有存储放到一个卷组里,该卷组是物理磁盘设备的一个抽象,所以如果超出可用磁盘空间最大值,还可以向卷组中添加新的设备,增加的空间在逻辑卷中直接可以使用。使用LVM使得磁盘空间分配更加灵活,而且增加和删除存储也更为容易。LVM除了在单机场景下使用外,还可以在多机场景下使用。在多宿主机环境中,可以在SAN上创建逻辑卷,且如果使用Cluster LVM(集群LVM),可以很容易的配置成多个主机同时访问某个逻辑卷。详见本站Linux常用运维工具分类中LVM逻辑卷一文。

virsh也可以对节点上的存储池和存储卷进行管理。virsh常用于存储池和存储卷的管理命令如下:

命令 功能描述
pool-list 显示libvirt管理的存储池
pool-define <pool.xml> 根据xml文件定义一个存储池
pool-define-as <–type\ target> 定义一个存储池,指定pool名,并指定pool类型和存储路径
pool-build 构建一个存储池
pool-start 激活一个存储池
pool-autostart 设置存储池开机自动运行
pool-info 根据一个存储池名称查询其基本信息
pool-uuid 根据存储池名称查询其uuid信息
pool-create<pool.xml> 根据xml配置文件信息创建一个存储池
pool-edit 编辑一个存储池的xml配置文件
pool-destroy 关闭一个存储池
pool-delete 删除一个存储池,不可恢复
vol-list 查询一个存储池中的存储卷的列表
vol-name 查询一个存储卷的名称
vol-path –pool 查询一个存储卷的路径
vol-create<vol.xml> 根据xml配置创建一个存储卷
vol-create-as <–pool\ name\ capacity\ allocation\ format> 创建一个卷,指定归属pool,卷名、预分配大小、占用大小、磁盘格式
vol-clone 克隆一个存储卷
vol-delete 删除一个存储卷
vol-pool 根据存储卷名或路径查询归属存储池信息

与全生命周期管理一样,可以通过virsh help|egrep ‘(pool*******|vol*********)’**查看全量存储管理命令。

img

KVM虚拟机的存储管理实战

存储池和存储卷的信息查询

有了上面的命令知识储备,我们**通过pool-list命令首先看下当前宿主机(192.168.101.251)上存储池信息。**如下:

img

上图中表示当前宿主机上有两个KVM虚拟机存储池,一个是网络文件系统NFS的存储池,名称为nfsdir,另一个是本地文件系统存储池,名称为root。其实,这两个存储池是在我们前面创建虚拟机通过disk选项制定虚拟机系统盘时,默认创建的。我们可以**通过pool-info命令查看对应存储池的详细信息。**如下:

1)nfsdir存储池信息

img

2)root存储池信息

img

**这里需要明确一个概念,上图中的存储池的总空间大小并不是创建的存储池空间大小,而是存储池所在的磁盘分区的大小,由于我们前面在创建虚拟机时指定的虚拟机系统盘文件都在系统根分区下创建(/root and /mydata/nfsdir/),所以这里的存储池总大小为根分区的大小。这一点可以通过查看根分区大小来确认。**如下:

img

掌握了存储池信息查看后,我们可以通过vol-list命令查看该存储池下有哪些存储卷。如下:

img

上图中表示nfsdir存储池下有一个存储卷cto67s.img,它位于/mydata/nfsdir目录下。接下来,我们还可以**通过vol-info命令查看该存储卷的详细信息。**如下:

img

如上图,在查看存储卷的详细信息时,需要通过–pool选项制定该存储卷对应的存储池名称。上图中表示cto67s.img存储卷的类型为file,总大小为2.28GB。

存储池和存储卷的增、删、改实战

上面查看存储池和存储卷的命令只能浏览大致的一些信息,其实,我们还可以通过**命令pool-deumpxml查看具体的存储卷xml配置详细信息。**如下:

img

上图中显示的存储池nfsdir的xml配置信息,从配置信息中我们可以知道存储池nfsdir的类型type、name、uuid、空间的大小、路径path、权限、归属的用户和用户组等信息。同理,我们如果想查看某个存储卷的xml配置信息,可以使用vol-dumpxml命令实现。如下:

img

在上图中,我们不仅知道存储卷的类型type、name、key、空间大小、路径、磁盘格式、文件权限,归属用户&用户组,还知道该存储卷的访问时间,修改时间和状态改变时间。

有了上面的知识储备后,我们就可以通过xml文件创建一个存储池和一个存储卷。我们首先创建一个存储池POOLB,xml配置内容如下:

img

如上图,我们只需要定义要创建的存储池类型、名称、路径、权限和归属用户及用户组等信息,其他如uuid、空间大小等信息会在存储池创建后,系统自动生成。由于我们定义的存储池类型为dir目录类型,因此实际上空间大小等信息就是存储池目录所在的磁盘分区大小信息。

有了上面存储池的xml配置文件后,就可以通过pool-create命令来创建一个存储池poolB了。需要注意,**由于我们定义的存储池类型为dir目录类型,所以需要提前在xml文件指定的路径下创建目标目录,否则会提示创建存储池失败。**如下:

img

在/mydata目录下创建poolB子目录后,结果如下:

img

上图中,我们完成存储池创建后,在该存储池中创建一个卷data01.img。同理,我们还是通过xml文件来创建,首先创建卷的xml配置文件data01.xml。如下:

img

然后,我们通过命令vol-cretae命令来创建卷data01.img。如下:

img

完成存储池和卷的创建验证后,我们现在来验证删除存储池和卷。既然我们创建的时候,先创建存储池,再创建卷。那么,删除的时候自然是反着来,是不是就是先删除卷再删除存储池。如果不删除存储池中的卷就直接删除存储池行不行?答案是可以的。。。所以,**我们既可以先通过vol-delete命令删除卷,然后通过pool-destroy命令删除池。也可以直接通过pool-destroy命令删除池。**如下:

img

img

在删除池时还有一个pool-delete命令,这个命令请慎用。因为一旦通过它删除池就无法恢复。所以,我们一般使用pool-destroy命令来销毁一个池,一旦需要时还可以通过pool-start命令恢复。即使真的不需要这个池,也可以通过find+rm命令来删除。

大家可能发现了,通过上面的方式创建的存储池是不能自动开始的。其实,KVM的virsh命令还有另一种方式来创建存储池和存储卷。就是**通过pool-define-as命令先定义一个存储池,然后通过pool-build命令来构建一个存储池,再通过pool-start命令激活存储池,最后通过pool-autostart命令设置该存储池开机自动运行。**如下:

img

其实,通过xml配置文件也能通过这种方式创建。如下:

img

完成上面pool的创建后,我们也可以**通过vol-create-as命令来创建一个卷。**如下:

img

如上图,通过制定归属pool,卷名、预分配大小、占用大小和磁盘格式,通过vol-create-as命令完成一个卷的创建。

删除卷和池的方式与上面类似,这里就不再举例了。存储池和卷的其他命令大家可以参考virsh help的信息自行研究。接下来,我们来看一个经常使用qemu-img命令,也就是KVM存储磁盘管理命令。

qemu-img命令实战

镜像算不算存储?在我初学OpenStack时,因为镜像管理服务是glance,存储管理服务是cinder和swift,所以当初单纯以为的镜像不算存储。后来通过深入了解和研究,发现其实镜像也是一种存储,可以把它简单理解为“虚拟机的元数据”,既然是元数据,当然是存储。

我们都知道,在创建KVM虚拟机时,首先需要通过qemu-img命令去创建一个虚拟系统盘。这个qemu-img命令就是是QEMU的磁盘镜像管理工具,在完成qemu-kvm源码编译或rpm包安装后就会默认编译好qemu-img这个二进制文件。qemu-img也是QEMU/KVM使用过程中一个比较重要的工具,我们下来就对其常用用法总结验证下。

qemu-img支持非常多种的文件格式,可以通过“qemu-img-h”查看其命令帮助得到,它支持20多种格式:file,quorum,blkverify,luks,dmg,sheepdog,parallels,nbd,vpc,bochs,blkdebug,qcow2,vvfat,qed,host_cdrom,cloop,vmdk,host_device,qcow,vdi,null-aio,blkreplay,null-co,raw等。

qemu-img工具的命令行基本用法为:qemu-img command[command options],也就是说qemu-img工具通过后面命令和命令选项实现各种磁盘镜像管理功能。它支持的命令分为如下几种:

检查镜像磁盘的数据一致性check[-f fmt]filename

该命令用于对磁盘镜像文件进行一致性检查,查找镜像文件中的错误,目前,仅支持对**“qcow2”、”qed”、”vdi”格式文件的检查**。如下:

img

如上图,提示该磁盘镜像没有错误,并且其中显示了该镜像磁盘在物理盘的I/O偏移地址等存储信息。在上面的命令中,我们使用**-f参数指定镜像磁盘的格式为qcow2,它和qed都是QEMU支持的磁盘镜像格式,qed是qcow2的增强磁盘文件格式,避免了qcow2格式的一些缺点,也提高了性能,不过目前还不够成熟。而另一种磁盘镜像格式vdi(Virtual Disk Image)是Oracle的VirtualBox虚拟机中的存储格式。最后的filename参数是磁盘镜像文件的名称(包括路径)。**

创建磁盘镜像文件create-f fmtfilename[size]

**该命令用于创建一个格式为fmt,大小为size,文件名为filename(包含路径)的镜像文件。**如下:

img

上图中,我们创建了一个raw格式的,大小为20G的镜像磁盘metdata001.raw,位于/mydata/poolB目录下。其实,可以根据文件格式fmt的不同,添加一个或多个选项(options)来附加对该文件的各种功能设置,可以使用”-o?”来查询某种格式文件支持哪些选项,在”-o”选项中各个选项用逗号来分隔。如下:

img

img

img

如上图,如果“-o”选项中使用了backing_file这个选项来指定其后端镜像文件,那么这个创建的镜像文件仅记录与后端镜像文件的差异部分。后端镜像文件不会被修改,除非在QEMU monitor中使用“commit”命令或者使用“qemu-img commit”命令去手动提交这些改动。这种情况下,size参数不是必须需的,其值默认为后端镜像文件的大小。另外,镜像文件的大小(size)也并非必须写在命令的最后,它也可以被写在“-o”选项中作为其中一个选项。而且,直接使用“-b backfile”参数也与“-o backing_file=backfile”效果等价。如下:

img

img

修改磁盘镜像文件格式convert-c-O output_fmtfilename[filename2[…]]output_filename

**该命令用于将fmt格式的filename镜像文件根据options选项转换为格式为output_fmt的名为output_filename的镜像文件。**比如我们先创建test01的qcwo2格式磁盘文件,然后将其转换为raw格式文件。如下:

img

如上图,将创建的qcow2格式的test01文件转换为raw格式的文件(蓝色框部分)。**这个命令一般在做虚拟机模板镜像文件时经常用到,将非raw格式的磁盘文件转换为raw格式的后缀为.img的镜像模板文件,用于后续的批量虚拟机发放。同时,它支持不同格式的镜像文件之间的转换,比如可以用VMware用的vmdk格式文件转换为qcow2文件,这对从其他虚拟化方案转移到KVM上的用户非常有用。**一般来说,输入文件格式fmt由qemu-img工具自动检测到,而输出文件格式output_fmt根据自己需要来指定,默认会被转换为与raw文件格式(且默认使用稀疏文件的方式存储以节省存储空间)。

命令中,“-c”参数是对输出的镜像文件进行压缩,**不过只有qcow2和qcow格式的镜像文件才支持压缩,而且这种压缩是只读的,如果压缩的扇区被重写,则会被重写为未压缩的数据。**同样可以使用“-o options”来指定各种选项,如:后端镜像、文件大小、是否加密等等。使用backing_file选项来指定后端镜像,让生成的文件是copy-on-write的增量文件,这时必须让转换命令中指定的后端镜像与输入文件的后端镜像的内容是相同的,尽管它们各自后端镜像的目录、格式可能不同。

**如果使用qcow2、qcow、cow等作为输出文件格式来转换raw格式的镜像文件(非稀疏文件格式),镜像转换还可以起到将镜像文件转化为更小的镜像,**因为它可以将空的扇区删除使之在生成的输出文件中并不存在。

查看镜像磁盘信息info [-f fmt] filename

**该命令用于显示镜像磁盘的详细信息。**如果文件是使用稀疏文件的存储方式,也会显示出它的本来分配的大小以及实际已占用的磁盘空间大小。如果文件中存放有客户机快照,快照的信息也会被显示出来。比如,我们想查看cto67s.img这个镜像磁盘的信息。如下:

img

这个命令比较简单,聪明如你,一学就会。。。。。。

镜像磁盘的快照命令集snapshot [-l | -a snapshot | -c snapshot | -d snapshot] filename

**这是一组命令,“-l” 选项是查询并列出镜像文件中的所有快照,“-a snapshot”是让镜像文件使用某个快照,“-c snapshot”是创建一个快照,“-d”是删除一个快照。**比如,我们现在看当下宿主机中有没有虚拟机磁盘cto74d.img的快照,可以使用-l选项查看,结果发现没有。如下:

img

此时,我们使用-c选项对该磁盘创建一个快照,此时需要注意**raw格式的磁盘文件不支持快照,因此对raw格式的磁盘创建快照时,需要将其转换为qcow2格式。同时,无论是使用快照还是创建快照都需要在关闭虚拟机的情况下进行,如果虚拟机时运行状态需要使用另一个命令virsh save vm。**如下:

img

上述快照创建成功后,我们在当前目录下查看是否新的镜像文件产生。如下:

img

发现并没有新的镜像文件产生,说明通过qemu-img该步并不会创建一个新的镜像,但是磁盘镜像的快照确实存在,因为通过-l选项可以查看。这样,我们在需要的时候,就可以使用**-a选项利用快照恢复磁盘**。同样,如果我们不需要快照,可以通过**-d选项将其删除**。如下:

img

修改磁盘镜像文件的大小resize filename[+|-]size

该命令用于改变镜像文件的大小。“+”和“-”分别表示增加和减少镜像文件的大小,size也支持K、M、G、T等单位的使用。比如,我们现在将cto67s.img磁盘镜像大小增大5G。如下:

img

在上图中,源磁盘大小为40G(红色框部分),通过resize命令增大5G后(黄色框部分),变成了45G(蓝色框部分)。需要注意的是:使用resize命令时需要小心(做好备份),如果失败,可能会导致镜像文件无法正常使用,而造成数据丢失。同时,缩小镜像的大小之前,需要在虚拟机中保证其中的文件系统有空余空间,否则数据会丢失。另外,qcow2格式文件不支持缩小镜像的操作。

至此,KVM虚拟机的存储管理实战上篇介绍完了。我们主要讲述了如何利用virsh命令行工具来管理KVM虚拟机的存储池以及存储卷等操作,以及介绍了qemu-img这个常用的命令几种用法等内容。这些内容是下一篇通过virsh命令完成快照链操作的基础,因此需要重点掌握。光说不练假把式,IT的东西就需要大量实践才能掌握,这也是IT领域没有科技创建只有最佳实践的原因。