虚拟机存储管理
四、 进阶:磁盘格式选择
在创建时,你可能会纠结磁盘格式,对于 SRE 来说,结论很明确:
- RAW: 裸格式。性能最好,但不支持快照,占用空间大(不支持稀疏文件)。
- QCOW2: 生产首选。
- 支持快照 (Snapshot)。
- 动态扩展:写多少占多少。
- 后端镜像:支持通过一个模板镜像派生出多个虚机(Linked Clone)。
前言
- 镜像文件可以存储在宿主机文件系统中,如:ext4、xfs 等
- 也可以存储在网络文件系统中,如:NFS、NAS等
- libguestfs 这样的工具可以实现对镜像文件的管理、备份、监控 等功能
KVM存储模式
- KVM的存储模式大体分为 存储池 和 存储卷
- 存储池:
- 把相关的文件放在一个池中,相当于一个集合
- 存储池包含了存储卷,并且可以包含多个存储卷
- 存储卷:
- 相当于一个具体的文件
- 存储池:
虚拟磁盘类型
固定 fixed
-
常用
-
在配置时,预先指定磁盘大小,不管在虚拟磁盘上实际存储多少数据,都将占用相同大小的宿主机磁盘空间
-
相当于 wmwarworkstation 中的立刻分配磁盘空间
动态 Dynamic
-
常用
-
初始空间占用大小,随着空间的使用逐渐增长到最大容量,但是只根据需求使用更多的空间
-
相当于 wmwarworkstation 中的不立刻分配磁盘空间
差异 Differencing
- 因为创建的是差异磁盘,所以只保存变更的数据
- 例如:将操作系统安装在父盘,然后创建差异化磁盘来执行进一步配置
虚拟镜像文件格式
常用格式
- qcow2
- 具有更多的功能,如:快照、压缩、加密等
- 可以用来代表通过模板镜像创建的虚拟机
- 因为只有虚拟机写入的扇区部分才会分配在镜像中,所以 cqow2 文件的网络传输效率较高
- 主要特点:
- 按需分配磁盘空间,不管文件系统是否支持(不依赖于文件系统)
- 支持快照
- 支持zlib的磁盘压缩
- 支持AES的加密
- 优点:
- 空间节约,功能丰富
- 缺点:
- 性能较差,但生产中推荐使用
- raw
- 此为默认的磁盘格式,但并非是一种真正的磁盘格式,而是代表虚拟机所使用的原始镜像,本质上就是一个空文件
- 本身不支持一些高级功能,如:快照、压缩等…
- 因为他的功能本身比较简单,所以可以很容易的转换成其他虚拟机的格式,相对来讲比较通用
- raw文件可以是 预分配 或 稀疏 格式
- 通常不需要通过网络传输镜像文件时,可以使用raw文件
其他格式
- cow
- qcow
- vmdk(wmware workstation使用的文件后缀)
- vhd | vhdx(微软默认采用的文件格式)
- vdi(virtual box采用的文件格式)
查看支持的文件格式
# qemu-img --help
...
Supported formats: blkdebug blklogwrites blkreplay blkverify copy-on-read file ftp ftps gluster host_cdrom host_device http https iscsi iser luks nbd null-aio null-co nvme qcow2 quorum raw rbd ssh throttle vhdx vmdk vpc
...KVM 虚拟机管理
查看虚拟机来自哪个磁盘文件
[root@centos-kvm ~]# virsh dumpxml centos7|grep centos
<name>centos7</name>
<libosinfo:os id="http://centos.org/centos/7.0"/>
<source file='/var/lib/libvirt/images/centos7-kvm.qcow2' index='2'/>
<source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-5-centos7/org.qemu.guest_agent.0'/>KVM 磁盘镜像管理
- qemu-img 是一个功能强大的磁盘镜像管理工具
创建虚拟磁盘文件
语法
create [--object objectdef] [-q] [-f fmt] [-b backing_file] [-F backing_fmt] [-u] [-o options] filename [size]创建raw格式的稀疏文件
- 不加任何选项则默认创建raw格式的稀疏文件
#创建方法一
[root@centos-kvm ~]# qemu-img create vm.img 1g
#创建方法二
[root@centos-kvm ~]# dd if=/dev/zero of=vm.img bs=1M count=0 seek=1024
[root@centos-kvm ~]# qemu-img info vm.img
image: vm.img
file format: raw #默认为raw格式
virtual size: 1 GiB (1073741824 bytes)
disk size: 4 KiB #稀疏文件
[root@centos-kvm ~]# ll -h
total 4.0K
-rw-r--r-- 1 root root 1.0G Apr 2 21:04 vm.img
[root@centos-kvm ~]# du -sh
436K .创建raw格式的非稀疏文件
#创建
[root@centos-kvm ~]# dd if=/dev/zero of=vm.img bs=1M count=1024
[root@centos-kvm ~]# qemu-img info vm.img
image: vm.img
file format: raw
virtual size: 1 GiB (1073741824 bytes)
disk size: 1 GiB #非稀疏文件
[root@centos-kvm ~]# ll -h
total 1.0G
-rw-r--r-- 1 root root 1.0G Apr 2 21:22 vm.img
[root@centos-kvm ~]# du -sh .
1.1G .非稀疏文件复制为稀疏文件
- cp 命令可以实现
指定预分配off
- 此为缺省配置,即不使用预分配策略,预分配后的虚拟磁盘占用很小,不属于稀疏映像类型,生成的磁盘文件很小
指定预分配metadata
- 只分配元数据(matadata),预分配后的磁盘文件属于稀疏格式,相当于wmware中的磁盘置备选项:Thin Provision(精简配置)
[root@centos-kvm ~]# qemu-img create -f qcow2 vm.img 1g -o preallocation=metadata
Formatting 'vm.img', fmt=qcow2 size=1073741824 cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16
[root@centos-kvm ~]# qemu-img info vm.img
image: vm.img
file format: qcow2
virtual size: 1 GiB (1073741824 bytes)
disk size: 832 KiB #分配的元数据占用的大小
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
[root@centos-kvm ~]# du -sh .
1.3M .
[root@centos-kvm ~]# ll -h
total 832K
-rw-r--r-- 1 root root 1.1G Apr 3 13:07 vm.img指定预分配falloc
- 分配文件的块并标识它们的状态为未初始化,即只分配空间,但不置零,预分配后的虚拟磁盘属于非稀疏类型,相对于full模式来说,创建虚拟磁盘的速度要快很多,相当于wmware中的磁盘置备选项:厚置备延迟置零
[root@centos-kvm ~]# qemu-img create -f qcow2 vm.img 1g -o preallocation=falloc
Formatting 'vm.img', fmt=qcow2 size=1073741824 cluster_size=65536 preallocation=falloc lazy_refcounts=off refcount_bits=16
[root@centos-kvm ~]# qemu-img info vm.img
image: vm.img
file format: qcow2
virtual size: 1 GiB (1073741824 bytes)
disk size: 2 GiB
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
[root@centos-kvm ~]# ll -h
total 2.1G
-rw-r--r-- 1 root root 1.1G Apr 3 13:10 vm.img
[root@centos-kvm ~]# du -sh .
2.1G .指定预分配full
- 分配所有磁盘空间并置零,预分配后的虚拟磁盘属于非稀疏映像类型,创建最慢,相当于wmware中的磁盘置备选项:厚置备置零
[root@centos-kvm ~]# qemu-img create -f qcow2 vm.img 1g -o preallocation=full
Formatting 'vm.img', fmt=qcow2 size=1073741824 cluster_size=65536 preallocation=full lazy_refcounts=off refcount_bits=16
[root@centos-kvm ~]# qemu-img info vm.img
image: vm.img
file format: qcow2
virtual size: 1 GiB (1073741824 bytes)
disk size: 1 GiB #实际占用的就是1G
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
[root@centos-kvm ~]# ll -h
total 1.1G
-rw-r--r-- 1 root root 1.1G Apr 3 13:17 vm.img
[root@centos-kvm ~]# du -sh .
1.1G .检查虚拟磁盘
- 对于关机的虚拟机磁盘,可以检查文件是否有错误
[root@centos-kvm ~]# qemu-img check /var/lib/libvirt/images/centos7-kvm3.qcow2
No errors were found on the image.
59783/3276800 = 1.82% allocated, 3.94% fragmented, 0.00% compressed clusters
Image end offset: 3922526208实现后备差异虚拟磁盘
- **简述:**后备差异虚拟磁盘其实就是准备一块硬盘作为所有硬盘的父硬盘,后续创建的虚拟机的基础数据都来自于这块父硬盘,然后在父硬盘的基础上修改数据
- **优点:**节省磁盘空间,无需在每台虚拟机上创建系统,因为使用的是父镜像的系统
- **缺点:**父镜像一旦损坏,其他的子镜像将全部无法使用,性能不如完整的一套系统
- **相似的场景:**数据库的差异备份,Docker创建镜像时的父镜像,WMware中的链接克隆等…
创建后备差异虚拟磁盘
- 注意:模板镜像文件可以是raw或qcow2格式,但后备磁盘差异磁盘文件必须为qcow2格式
[root@centos-kvm ~]# cd /var/lib/libvirt/images/
[root@centos-kvm images]# ll -h
...
-rw-r--r-- 1 qemu qemu 3.7G Apr 3 13:33 centos7-kvm.qcow2 #此文件为事先创建好的父硬盘文件
#基于父硬盘文件创建新的差异磁盘
[root@centos-kvm images]# qemu-img create -f qcow2 -o backing_file=centos7-kvm.qcow2 centos7-kvm-test1.qcow2
Formatting 'centos7-kvm-test1.qcow2', fmt=qcow2 size=214748364800 backing_file=centos7-kvm.qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16
#插件创建后的差异磁盘文件
[root@centos-kvm images]# ll -h
-rw-r--r-- 1 root root 196K Apr 3 13:41 centos7-kvm-test1.qcow2
...
[root@centos-kvm images]# qemu-img info centos7-kvm-test1.qcow2
image: centos7-kvm-test1.qcow2
file format: qcow2
virtual size: 200 GiB (214748364800 bytes)
disk size: 196 KiB
cluster_size: 65536
backing file: centos7-kvm.qcow2
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false基于差异磁盘文件创建虚拟机
- 注意:启动虚拟机需要父硬盘处于关机状态,并且启动后父硬盘就处于只读状态了
#检查父硬盘是否为启动状态
[root@centos-kvm images]# virsh list --all
Id Name State
----------------------------
- centos7 shut off
#基于差异磁盘文件创建虚拟机
virt-install --import --name centos7-kvm-test1 --memory 2048 --vcpus 2 --disk path=/var/lib/libvirt/images/centos7-kvm-test1.qcow2 --network network=default --graphics vnc,listen=0.0.0.0 --os-type=linix --os-variant=centos7.0启动虚拟机
- 可以通过virt-manager来管理和启动
[root@centos-kvm ~]# export DISPLAY=10.0.0.1:0.0
[root@centos-kvm ~]# virt-manager
#父镜像磁盘无法启动
[root@centos-kvm images]# virsh start centos7
error: Failed to start domain centos7
error: internal error: process exited while connecting to monitor: 2022-04-03T06:40:12.625249Z qemu-kvm: -blockdev {"node-name":"libvirt-2-format","read-only":false,"driver":"qcow2","file":"libvirt-2-storage","backing":null}: Failed to get "write" lock
Is another process using the image [/var/lib/libvirt/images/centos7-kvm.qcow2]?磁盘快照管理
磁盘快照分类
- 按快照信息保存分为:
- 内置快照:快照数据和base磁盘数据放在同一个qcow2文件中
- 外置快照:快照数据不与qcow2文件一起存放,即单独存放
- 按虚拟机状态分为:
- 关机状态快照:数据可以保持一致性
- 开启状态快照:数据无法保持一致性,类似于系统crash后的磁盘数据。使用是可能需要fsck等操作
- 按磁盘数量分为:
- 单盘快照:不涉及原子性
- 多盘快照:涉及原子性,主要分以下两点:
- 是所有盘快照点相同
- 所有盘要么快照都成功,要么快照都失败
- 主要依赖于qemu的transaction实现
qemu-img 管理磁盘快照
语法
# qemu-img --help|grep snap
...
snapshot [--object objectdef] [--image-opts] [-U] [-q] [-l | -a snapshot | -c snapshot | -d snapshot] filename
...
Parameters to snapshot subcommand:
'snapshot' is the name of the snapshot to create, apply or delete
'-a' applies a snapshot (revert disk to saved state)
'-c' creates a snapshot
'-d' deletes a snapshot
'-l' lists all snapshots in the given image范例
[root@centos-kvm ~]# virsh list --all
Id Name State
----------------------------
- centos7 shut off
- centos7-3 shut off
#查看块设备
[root@centos-kvm ~]# virsh domblklist centos7
Target Source
-----------------------------------------------------
vda /var/lib/libvirt/images/centos7-kvm.qcow2
sda -
#查看快照,如果没有快照,则无显示信息
[root@centos-kvm ~]# qemu-img snapshot -l /var/lib/libvirt/images/centos7-kvm.qcow2
#创建快照
[root@centos-kvm ~]# qemu-img snapshot -c centos7-s1 /var/lib/libvirt/images/centos7-kvm.qcow2
#再次查看快照
[root@centos-kvm ~]# qemu-img snapshot -l /var/lib/libvirt/images/centos7-kvm.qcow2
Snapshot list:
ID TAG VM SIZE DATE VM CLOCK
1 centos7-s1 0 B 2022-04-03 15:12:32 00:00:00.000
#查看快照信息方法二
[root@centos-kvm ~]# qemu-img info /var/lib/libvirt/images/centos7-kvm.qcow2
image: /var/lib/libvirt/images/centos7-kvm.qcow2
file format: qcow2
virtual size: 200 GiB (214748364800 bytes)
disk size: 3.64 GiB
cluster_size: 65536
Snapshot list:
ID TAG VM SIZE DATE VM CLOCK
1 centos7-s1 0 B 2022-04-03 15:12:32 00:00:00.000
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
#删除centos7中的文件,模拟破坏
过程省略。。。
#恢复快照(注意:关机后才能还原快照恢复故障)
qemu-img snapshot -a centos7-s1 /var/lib/libvirt/images/centos7-kvm.qcow2virsh 管理磁盘快照
#列出现有的快照
[root@centos-kvm ~]# virsh snapshot-list centos7
Name Creation Time State
-------------------------------
#创建虚拟机快照
[root@centos-kvm ~]# virsh snapshot-create centos7
Domain snapshot 1648970635 created
[root@centos-kvm ~]# virsh snapshot-list centos7
Name Creation Time State
---------------------------------------------------
1648970635 2022-04-03 15:23:55 +0800 running
#删除centos7中的文件,模拟破坏
过程省略。。
#恢复快照(注意:关机后才能还原快照恢复故障)
[root@centos-kvm ~]# virsh snapshot-revert centos7 --snapshotname 1648970635 virt-manager 管理磁盘快照
- 基于图形界面的快照管理
- …
KVM 存储池管理
存储池概述
-
libvirt可以以存储池的形式对存储进行统一管理、简化操作
-
对于虚拟机操作,存储池和存储卷并不是必须的
-
一个存储池中可以有多个存储卷
-
KVM支持的存储池类型:
-
dir:文件系统目录
-
disk:物理磁盘设备
-
fs:预格式化的块设备(比如说一个分区)
-
等…
-
virt-manager 管理存储池
- virt-manager图形工具也可以实现对存储的查看、管理、删除等操作
- …
存储池管理相关命令
[root@centos-kvm ~]# virsh --help|grep pool
allocpages Manipulate pages pool size
Storage Pool (help keyword 'pool')
find-storage-pool-sources-as find potential storage pool sources
find-storage-pool-sources discover potential storage pool sources
pool-autostart autostart a pool
pool-build build a pool
pool-create-as create a pool from a set of args
pool-create create a pool from an XML file
pool-define-as define a pool from a set of args
...
#子命令帮助
virsh pool-build --help显示存储池相关信息
- 存储池相关配置文件都存放在 /etc/libvirt/storage/ 目录下
# ll /etc/libvirt/storage/
total 12
-rw------- 1 root root 522 Mar 31 21:03 7.xml
drwxr-xr-x 2 root root 56 Mar 31 21:03 autostart
-rw------- 1 root root 538 Mar 28 16:27 default.xml
-rw------- 1 root root 530 Mar 28 19:43 ubuntu.xml
#存储池是否开机启动也是以软链接的方式实现的
# ll /etc/libvirt/storage/autostart/
total 0
lrwxrwxrwx 1 root root 26 Mar 31 21:03 7.xml -> /etc/libvirt/storage/7.xml
lrwxrwxrwx 1 root root 32 Mar 28 16:27 default.xml -> /etc/libvirt/storage/default.xml
lrwxrwxrwx 1 root root 31 Mar 28 19:43 ubuntu.xml -> /etc/libvirt/storage/ubuntu.xml
# cat /etc/libvirt/storage/autostart/ubuntu.xml
<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
virsh pool-edit ubuntu
or other application using the libvirt API.
-->
<pool type='dir'>
<name>ubuntu</name>
<uuid>dc04b819-1df9-40eb-a87d-681e3ba95755</uuid>
<capacity unit='bytes'>0</capacity>
<allocation unit='bytes'>0</allocation>
<available unit='bytes'>0</available>
<source>
</source>
<target>
<path>/data/isos/ubuntu</path>
</target>
</pool>- 范例:显示存储池信息
# virsh pool-list
Name State Autostart
-------------------------------
7 active yes
default active yes
ubuntu active yes
# virsh pool-list --uuid --name
e28d9545-23d1-4a08-9d51-e61ce675b791 7
c2ae2dfc-04bf-4d74-9994-ca6e64711e35 default
dc04b819-1df9-40eb-a87d-681e3ba95755 ubuntu
#通过存储池的名称查找UUID
# virsh pool-uuid --pool ubuntu
dc04b819-1df9-40eb-a87d-681e3ba95755
#通过UUID查找存储池的名称
# virsh pool-name dc04b819-1df9-40eb-a87d-681e3ba95755
ubuntu
#查看存储池的详细信息
# virsh pool-info ubuntu
Name: ubuntu
UUID: dc04b819-1df9-40eb-a87d-681e3ba95755
State: running
Persistent: yes
Autostart: yes
Capacity: 49.98 GiB
Allocation: 6.01 GiB
Available: 43.97 GiB实现基于目录的存储池
-
基于现有的目录实现存储池
-
查看帮助:
virsh pool-define-as --help
创建基于目录的存储池
#存储池所需目录需要事先创建,否则虽然可以创建存储池,但无法直接启动
#后期也可以先创建存储池,再使用 pool-build 命令来自动创建存储池所需目录
#创建存储池所需目录
[root@centos-kvm ~]# mkdir /data/vm_images
[root@centos-kvm ~]# chmod 700 /data/vm_images #出于安全考虑
[root@centos-kvm ~]# ll /data/vm_images_pool -d
drwx------ 2 root root 6 Apr 3 17:01 /data/vm_images
#创建存储池
# virsh pool-define-as vm_images dir --target /data/vm_images/
Pool vm_images defined
# virsh pool-list --all
Name State Autostart
-----------------------------------
7 active yes
default active yes
ubuntu active yes
vm_images inactive no #创建后的默认状态为不启用和开机不自动启动
#设置创建的存储池为启用状态
# virsh pool-start vm_images
Pool vm_images started
# virsh pool-list --all
Name State Autostart
---------------------------------
7 active yes
default active yes
ubuntu active yes
vm_images active no #启用状态
#设置创建的存储池为开机自启动
# virsh pool-autostart vm_images
Pool vm_images marked as autostarted
# virsh pool-list --all
Name State Autostart
---------------------------------
7 active yes
default active yes
ubuntu active yes
vm_images active yes
#创建存储池后生产的相关文件
# ll /etc/libvirt/storage/
...
-rw------- 1 root root 534 Apr 3 17:13 vm_images.xml
# cat /etc/libvirt/storage/vm_images.xml
<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
virsh pool-edit vm_images
or other application using the libvirt API.
-->
<pool type='dir'>
<name>vm_images</name>
<uuid>9f748d23-a872-4515-9ac9-4b0a8c39224c</uuid>
<capacity unit='bytes'>0</capacity>
<allocation unit='bytes'>0</allocation>
<available unit='bytes'>0</available>
<source>
</source>
<target>
<path>/data/vm_images</path>
</target>
</pool>删除基于目录的存储池
- 需要先停止存储池后才能删除
#停止存储池
# virsh pool-destroy --pool vm_images
Pool vm_images destroyed
# virsh pool-list --all
Name State Autostart
-----------------------------------
vm_images inactive yes
#删除存储池相关数据
# virsh pool-delete vm_images
Pool vm_images deleted
# ls /data/vm_images
ls: cannot access '/data/vm_images': No such file or directory
#但存储池配置还在
# virsh pool-list --all
Name State Autostart
-----------------------------------
vm_images inactive yes
#删除存储池配置
# virsh pool-undefine vm_images
Pool vm_images has been undefined
# cat /etc/libvirt/storage/vm_images.xml
cat: /etc/libvirt/storage/vm_images.xml: No such file or directory
# virsh pool-list --all
Name State Autostart
-------------------------------实现基于分区的存储池
- 基于现有挂载的磁盘创建分区后实现存储池
参考流程
- fdisk 创建分区 –> mkfs 创建文件系统 –> mkdir 创建存储池的挂载点目录 –> virsh 创建分区的存储池
创建基于分区的存储池
#实现前分区情况
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 1G 0 part /boot
├─sda2 8:2 0 30G 0 part /
└─sda3 8:3 0 50G 0 part /data
#创建分区
# fdisk /dev/sda
...
Command (m for help): n #n表示创建一个新的分区
...
Select (default e): e #e表示创建一个扩展分区
...
First sector (169871360-209715199, default 169871360): #回车选择默认的开始范围
...
Last sector, +sectors or +size{K,M,G,T,P} (169871360-209715199, default 209715199): #直接敲回车,将剩余所有空间都设为扩展分区(因为主分区已经有三个了)
Command (m for help): p #查看
Disk /dev/sda: 100 GiB, 107374182400 bytes, 209715200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xc0a5b2de
Device Boot Start End Sectors Size Id Type
/dev/sda1 * 2048 2099199 2097152 1G 83 Linux
/dev/sda2 2099200 65013759 62914560 30G 83 Linux
/dev/sda3 65013760 169871359 104857600 50G 83 Linux
/dev/sda4 169871360 209715199 39843840 19G 5 Extended
Command (m for help): n #创建一个逻辑分区
All primary partitions are in use.
Adding logical partition 5
First sector (169873408-209715199, default 169873408): #回车
Last sector, +sectors or +size{K,M,G,T,P} (169873408-209715199, default 209715199): +10G #选择10G用于测试
...
Command (m for help): w #保存
#查看新创建的分区
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
├─sda1 8:1 0 1G 0 part /boot
├─sda2 8:2 0 30G 0 part /
├─sda3 8:3 0 50G 0 part /data
├─sda4 8:4 0 1K 0 part
└─sda5 8:5 0 10G 0 part #新创建的分区
#为新创建的分区创建文件系统
# mkfs.ext4 /dev/sda5
...
#查看创建的文件系统
# lsblk -f /dev/sda5
NAME FSTYPE LABEL UUID MOUNTPOINT
sda5 ext4 2c037a1c-8408-4352-83f9-26a18e847b86
#基于创建的分区创建存储池(注意:新创建的分区一定要创建文件系统)
# virsh pool-define-as vm_images_fs fs --source-dev "/dev/sda5" --target /vm_images
Pool vm_images_fs defined
#查看新创建的存储池
# virsh pool-list --all
Name State Autostart
--------------------------------------
vm_images_fs inactive no
#构建存储池(构建后会自动生成挂载点)
# virsh pool-build vm_images_fs
Pool vm_images_fs built
# ll /vm_images/ -d
drwx--x--x 2 root root 6 Apr 3 18:02 /vm_images/
#启动存储池(启动后会自动挂载)
# virsh pool-start vm_images_fs
Pool vm_images_fs started
# df -hT
Filesystem Type Size Used Avail Use% Mounted on
...
/dev/sda4 ext4 9.8G 37M 9.3G 1% /vm_images
#查看存储池的信息
# virsh pool-info --pool vm_images_fs
Name: vm_images_fs
UUID: 42c8869e-67e8-4811-8839-eecf5abb9d6c
State: running
Persistent: yes
Autostart: no
Capacity: 9.78 GiB
Allocation: 36.02 MiB
Available: 9.75 GiB
#将存储池设备开机自启动(否则开机后不会自动挂载)
# virsh pool-autostart vm_images_fs
Pool vm_images_fs marked as autostarted
# virsh pool-info --pool vm_images_fs
Name: vm_images_fs
UUID: 42c8869e-67e8-4811-8839-eecf5abb9d6c
State: running
Persistent: yes
Autostart: yes
Capacity: 9.78 GiB
Allocation: 36.02 MiB
Available: 9.75 GiB
#可以重启测试是否可以自动挂载(前提不影响业务)
# reboot
#重启后查看
# df /dev/sda5
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda5 10255636 36888 9678076 1% /vm_images
#将储存池设为开机不启动
# virsh pool-autostart vm_images_fs --disable
Pool vm_images_fs unmarked as autostarted删除基于分区的存储池
#停止存储池
# virsh pool-destroy vm_images_fs
Pool vm_images_fs destroy
#删除存储池相关数据
# virsh pool-delete vm_images_fs
Pool vm_images_fs deleted
#删除存储池配置
# virsh pool-undefine vm_images_fs
Pool vm_images_fs has been undefined
#查看存储池删除情况
# virsh pool-list --all
# df
# ll /vm_images实现基于磁盘的存储池
- 使用一块完整的硬盘实现存储池
创建基于磁盘的存储池
- 假设添加了一块30G的硬盘,过程省略…
#不重启的方式扫描硬盘
# echo '- - -' > /sys/class/scsi_host/host0/scan;echo '- - -' > /sys/class/scsi_host/host1/scan;echo '- - -' > /sys/class/scsi_host/host2/scan;echo '- - -' > /sys/class/scsi_host/host3/scan
#查看新添加的硬盘
# lsblk /dev/sdb
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb 8:16 0 30G 0 disk
#创建分区和文件系统
过程省略...
#查看创建后的结果
# lsblk -f /dev/sdb
NAME FSTYPE LABEL UUID MOUNTPOINT
sdb
└─sdb1 ext4 8d66aaa1-507b-4a0c-8822-1d48c4fe7d26
#准备基于磁盘储存池的配置文件(type类型中dos代表mbr分区,gpt表示gpt分区)
# vim vm_images_disk.xml
<pool type='disk'>
<name>vm_images_disk</name>
<source>
<device path='/dev/sdb'/>
<format type='dos'/>
</source>
<target>
<path>/dev</path>
</target>
</pool>
#创建基于磁盘的存储池
# virsh pool-define vm_images_disk.xml
Pool vm_images_disk defined from vm_images_disk.xml
# virsh pool-list --all
Name State Autostart
----------------------------------------
vm_images_disk inactive no
#启动基于磁盘的存储池
# virsh pool-start vm_images_disk
Pool vm_images_disk started
# virsh pool-list --all
Name State Autostart
--------------------------------------
vm_images_disk active no
#基于磁盘的存储池设置为开机启动
# virsh pool-autostart vm_images_disk
Pool vm_images_disk marked as autostarted
# virsh pool-list --all
Name State Autostart
--------------------------------------
vm_images_disk active yes
#最后可以再virt-manager的storage中查看删除基于磁盘的存储池
- **注意:**基于磁盘的存储池不支持pool-delete
- 下面是删除步骤:
#停止存储池
# virsh pool-destroy vm_images_disk
Pool vm_images_disk destroyed
# virsh pool-list --all
Name State Autostart
----------------------------------------
vm_images_disk inactive yes
#删除存储池配置
# virsh pool-undefine vm_images_disk
Pool vm_images_disk has been undefined
#查看是否删除
# virsh pool-list --all
Name State Autostart
----------------------------------------实现基于LVM的存储池
- 注意:基于LVM的存储池要求使用VG中的全部磁盘空间
- 基于LVM 创建存储池有两种方法:
- 创建新的VG 来创建存储池
- 使用现有的VG 来创建存储池
无卷组的场景创建存储池
- 相关命令说明:
- source-dev 指定硬盘设备,基于硬盘设备创建卷组,事先无卷组时此项才需指定
- 先决条件:
- 宿主机具有一块空硬盘
准备硬盘
[root@centos-kvm ~]# lsblk /dev/sdc
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdc 8:32 0 30G 0 disk创建存储池
#查看是否有存在的卷组
[root@centos-kvm ~]# pvs
#创建存储池
[root@centos-kvm ~]# virsh pool-define-as vm_images_lvm logical --source-dev /dev/sdc
Pool vm_images_lvm defined
#构建存储池同时构建卷组
[root@centos-kvm ~]# virsh pool-build vm_images_lvm
Pool vm_images_lvm built
#查看virsh命令自动构建的物理卷
[root@centos-kvm ~]# pvs
PV VG Fmt Attr PSize PFree
/dev/sdc vm_images_lvm lvm2 a-- <30.00g <30.00g
#查看virsh命令自动构建的卷组
[root@centos-kvm ~]# vgs
VG #PV #LV #SN Attr VSize VFree
vm_images_lvm 1 0 0 wz--n- <30.00g <30.00g
#查看生成的存储池
[root@centos-kvm ~]# virsh pool-list --all
Name State Autostart
------------------------------------
...
vm_images_lvm inactive no
#启动
[root@centos-kvm ~]# virsh pool-start vm_images_lvm
Pool vm_images_lvm started
#设为开机自启动
[root@centos-kvm ~]# virsh pool-autostart vm_images_lvm
Pool vm_images_lvm marked as autostarted
#再次查看
[root@centos-kvm ~]# virsh pool-list --all
Name State Autostart
-------------------------------------
...
vm_images_lvm active yes有卷组的场景创建存储池
- 相关命令说明:
- source-name 指定已有卷组名,基于现有卷组创建存储池,事先有卷组时此项才需指定
查看现有卷组
[root@centos-kvm ~]# pvs
PV VG Fmt Attr PSize PFree
/dev/sdc vm_images_lvm lvm2 a-- <30.00g <30.00g
[root@centos-kvm ~]# vgs
VG #PV #LV #SN Attr VSize VFree
vm_images_lvm 1 0 0 wz--n- <30.00g <30.00g创建存储池
#创建
[root@centos-kvm ~]# virsh pool-define-as vm_images2_lvm logical --source-name=vm_images_lvm
Pool vm_images2_lvm defined
#查看生成的存储池
[root@centos-kvm ~]# virsh pool-list --all
Name State Autostart
----------------------------------------
...
vm_images2_lvm inactive no
#启动
[root@centos-kvm ~]# virsh pool-start vm_images2_lvm
Pool vm_images2_lvm started
#设为开机自启动
[root@centos-kvm ~]# virsh pool-autostart vm_images2_lvm
Pool vm_images2_lvm marked as autostarted
#再次查看
[root@centos-kvm ~]# virsh pool-list --all
Name State Autostart
-------------------------------------
...
vm_images2_lvm active yes后语
- virt-manager工具也可以创建
实现基于NFS的存储池
环境说明
| IP | service |
|---|---|
| 10.0.0.8 | KVM |
| 10.0.0.18 | NFS |
NFS server 配置
- 安装过程省略…
#安装NFS
[root@nfs-server ~]# yum -y install nfs-utils
#创建共享目录
[root@nfs-server ~]# mkdir -p /data/kvm_pool_data
#修改配置文件(要开启rw读写 和 只读远程用户以root身份创建,否则将变成只读和权限拒绝 从而无法创建新的文件)
[root@nfs-server ~]# vim /etc/exports.d/kvm_pool.exports
/data/kvm_pool_data 10.0.0.0/24(rw,no_roots_squash)
#启动NFS
[root@nfs-server ~]# systemctl enable --now nfs-server.service
#验证配置
[root@nfs-server ~]# exportfs -v
/data/kvm_pool_data
10.0.0.0/24(sync,wdelay,hide,no_subtree_check,sec=sys,rw,secure,no_root_squash,no_all_squash)创建基于磁盘的存储池
NFS挂载配置
#安装 fs-utils 包
[root@centos-kvm ~]# yum -y install nfs-utils
#查看远程主机的NFS共享
[root@centos-kvm ~]# showmount -e 10.0.0.18
Export list for 10.0.0.18:
/data/kvm_pool_data 10.0.0.0/24
#创建本机的挂载目录
[root@centos-kvm ~]# mkdir /data/kvm_pool_data/
#永久挂载
[root@centos-kvm ~]# vim /etc/fstab
...
10.0.0.18:/data/kvm_pool_data/ /data/kvm_pool_data/ nfs _netdev 0 0
...
#同步挂载
[root@centos-kvm ~]# mount -a
#查看挂载信息
[root@centos-kvm ~]# df -h
Filesystem Size Used Avail Use% Mounted on
...
10.0.0.18:/data/kvm_pool_data 50G 389M 50G 1% /data/kvm_pool_dataKVM配置
#创建
[root@centos-kvm ~]# virsh pool-define-as vm_images_nfs netfs --source-host 10.0.0.18 --source-path /data/kvm_pool_data/ --target /data/kvm_pool_data/
Pool vm_images_nfs defined
#使用pool-build自动创建挂载点(可选项,也可以使用上面的手动挂载方式)
[root@centos-kvm ~]# virsh pool-build vm_images_nfs
#默认为未启动和开机不自动启动
[root@centos-kvm ~]# virsh pool-list --all
Name State Autostart
---------------------------------------
vm_images_nfs inactive no
#启动
[root@centos-kvm ~]# virsh pool-start vm_images_nfs
Pool vm_images_nfs started
#设为开机启动
[root@centos-kvm ~]# virsh pool-autostart vm_images_nfs
Pool vm_images_nfs marked as autostarted
[root@centos-kvm ~]# virsh pool-list --all
Name State Autostart
-------------------------------------
vm_images_nfs active yes
[root@centos-kvm ~]# virsh pool-info vm_images_nfs
Name: vm_images_nfs
UUID: 304d5f75-9540-4551-a98f-f42a46190bfe
State: running
Persistent: yes
Autostart: yes
Capacity: 49.98 GiB
Allocation: 389.00 MiB
Available: 49.60 GiB
[root@centos-kvm ~]# cat /etc/libvirt/storage/vm_images_nfs.xml
<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
virsh pool-edit vm_images_nfs
or other application using the libvirt API.
-->
<pool type='netfs'>
<name>vm_images_nfs</name>
<uuid>304d5f75-9540-4551-a98f-f42a46190bfe</uuid>
<capacity unit='bytes'>0</capacity>
<allocation unit='bytes'>0</allocation>
<available unit='bytes'>0</available>
<source>
<host name='10.0.0.18'/>
<dir path='/data/kvm_pool_data'/>
<format type='auto'/>
</source>
<target>
<path>/data/kvm_pool_data</path>
</target>
</pool>
[root@centos-kvm ~]# df -h
Filesystem Size Used Avail Use% Mounted on
...
10.0.0.18:/data/kvm_pool_data 50G 389M 50G 1% /data/kvm_pool_data删除基于磁盘的存储池
#停止
[root@centos-kvm ~]# virsh pool-destroy vm_images_nfs
Pool vm_images_nfs destroyed
#删除
[root@centos-kvm ~]# virsh pool-undefine vm_images_nfs
Pool vm_images_nfs has been undefined
#查看删除的结果
[root@centos-kvm ~]# df | grep kvm_pool_data
[root@centos-kvm ~]# virsh pool-info vm_images_nfs
error: failed to get pool 'vm_images_nfs'
error: Storage pool not found: no storage pool with matching name 'vm_images_nfs'KVM 存储卷管理
存储卷概述
一个存储池可以被分割为多个存储卷(storage volume)
存储卷可以为以下类型:
- 文件
- 块设备(物理分区、LVM逻辑卷等)
- libvirt管理的其他类型存储抽象
存储卷管理相关命令
[root@centos-kvm ~]# virsh help volume
Storage Volume (help keyword 'volume'):
vol-clone clone a volume.
vol-create-as create a volume from a set of args
vol-create create a vol from an XML file
vol-create-from create a vol, using another volume as input
vol-delete delete a vol
vol-download download volume contents to a file
vol-dumpxml vol information in XML
vol-info storage vol information
vol-key returns the volume key for a given volume name or path
vol-list list vols
vol-name returns the volume name for a given volume key or path
vol-path returns the volume path for a given volume name or key
vol-pool returns the storage pool for a given volume key or path
vol-resize resize a vol
vol-upload upload file contents to a volume
vol-wipe wipe a vol子命令帮助
[root@centos-kvm ~]# virsh help vol-clone
NAME
vol-clone - clone a volume.
SYNOPSIS
vol-clone <vol> <newname> [--pool <string>] [--prealloc-metadata] [--reflink]
DESCRIPTION
Clone an existing volume within the parent pool.
OPTIONS
[--vol] <string> vol name, key or path
[--newname] <string> clone name
--pool <string> pool name or uuid
--prealloc-metadata preallocate metadata (for qcow2 instead of full allocation)
--reflink use btrfs COW lightweight copy基于目录的存储池的存储卷管理
创建基于目录的存储池
#创建存储池
# virsh pool-define-as vm_images dir --target /data/vm_images_dir/
Pool vm_images defined
#构建存储池(构建后virsh会自动创建存储池所需目录)
# virsh pool-build vm_images
Pool vm_images built
#设置创建的存储池为启用状态
# virsh pool-start vm_images
Pool vm_images started
#设置创建的存储池为开机自启动
# virsh pool-autostart vm_images
Pool vm_images marked as autostarted
# virsh pool-list --all
Name State Autostart
---------------------------------
...
vm_images active yes
#创建存储池后生产的相关文件
# cat /etc/libvirt/storage/vm_images.xml
<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
virsh pool-edit vm_images
or other application using the libvirt API.
-->
<pool type='dir'>
<name>vm_images</name>
<uuid>93201420-a64d-4361-886e-e4ba08bc121c</uuid>
<capacity unit='bytes'>0</capacity>
<allocation unit='bytes'>0</allocation>
<available unit='bytes'>0</available>
<source>
</source>
<target>
<path>/data/vm_images_dir</path>
</target>
</pool>
# virsh pool-dumpxml vm_images
<pool type='dir'>
<name>vm_images</name>
<uuid>93201420-a64d-4361-886e-e4ba08bc121c</uuid>
<capacity unit='bytes'>53660876800</capacity>
<allocation unit='bytes'>6452051968</allocation>
<available unit='bytes'>47208824832</available>
<source>
</source>
<target>
<path>/data/vm_images_dir</path>
<permissions>
<mode>0711</mode>
<owner>0</owner>
<group>0</group>
</permissions>
</target>
</pool>创建基于目录的存储池的存储卷
#创建
# virsh vol-create-as vm_images test.qcow2 1g --format qcow2
Vol test.qcow2 created
#查看创建的基于目录的存储池的存储卷
# ll -h /data/vm_images_dir/
total 196K
-rw------- 1 root root 193K Apr 4 23:10 test.qcow2
# virsh vol-list vm_images
Name Path
----------------------------------------------
test.qcow2 /data/vm_images_dir/test.qcow2
# virsh vol-info test.qcow2 --pool vm_images
Name: test.qcow2
Type: file
Capacity: 1.00 GiB
Allocation: 196.00 KiB
# virsh vol-info /data/vm_images_dir/test.qcow2
Name: test.qcow2
Type: file
Capacity: 1.00 GiB
Allocation: 196.00 KiB
# qemu-img info /data/vm_images_dir/test.qcow2
image: /data/vm_images_dir/test.qcow2
file format: qcow2
virtual size: 1 GiB (1073741824 bytes)
disk size: 196 KiB
cluster_size: 65536
Format specific information:
compat: 0.10
refcount bits: 16删除基于目录的存储池的存储卷
#删除前
# ls /data/vm_images_dir/
test.qcow2
#删除
# virsh vol-delete test.qcow2 --pool vm_images
Vol test.qcow2 deleted
#删除后
# ls /data/vm_images_dir/基于LVM的存储池的存储卷管理
创建基于LVM的存储池
- 下面基于事先无卷组的场景创建LVM的存储池
#查看是否有存在的卷组
# pvs
#准备硬盘
# lsblk /dev/sdc
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdc 8:32 0 30G 0 disk
#创建存储池
# virsh pool-define-as vm_images_lvm logical --source-dev /dev/sdc
Pool vm_images_lvm defined
#构建存储池同时构建卷组
# virsh pool-build vm_images_lvm
Pool vm_images_lvm built
#启动
# virsh pool-start vm_images_lvm
Pool vm_images_lvm started
#设为开机自启动
# virsh pool-autostart vm_images_lvm
Pool vm_images_lvm marked as autostarted
#再次查看
# virsh pool-list --all
Name State Autostart
-------------------------------------
...
vm_images_lvm active yes创建基于LVM的存储池的存储卷
#创建前查看是否有逻辑卷
# lvs
#创建基于LVM的存储池的存储卷
# virsh vol-create-as vm_images_lvm lv_vol1 8g
Vol lv_vol1 created
#查看存储池中的存储卷
# virsh vol-list vm_images_lvm
Name Path
---------------------------------------
lv_vol1 /dev/vm_images_lvm/lv_vol1
#查看自动创建的逻辑卷
# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv_vol1 vm_images_lvm -wi-a----- 8.00g 删除基于LVM的存储池的存储卷
#删除前查看存储池中的存储卷
# virsh vol-list vm_images_lvm
Name Path
---------------------------------------
lv_vol1 /dev/vm_images_lvm/lv_vol1
#删除
# virsh vol-delete lv_vol1 vm_images_lvm
Vol lv_vol1 deleted
#删除后查看
# virsh vol-list vm_images_lvm
Name Path
--------------利用存储卷创建虚拟机
- 可以使用virt-manager工具创建
- 也可以使用命令行创建
- 和之前创建虚拟机的流程一样,只不过就是免去了创建存储卷这一步
clone存储卷
clone基于文件的存储卷
查看目前基于文件的存储卷
# virsh vol-list default
Name Path
------------------------------------------------------------------
centos7-kvm.qcow2 /var/lib/libvirt/images/centos7-kvm.qcow2
centos7-kvm3.qcow2 /var/lib/libvirt/images/centos7-kvm3.qcow2
#查看default存储池中centos7-kvm.qcow2存储卷的详细信息
# virsh vol-info centos7-kvm.qcow2 default
Name: centos7-kvm.qcow2
Type: file
Capacity: 200.00 GiB
Allocation: 4.12 GiBclone基于文件的存储卷
#clone
# virsh vol-clone centos7-kvm.qcow2 centos7-kvm_clone.qcow2 default
#查看clone结果
# virsh vol-info centos7-kvm_clone.qcow2 default
Name: centos7-kvm_clone.qcow2
Type: file
Capacity: 200.00 GiB
Allocation: 1.86 GiB
# ll /var/lib/libvirt/images/ -h
total 9.7G
-rw-r--r-- 1 qemu qemu 3.7G Apr 5 00:30 centos7-kvm3.qcow2
-rw-r--r-- 1 qemu qemu 1.9G Apr 5 00:39 centos7-kvm_clone.qcow2 #clone后占用空间较小
-rw-r--r-- 1 qemu qemu 4.0G Apr 3 18:01 centos7-kvm.qcow2clone基于LVM的存储卷
查看目前基于LVM的存储卷
# virsh vol-list vm_images_lvm
Name Path
---------------------------------------
lv_vol1 /dev/vm_images_lvm/lv_vol1
# virsh vol-info lv_vol1 vm_images_lvm
Name: lv_vol1
Type: block
Capacity: 8.00 GiB
Allocation: 8.00 GiB
# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv_vol1 vm_images_lvm -wi-a----- 8.00g clone基于LVS的存储卷
#clone
# virsh vol-clone lv_vol1 lv_vol1_clone vm_images_lvm
Vol lv_vol1_clone cloned from lv_vol1
#查看clone的存储卷
# lvs
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
lv_vol1 vm_images_lvm -wi-a----- 8.00g
lv_vol1_clone vm_images_lvm -wi-a----- 8.00g
# virsh vol-info lv_vol1_clone vm_images_lvm
Name: lv_vol1_clone
Type: block
Capacity: 8.00 GiB
Allocation: 8.00 GiB向虚拟机添加存储卷
- 可以通过attach-device 和 attach-disk 给现有虚拟机添加存储卷,从而实现给虚拟机添加新的虚拟磁盘
attach-device 通过XML文件给已有虚拟机添加存储卷
- …
attach-disk 给已有虚拟机添加存储卷
#登录到虚拟机中查看添加存储卷前的磁盘情况
# ssh 192.168.122.208
...
[root@localhost ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 253:0 0 200G 0 disk
├─vda1 253:1 0 1G 0 part /boot
├─vda2 253:2 0 50G 0 part /
└─vda3 253:3 0 50G 0 part /data
#使用 attach-disk 子命令给已有虚拟机添加存储卷
[root@centos-kvm ~]# virsh attach-disk --domain centos7 --sourcetype block --source /dev/vm_images_lvm/lv_vol1 --target vdb
Disk attached successfully
#查看添加存储卷后的磁盘情况
[root@localhost ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 253:0 0 200G 0 disk
├─vda1 253:1 0 1G 0 part /boot
├─vda2 253:2 0 50G 0 part /
└─vda3 253:3 0 50G 0 part /data
vdb 253:16 0 8G 0 disk #添加的存储卷