环境搭建和准备
# 查看cpu是否支持硬件虚拟化
grep -E -c "vmx|svm" /proc/cpuinfo
sudo apt install -y qemu qemu-kvm libvirt-daemon bridge-utils virt-manager virtinst
# if centos
# yum install -y kvm virt-manager libvirt libvirt-python python-virtinst virt-install qemu-kvm
lsmod | grep -i kvm
sudo systemctl status libvirtd.service
# 如果服务未启动
sudo systemctl enable libvirtd --now
# 配置网桥使得libvirt可以从外部访问
cat /etc/netplan/00-installer-config.yaml
# 可选,GUI管理工具
sudo apt-get install virt-manager python-spice-client-gtk
下载调试镜像: 从官方地址下载cirros镜像,用来调试虚拟机,用户名和密码如下
user:cirros
pass:cubswin:) # 不同版本密码不同
通常将cirros镜像放置到
/var/lib/libvirt/boot
路径下可以查看镜像信息
qemu-img info cirros-0.5.0-x86_64-disk.img
至此,vrish学习的基本环境就搭建完成
Libvirt基本概念
virsh命令大概分组
- Domain Management(域管理)
- Domain Monitoring(域监控)
- Host and Hypervisor(主机及虚拟化)
- Interface(网卡接口)
- Network Filter(网络防火墙)
- Networking(网络)
- Node Device(节点设备驱动)存在
- Secret
- Snapshot(快照)
- Storage Pool(存储池或存储策略)
- Storage Volume(存储卷)
- Virsh itself(virsh shell自身相关)
定义过的或者能够被libvirt感知到的虚机的配置文件都在
/etc/libvirt
目录下虚拟机文件和其它的相关文件都保存在
/var/lib/libvirt/
下镜像的默认路径是
/var/lib/libvirt/boot/
。
上图时一个libvirt虚拟机的生命周期图,虚拟机分为两种:
- 持久性的
- 短暂性的
持久性虚拟机会一直存在,直到被删除;
短暂性的虚拟机只有在虚拟机被关机或重启前存在
虚拟机常用命令
virsh和qemu的命令非常多,下面罗列一些常用的命令
virsh help # 查看帮助信息
virsh version # 查看qemu版本
virsh help <特定命令> # 查看特定命令帮助信息
virsh <特定命令> --help # 查看特定命令帮助信息
virsh nodeinfo # 查看宿主机信息
virsh uri # 查看当前主机hyperviso的连接路径;
virsh connect <hypervisor uri> # 连接到特定hypervisor,默认qemu:///system
virsh sysinfo # 查看hypervisro信息
virsh start <虚拟机名称> # 启动一个之前已经定义define过的虚拟机(domain)
virsh shutdown <虚拟机名称> # 关闭虚拟机,类似虚拟机内执行关机
virsh reboot <虚拟机名称> # 重启虚拟机
virsh destroy <虚拟机名称> # 强制关闭虚拟机,类似于断电
virsh suspend <虚拟机名称> # 挂起虚拟机,将当前状态保存在内存中
virsh resume <虚拟机名称> # 恢复虚拟机挂起状态,从内存中恢复虚拟机状态
virsh save <虚拟机名称> <img镜像文件名> # 暂停虚拟机,将虚拟机状态保存在磁盘镜像文件中
virsh restore <img镜像文件名> #重新载入暂停的虚拟机
virsh autostart <虚拟机名称> # 虚拟机随着物理机启动自动启动
virsh autostart <虚拟机名称> --disable # 禁止开机启动
virsh dominfo <虚拟机名称> # 查看虚拟机domain信息
virsh domblklist <虚拟机名称> # 列出虚拟机所有块存储设备
virsh console <虚拟机名称> # 控制台连接虚拟机
virsh dumpxml <虚拟机名称> # 查看虚拟机xml文件
virsh edit <虚拟机名称> # 编辑虚拟机xml文件
virsh managedsave <虚拟机名称> # 保存状态save并关闭虚拟机,下次启动会恢复到之前保存的状态
virsh start <虚拟机名称> # 启动并恢复managedsave保存的状态
virsh reset <虚拟机名称> # 对虚拟机执行强制重启,类似重置电源按钮
virsh create <虚拟机xml文件> # 从xml文件中创建domain,创建完成后会自动启动;
# 一个xml对应一个domain虚拟机
virsh define <虚拟机xml文件> # 从xml文件定义define新的domain,不会自动启动
virsh undefine <虚拟机名称> # 对于运行中的持久性虚拟机,将状态转换为暂时的,关机后virsh无法感知其存在
# 对于非活动的虚拟机,undefine后virsh将无法感知其存在
# undefine后磁盘依然存在,只是删除虚拟机的配置文件/etc/libvirt/qemu
virsh undefine <虚拟机名称> --remove-all-storage # 删除虚拟机并删除所有磁盘文件
virsh snapshot-create-as <虚拟机名称> --name <快照名称> # 从命令行创建快照
virsh snapshot-create <虚拟机名称> # 从xml文件创建快照
virsh snapshot-list <虚拟机名称> # 查看虚拟机快照列表
virsh snapshot-parent <虚拟机名称> --current # 查看当前快照的上一级快照
virsh snapshot-edit <虚拟机名称> --snapshotname <快照名> # 编辑快照
virsh snapshot-revert <虚拟机名称> --snapshotname <快照名> # 恢复快照
virsh snapshot-delete <虚拟机名称> --snapshotname <快照名> # 删除快照
virsh list # 查看活动虚拟机状态
virsh list --all # 查看所有虚拟机状态
virsh setvcpus <虚拟机名称> 4 --maximum --config # 设置最大vcpu数(只能用--config,下次运行生效)
virsh setvcpus <虚拟机名称> 4 --config # 下次启动使用vcpu数
virsh vcpuinfo <虚拟机名称> # 查看vcpu信息
virsh vcpupin <虚拟机名称> # 查询域 vcpu亲和性,即vcpu和物理cpu之间关系
virsh maxvcpus # 显示本机vcpu最大值
virsh setmaxmem <虚拟机名称> [--size] 2G --current # 设置最大内存限制值
virsh setmem <虚拟机名称> [--size] 2G --current # 设置内存分配
virsh domblklist cirros # 查看虚拟机的存储块设备
创建磁盘文件
#qcow2是文件类型,test1-add1.qcow2是磁盘文件,5G是大小
qemu-img create -f qcow2 /var/lib/libvirt/images/test1-add1.qcow2 5G
qemu-img info <虚拟机镜像> # 查看镜像信息
virt-install <命令行> # 通过命令行指定来创建虚拟机
virsh attach-disk <虚拟机名称>
virsh attach-device <虚拟机名称> /etc/libvirt/qemu/test2-add.xml --persistent # 从XML文件附加设备
virsh detach-device <虚拟机名称> /etc/libvirt/qemu/test2-add.xml --persistent # 卸载设备
虚拟机操作实践
实验1:修改虚拟机vcpu
修改虚拟机的最大vcpu数量,可以修改maximum config 和current config的值
# 查看vcpu配置
➜ ~ virsh vcpucount cirros
maximum config 2 # 指定下次重启虚拟机后可用的最大vcpu数量
maximum live 2 # 指定运行/暂停状态下虚拟机可用的最大vcpu数量,重启后和maximum config一致
current config 2 # 下次重启时虚拟机使用的vcpu数量
current live 2 # 正在运行的虚拟机vcpu实际数量
通过修改xml文件修改vcpu数量
virsh edit cirros
# <vcpu placement='static'>2</vcpu>
# 修改为
<vcpu placement='static'>3</vcpu>
关闭并重新启动虚拟机
virsh shutdown cirros
virsh list --all # 确认已经是shut off状态
virsh start cirros
再次查看vcpu数量,发现已经改变
➜ ~ virsh vcpucount cirros
maximum config 3
maximum live 3
current config 3
current live 3
同样方式,修改xml文件,恢复为2个vcpu,执行virsh reboot 后并没释放vcpu
➜ ~ virsh vcpucount cirros
maximum config 2
maximum live 3
current config 2
current live 3
必须执行shutdown或者destory,然后重新start才能改变运行时的vcpu
➜ ~ virsh vcpucount cirros
maximum config 2
maximum live 2
current config 2
current live 2
还可以通过命令行修改vcpu的各个配置值
➜ ~ virsh setvcpus cirros 3 --maximum --config
➜ ~ virsh vcpucount cirros
maximum config 3
maximum live 2
current config 2
current live 2
➜ ~ virsh setvcpus cirros 3 --config # 修改current config
➜ ~ virsh vcpucount cirros
maximum config 3
maximum live 2
current config 3
current live 2
# 重启虚拟机使其生效
➜ ~ virsh shutdown cirros
➜ ~ virsh start cirros
➜ ~ virsh vcpucount cirros
maximum config 3
maximum live 3
current config 3
current live 3
在宿主机上无法设置vcpu的current live小于current config,只能在虚拟机内部执行
chcpu
指令来修改,使得vcpu离线也可以将最大可用vcpu设置较大,方便后续在虚拟机运行时可以动态调整vcpu的数量
➜ ~ virsh setvcpus cirros 5 --maximum --config
➜ ~ virsh setvcpus cirros 2 --config
➜ ~ virsh shutdown cirros
➜ ~ virsh start cirros
➜ ~ virsh vcpucount cirros
maximum config 5
maximum live 5
current config 2
current live 2
➜ ~ virsh setvcpus cirros 3 # 动态调整vcpu数量,调整范围[current config,比maximum config]
➜ ~ virsh vcpucount cirros
maximum config 5
maximum live 5
current config 2
current live 3
➜ ~ virsh setvcpus cirros 2
➜ ~ virsh vcpucount cirros
maximum config 5
maximum live 5
current config 2
current live 2
➜ ~ virsh vcpuinfo cirros # 查看vcpu运行状态
实验2:修改虚拟机的内存
通过修改xml配置文件并重新启动虚拟机
# 修改项,修改完成后
<memory unit='KiB'>462144</memory> # 启动后最大允许可用内存
<currentMemory unit='KiB'>262144</currentMemory># 启动时使用的内存大小
在最大可用内存范围内,可以在虚拟机运行时调整内存使用
虚拟机最大内存只能在虚拟机关闭状态更改,重启后生效
使用virsh setmaxmem命令,和直接修改xml文件等效
➜ ~ virsh dominfo cirros | grep memory # 虚拟机启动时显示的used memory不准确
Max memory: 462144 KiB
Used memory: 262144 KiB
➜ ~ virsh setmem cirros 300000
➜ ~ virsh dominfo cirros | grep memory
Max memory: 462144 KiB
Used memory: 300000 KiB
➜ ~ virsh shutdown cirros
➜ ~ virsh setmaxmem cirros 700000
实验3:调整虚拟机的磁盘
虚拟机支持在虚拟机开机时动态挂载新的磁盘
➜ ~ qemu-img create -f qcow2 -o size=20M,preallocation=metadata /var/lib/libvirt/boot/second.qcow2
Formatting '/var/lib/libvirt/boot/second.qcow2', fmt=qcow2 size=20971520 cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16
➜ ~ qemu-img info /var/lib/libvirt/boot/second.qcow2
image: /var/lib/libvirt/boot/second.qcow2
file format: qcow2
virtual size: 20 MiB (20971520 bytes)
disk size: 260 KiB
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
virsh attach-disk cirros /images/cirros/second.qcow2 vda --targetbus virtio
# 卸载磁盘(前提时没有分区或者挂载
virsh detach-disk 26 vda
也可以手动修改xml文件,然后重启虚拟机
# 首先创建一个qcow2磁盘或者raw磁盘
# dd命令创建一个非稀疏的磁盘
dd if=/dev/zero of=/vm-images/vm1-add.img bs=1M count=1024
# 在xml文件中加入一个新的xml段
<disk type='file' device='disk'>
<driver name='qemu' type='raw' cache='none' io='threads'/>
<source file='/vm-images/vm1-add.img'/>
<target dev='vdb' bus='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
</disk>
实验4:创建虚拟机
virt-install --name=cirros --ram=256 --vcpus=1 --disk path=/var/lib/libvirt/boot/cirros-0.5.0-x86_64-disk.img,format=qcow2 --import --network network:default --vnc --vncport=5920
# 也可以通过xml文件来创建
实验5:复制虚拟机
可以通过命令行复制一个虚拟机,也可以通过拷贝并修改配置文件和存储卷文件进行复制
# 通过virt-clone命令复制
# virt-clone -o <虚拟机名称> -n <新虚拟机名称> -f /var/lib/libvirt/images/test4.qcow2
# qcow2磁盘不需要预先创建,创建完成后需要进虚拟机手动改变ip地址和用户名
➜ ~ virt-clone -o cirros -n cirros1 -f /var/lib/libvirt/boot/cirros1.qcow2
# 自动生产不一样的mac地址和uuid
➜ ~ diff cirros.xml cirros1.xml
< <name>cirros</name>
< <uuid>874fe199-47ea-45d1-a25d-98d0535dddb3</uuid>
---
> <name>cirros1</name>
> <uuid>fba2f776-432d-4870-a7ec-bbf73fa1b086</uuid>
39c39
< <source file='/var/lib/libvirt/boot/cirros-0.5.0-x86_64-disk.img'/>
---
> <source file='/var/lib/libvirt/boot/cirros1.qcow2'/>
63c63
< <mac address='52:54:00:fa:5c:d3'/>
---
> <mac address='52:54:00:29:8d:06'/>
81c81
< <graphics type='vnc' port='5921' autoport='no'>
---
> <graphics type='vnc' port='-1' autoport='yes'>
#virt-clone -f指定的文件不要事先创建,如果有多个磁盘文件就用多个-f选项 如
virt-clone -o <虚拟机名称> -n <新虚拟机名称> -f /home/lib/libvirt/images/test4.qcow2 -f /mnt/images/test4-add1.qcow2
可以手动复制xml文件和磁盘镜像来复制
➜ qemu cp cirros.xml cirros3.xml
# 修改xml文件中的domain name和mac地址等信息
➜ qemu vim cirros3.xml
➜ qemu cd /var/lib/libvirt/boot
# 在define新的克隆虚拟机之前准备好所需的磁盘
➜ boot cp cirros-0.5.0-x86_64-disk.img cirros3.img
➜ boot qemu-img info cirros3.img
image: cirros3.img
file format: qcow2
virtual size: 112 MiB (117440512 bytes)
disk size: 198 MiB
cluster_size: 65536
Snapshot list:
ID TAG VM SIZE DATE VM CLOCK
1 1603292226 101 MiB 2020-10-21 22:57:06 94:39:31.435
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
➜ ~ virsh define /etc/libvirt/qemu/cirros3.xml
Domain cirros3 defined from /etc/libvirt/qemu/cirros3.xml
➜ ~ virsh list --all
Id Name State
--------------------------
2 cirros running
- cirros3 shut off
➜ ~ virsh start cirros3
Domain cirros3 started
# 此时,一个新的克隆虚拟机就创建完成
# 需要手动修改IP和hostname
实验6:误删虚拟机恢复
# 误删除虚拟机
➜ ~ virsh undefine cirros1
Domain cirros1 has been undefined
➜ ~ virsh dominfo cirros1
Id: 1
Name: cirros1
UUID: fba2f776-432d-4870-a7ec-bbf73fa1b086
OS Type: hvm
State: running
CPU(s): 2
CPU time: 41.7s
Max memory: 700416 KiB
Used memory: 262144 KiB
Persistent: no # 已经变为非持久化的,无法重新启动
Autostart: disable
Managed save: no
Security model: apparmor
Security DOI: 0
Security label: libvirt-fba2f776-432d-4870-a7ec-bbf73fa1b086 (enforcing)
➜ ~ virsh shutdown cirros1 # 关机后再也启动不了了
➜ ~ ls /etc/libvirt/qemu # cirros1的xml文件已经不存在
➜ ~ ls /var/lib/libvirt/boot # cirros1的qcow2镜像仍然存在
# 需要在关闭虚拟机之前,重新定义define一个配置文件即可恢复
virsh dumpxml centos-C > /etc/libvirt/qemu/centos-C.xml
virsh define /etc/libvirt/qemu/centos-C.xml
# 如果是在关闭着的服务器上执行的virsh undefine centos-C 删除命令,则会把对应的配置文件清空,虚拟机再也启动不了,重新定义也不行
对于