01-kvm服务部署¶
基本理论¶
KVM:内核级虚拟化技术(Kernel-based Virtual Machine)
结构简单,包含两个部分:
1)设备驱动/dev/kvm, 针对模拟PC硬件的用户空间组件
2) KVM需要CPU中虚拟化功能的支持,只可在具有虚拟化支持的CPU上运行,即具有VT功能的interCPU和具有ADM-V功能的AMD CPU
KVM虚拟化特性
嵌入到Linux正式Kernel(提高兼容性)
代码级资源调用(提高性能)
虚拟机就是一个进程(内存易于管理)
直接支持NUMA技术(提高扩展性)
------RedHat收购KVM---------
保持开源发展模式
更好的商业支持及服务保障
以下为红帽基于KVM的企业级虚拟化图解:
准备环境¶
系统环境介绍
[root@linux-node1 ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
[root@linux-node1 ~]# hostname -I
10.0.0.111
[root@linux-node1 ~]# uname -r
3.10.0-327.28.2.el7.x86_64
[root@linux-node1 ~]# hostname
linux-node1
配置阿里云的base源和epel源(CentOS7)
rm -f /etc/yum.repos.d/*.repo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.cloud.tencent.com/repo/centos7_base.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.cloud.tencent.com/repo/epel-7.repo
yum clean all
yum repolist
开启虚拟化¶
一:硬件服务器
如果你的环境是生产环境的硬盘服务器的话,那么就需要进入bios开启CPU支持虚拟化,不过一般物理机服务器默认都是支持的,所以无需担心
二:虚拟机环境
如果你的环境是vmware环境的话,那么就需要做如下操作啦,让vmware支持KVM虚拟化
1.支持虚拟化的条件
inter的cpu:vmx
AMD的cpu:svm
本文使用的是vmvare,需要开启如下两个条件即可,如果是物理机,需要在bios里面设置,默认都是开启状态。
实验必备条件,必须开启虚拟机VT-EPT技术,在vmware虚拟机选择上即可。服务器上默认是开启状态。
2.硬件要求:
CPU:双核
内存:4G
3.开启虚拟化(vmware)
3.开启虚拟化(vcenter)
4.在cpuinfo中可以查看具体的支持虚拟化的信息
[root@chuck~]``# grep -E "svm|vmx" /proc/cpuinfo #如果过滤没有代表不支持虚拟化
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq vmx ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave avx hypervisor lahf_lm arat epb pln pts dtherm tpr_shadow vnmi ept vpid tsc_adjust
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq vmx ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave a* vx hypervisor lahf_lm arat epb pln pts dtherm tpr_shadow vnmi ept vpid tsc_adjust`
快速安装¶
(1)安装KVM相关软件
yum install qemu-kvm qemu-kvm-tools virt-manager libvirt virt-install -y
#最小化安装
yum -y install qemu-kvm libvirt
kvm:linux内核的一个模块,模块不需要安装只需要加载,通过用户态程序来管理即可。 qeum:虚拟化软件,可以虚拟不同的CPU,支持异构(x86的架构可以虚拟化不是x86架构的) qeum-kvm:用户态管理kvm,网卡、声卡、PCI设备等都是需要qemu来管理。 libvirt:管理kvm本身的工具 libvirt virt-install:安装虚拟机需要使用的软件包 virt-manager:管理创建删除虚拟机的工具
(2)检查kvm内核是否被加载
[root@linux-node1~]# lsmod|grep kvm #查看kvm内核是否被加载
kvm_intel 148081 0
kvm 461126 1 kvm_intel
(3)启动相关服务
systemctl enable libvirtd.service
systemctl start libvirtd.service
提示:libvirtd虚拟化工具统一的接口
(4)检查服务是否启动
[root@linux-node1 ~]# systemctl status libvirtd.service
● libvirtd.service - Virtualization daemon
Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2016-08-11 06:45:19 EDT; 22s ago
虚拟机创建¶
创建空虚拟机¶
提示:如果你的虚拟机硬盘比较小的话,会影响后面的操作,所以需要添加一块硬盘,如果你的虚拟机硬盘足够大的话,那么此步骤可以略过!
进入系统将新添加的硬盘进行格式化
mkfs.xfs -f /dev/sdb
mkdir -p /data
mount /dev/sdb /data/
echo "/dev/sdb /data xfs defaults 0 0" >>/etc/fstab ; cat /etc/fstab |grep data
*提示:如果是虚拟机硬盘不够的情况使用此方法,如果够请略过此方法!*
(1)创建虚拟磁盘,-f指定格式,路径/opt/CentOS-7.1-x86_64.raw,大小10G
创建raw格式的虚拟磁盘(会立刻占用所有空间容量)
mkdir -p /data/kvm-data/linux-node-moban/
qemu-img create -f raw /data/kvm-data/linux-node-moban/linux-node-moban.raw 10G
创建qcow2格式的虚拟磁盘(使用多少占用多少)
mkdir -p /data/kvm-data/linux-node-moban/
qemu-img create -f qcow2 /data/kvm-data/linux-node-moban/linux-node-moban.qcow2 100G
(3)创建一台KVM虚拟机(通过iso镜像创建虚拟机)
virt-install --name linux-node-moban --virt-type kvm --vcpus 2 --ram 2048 --cdrom=/tmp/CentOS-7-x86_64-Minimal-1810.iso --disk path=/data/kvm-data/linux-node-moban/linux-node-moban.qcow2 --channel unix,path=/var/lib/libvirt/qemu/linux-node-moban.agent,mode=bind,target_type=virtio,name=org.qemu.guest_agent.0 --network network=default --graphics vnc,listen=0.0.0.0 --noautoconsole
创建一个指定mac地址与model=virtio的虚拟机
virt-install --name linux-node-test --virt-type kvm --vcpus 2 --ram 2048 --disk path=/data/kvm-data/linux-node-test.qcow2 --pxe --network network=vmnet8,model=virtio,mac=52:54:04:15:52:3d --graphics vnc,listen=0.0.0.0 --noautoconsole
创建虚拟机指定两个网卡
virt-install --name linux-node11 --virt-type kvm --ram 4096 --disk path=/data/kvm-data/linux-node11.qcow2 --pxe --network network=vmnet8,model=virtio,mac=52:54:04:15:52:11 --network network=vmnet10,model=virtio --noautoconsole
(4)首先学习下virsh-install创建虚拟机命令
- -virt-type: 指定虚拟机类型(kvm、qemu、xen)
- -name: 指定虚拟机的名称
- -ram: 指定内存大小
- -cpu: 指定cpu的核数(默认为1)
- -cdrom: 指定镜像
- -disk: 指定磁盘路径(即上文创建的虚拟磁盘)
- -network: 指定网络类
(5) 配置VNC客户端连接KVM虚拟机
制作虚拟机模版¶
打开一个VNC客户端,输入192.168.56.111:5900(第一个默认5900,第二个5901,以此类推)连接虚拟机里面建立的KVM虚拟机,安装CentOS7的过程,此处不在演示如何安装
操作系统安装:
为了统一环境,保证实验的通用性,建议将网卡名称设置为 eth*,不使用 CentOS7 默
认的网卡命名规则。所以需要在安装的时候,增加内核参数。
点击 Tab,打开 kernel 启动选项,增加 net.ifnames=0 biosdevname=0 回车即可安装
安装CentOS7,在启动前修改内核让网卡为eth0,如图1-2
关于创建虚拟机失败的解决思路:
1.关闭虚拟机,然后进行删除
2.删除虚拟磁盘文件
3.重新创建虚拟机即可解决
以下为详细的步骤:
virsh destory linux-node-moban #强制关闭虚拟机
virsh undefine linux-node-moban #删除虚拟机
#重新创建虚拟机即可
初始化模版虚拟机¶
上面的图是正在安装系统的过程!对于安装成功的系统我们需要重启启动一下KVM虚拟机
[root@linux-node1 ~]# virsh start linux-node-moban
Domain linux-node-moban started
[root@linux-node1 ~]# virsh list
Id Name State
----------------------------------------------------
6 linux-node-moban running
1.修改IP地址为DHCP自动获取IP
[root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0
BOOTPROTO=dhcp
DEVICE=eth0
ONBOOT=yes
2.重启网卡使其配置生效
[root@localhost ~]# systemctl restart network
3.安装配置常见的YUM源安装常用的软件包。
rm -f /etc/yum.repos.d/*.repo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.cloud.tencent.com/repo/centos7_base.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.cloud.tencent.com/repo/epel-7.repo
yum clean all
yum repolist
安装Linux常用软件
yum install -y net-tools vim lrzsz tree screen lsof tcpdump bash-completion bash-completion-extras wget
4.关闭 NetworkManager 和防火墙
systemctl disable firewalld && systemctl stop firewalld
systemctl disable NetworkManager && systemctl stop NetworkManager
5.关闭并确认 SELinux 处于关闭状态
sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config && grep 'SELINUX=disabled' /etc/selinux/config
setenforce 0
getenforce
6.开启虚拟机支持virsh console功能
systemctl start serial-getty@ttyS0.service
systemctl enable serial-getty@ttyS0.service
7.安装部署Kvm QGA(Qemu Guest Agent)
yum -y install qemu-guest-agent --enablerepo=C7.4*
systemctl enable qemu-guest-agent
systemctl start qemu-guest-agent
vi /etc/sysconfig/qemu-ga
# 注释如下行
#BLACKLIST_RPC=guest-file-open,guest-file-close,guest-file-read,guest-file-write,guest-file-seek,guest-file-flush,guest-exec,guest-exec-status
systemctl restart qemu-guest-agent
8.优化ssh服务
sed -i 's%#UseDNS yes%UseDNS no%g' /etc/ssh/sshd_config
systemctl restart sshd
9.关闭postfix服务
systemctl stop postfix
systemctl disable postfix
10.配置dns服务
cat >/etc/resolv.conf<<EOF
nameserver 114.114.114.114
EOF
11.配置ntp服务
yum -y install chrony ntp
vim /etc/chrony.conf
server ntp1.aliyun.com iburst
systemctl enable chronyd.service
systemctl start chronyd.service
12.开始清理服务器日志和命令记录
> /var/log/messages
> /var/log/secure
> /var/log/lastlog
> /var/log/yum.log
> /var/log/wtmp
> /var/log/boot.log
> /var/log/maillog
> /var/log/dmesg
> /var/log/maillog
> /var/log/cron
> /var/log/grubby_prune_debug
> /root/.bash_history
history -c
13.将模版虚拟机进行关机
virsh shutdown linux-node-moban
从模版创建虚拟机¶
复制模版文件到指定位置
\cp /data/kvm-data/linux-node-moban/linux-node-moban.qcow2 /data/centos7.6-moban.qcow2
开始从模版创建虚拟机
moban_file=/data/centos7.6-moban.qcow2
vmname=linux-node2
mkdir -p /data/kvm-data/${vmname}/
cp -rf $moban_file /data/kvm-data/${vmname}/${vmname}.qcow2
virt-install --name ${vmname} --virt-type kvm --vcpus 2 --ram 4096 --disk path=/data/kvm-data/${vmname}/${vmname}.qcow2 --boot hd=${vmname} --channel unix,path=/var/lib/libvirt/qemu/${vmname}.agent,mode=bind,target_type=virtio,name=org.qemu.guest_agent.0 --network network=default --graphics vnc,listen=0.0.0.0 --noautoconsole
检查创建的虚拟机的状态
[root@linux-bkce-node215 ~]# virsh list
Id Name State
----------------------------------------------------
5 linux-node2 running
虚拟机管理¶
访问虚拟机¶
我们可以通过virsh console命令来对虚拟机进行访问
[root@linux-bkce-node215 ~]# virsh console linux-node2
Connected to domain linux-node2
Escape character is ^]
CentOS Linux 7 (Core)
Kernel 3.10.0-957.el7.x86_64 on an x86_64
localhost login: root
Password:
Last failed login: Fri Mar 18 10:34:02 CST 2022 from 192.168.122.1 on ssh:notty
There was 1 failed login attempt since the last successful login.
[root@localhost ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:c0:ef:f2 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.179/24 brd 192.168.122.255 scope global dynamic eth0
valid_lft 3543sec preferred_lft 3543sec
inet6 fe80::5054:ff:fec0:eff2/64 scope link
valid_lft forever preferred_lft forever
[root@localhost ~]#
查看虚拟机¶
查看正在运行的KVM虚拟机
virsh list
查看所有KVM虚拟机(包括已关机的虚拟机)
virsh list --all
关闭虚拟机¶
重启KVM虚拟机
virsh reboot linux-node2
正常关闭KVM虚拟机
virsh shutdown linux-node2
强制关闭KVM虚拟机(类似于直接断电)
virsh destroy linux-node2
开启虚拟机¶
启动KVM虚拟机
virsh start linux-node2
挂起虚拟机¶
针对进行不使用的虚拟机可以进行挂起操作
[root@linux-bkce-node215 ~]# virsh suspend linux-node2
Domain linux-node2 suspended
[root@linux-bkce-node215 ~]# virsh list
Id Name State
----------------------------------------------------
5 linux-node2 paused
当然针对挂起的虚拟机我们也可以进行恢复
[root@linux-bkce-node215 ~]# virsh resume linux-node2
Domain linux-node2 resumed
[root@linux-bkce-node215 ~]# virsh list
Id Name State
----------------------------------------------------
5 linux-node2 running
虚拟机重设密码¶
设置虚拟机的密码,需要提前安装Qemu Guest Agent
virsh qemu-agent-command linux-node2 --cmd '{"execute":"guest-info"}'
virsh set-user-password linux-node2 --user root --password 123
virsh console linux-node2
查看虚拟机的IP¶
首先编写脚本
#!/bin/bash
get_data(){
local qga_pid=$2
local xuji_id=$1
data=`echo "virsh qemu-agent-command $xuji_id --pretty '{\"execute\":\"guest-exec-status\", \"arguments\":{\"pid\": $qga_pid}}'"|bash|egrep 'exitcode|out-data|err-data|exited'|sed 's#,##g'`
#echo $data|xargs -n 2
exited=`echo $data|xargs -n 2|grep exited|awk '{print $2}'`
while true
do
if [ "$exited" == "false" ]
then
#data=`echo "virsh qemu-agent-command $xuji_id --pretty '{\"execute\":\"guest-exec-status\", \"arguments\":{\"pid\": $qga_pid}}'"|bash|egrep 'exitcode|out-data|err-data|exited'|awk -F ':|,' '{print $2}'`
data=`echo "virsh qemu-agent-command $xuji_id --pretty '{\"execute\":\"guest-exec-status\", \"arguments\":{\"pid\": $qga_pid}}'"|bash|egrep 'exitcode|out-data|err-data|exited'|sed 's#,##g'`
exited=`echo $data|xargs -n 2|grep exited|awk '{print $2}'`
else
break
fi
done
exitcode=`echo $data|xargs -n 2|grep exitcode|awk '{print $2}'`
out_data=`echo $data|xargs -n 2|grep '\-data'|awk '{print $2}'`
#echo "$out_data"
if [ "$exitcode" != "0" ]
then
[ -z $out_data ] || echo "$out_data"|base64 -d
return 3
fi
[ -z $out_data ] || echo "$out_data"|base64 -d
}
id=$1
command=$2
cmd_support=`virsh qemu-agent-command $id --pretty '{"execute":"guest-info"}'|egrep -B 1 'guest-exec|guest-exec-status'|grep true|wc -l`
[ $cmd_support -ne 2 ] && echo "This virtual machine does not support CMD" >&2 && exit 1
if [ $# -eq 2 ]
then
qga_pid=`echo "virsh qemu-agent-command $id --pretty '{\"execute\":\"guest-exec\", \"arguments\":{\"path\":\"$command\", \"capture-output\":true}}'"|bash|grep pid|awk '{print $2}'`
get_data $id $qga_pid
else
shift 2
in_arg=$*
#echo $in_arg
#arg=`echo \"${in_arg// /\",\"}\"`
qga_pid=`echo "virsh qemu-agent-command $id --pretty '{\"execute\":\"guest-exec\", \"arguments\":{\"path\":\"$command\", \"arg\":[$(echo \"${in_arg// /\",\"}\")], \"capture-output\":true}}'"|bash|grep pid|awk '{print $2}'`
get_data $id $qga_pid
fi
查看虚拟机的IP地址
# chmod +x /root/qga
# ./qga linux-node2 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:c0:ef:f2 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.179/24 brd 192.168.122.255 scope global dynamic eth0
valid_lft 2272sec preferred_lft 2272sec
inet6 fe80::5054:ff:fec0:eff2/64 scope link
valid_lft forever preferred_lft forever
虚拟机注入脚本¶
创建一个测试的小脚本
[root@linux-bkce-node215 ~]# cat >/root/test.sh<<EOF
ip addr
hostname
lsblk
EOF
获取脚本的base加密值
[root@linux-bkce-node215 ~]# cat /root/test.sh |base64 -w 0
aXAgYWRkcgpob3N0bmFtZQpsc2Jsawo=
开始注入脚本
[root@linux-bkce-node215 ~]# virsh qemu-agent-command linux-node2 '{"execute":"guest-file-open","arguments":{"path":"/root/test.sh","mode":"w+"}}'
{"return":1000}
[root@linux-bkce-node215 ~]# virsh qemu-agent-command linux-node2 '{"execute":"guest-file-write","arguments":{"handle":1000,"buf-b64":"aXAgYWRkcgpob3N0bmFtZQpsc2Jsawo="}}'
{"return":{"count":23,"eof":false}}
[root@linux-bkce-node215 ~]# virsh qemu-agent-command linux-node2 '{"execute":"guest-file-close","arguments":{"handle":1000}}'
{"return":{}}
使用qga脚本执行注入的脚本
[root@linux-bkce-node215 ~]# sh qga.sh linux-node2 cat /root/test.sh
[root@linux-bkce-node215 ~]# sh qga linux-node2 sh /root/test.sh
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:c0:ef:f2 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.179/24 brd 192.168.122.255 scope global dynamic eth0
valid_lft 3357sec preferred_lft 3357sec
inet6 fe80::5054:ff:fec0:eff2/64 scope link
valid_lft forever preferred_lft forever
localhost.localdomain
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
└─sda1 8:1 0 100G 0 part /
配置虚拟机的IP¶
编写一个IP地址的小脚本
[root@linux-bkce-node215 ~]# vi /root/ip_set.sh
cat >/etc/sysconfig/network-scripts/ifcfg-eth0<<EOF
NAME=eth0
GATEWAY=192.168.122.1
DNS1=114.114.114.114
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
NETMASK=255.255.255.0
IPADDR=192.168.122.2
EOF
systemctl restart network
获取脚本的base加密值
[root@linux-bkce-node215 ~]# cat /root/ip_set.sh |base64 -w 0
Y2F0ID4vZXRjL3N5c2NvbmZpZy9uZXR3b3JrLXNjcmlwdHMvaWZjZmctZXRoMDw8RU9GCk5BTUU9ZXRoMApHQVRFV0FZPTE5Mi4xNjguMTIyLjEKRE5TMT0xMTQuMTE0LjExNC4xMTQKREVWSUNFPWV0aDAKT05CT09UPXllcwpCT09UUFJPVE89c3RhdGljCk5FVE1BU0s9MjU1LjI1NS4yNTUuMApJUEFERFI9MTkyLjE2OC4xMjIuMgpFT0YKc3lzdGVtY3RsIHJlc3RhcnQgbmV0d29yawo=
开始注入脚本
shell_file_dir="/root/ip_set.sh"
shell_buf_b64=$(cat ${shell_file_dir} |base64 -w 0)
[root@linux-bkce-node215 ~]# virsh qemu-agent-command linux-node2 '{"execute":"guest-file-open","arguments":{"path":"'${shell_file_dir}'","mode":"w+"}}'
{"return":1000}
[root@linux-bkce-node215 ~]# virsh qemu-agent-command linux-node2 '{"execute":"guest-file-write","arguments":{"handle":1001,"buf-b64":"'${shell_buf_b64}'"}}'
{"return":{"count":217,"eof":false}}
[root@linux-bkce-node215 ~]# virsh qemu-agent-command linux-node2 '{"execute":"guest-file-close","arguments":{"handle":1001}}'
{"return":{}}
使用qga脚本执行注入的脚本
[root@linux-bkce-node215 ~]# sh qga linux-node2 sh /root/ip_set.sh
[root@linux-bkce-node215 ~]# sh qga linux-node2 ip addr
删除虚拟机¶
先查询虚拟机虚拟磁盘的位置
[root@linux-bkce-node215 ~]# virsh dumpxml linux-node2|grep qcow2
<driver name='qemu' type='qcow2'/>
<source file='/data/kvm-data/linux-node2/linux-node2.qcow2'/>
删除虚拟机的步骤
virsh destroy linux-node-test
virsh undefine linux-node-test
找到虚拟机的虚拟磁盘位置进行删除
rm -f /data/kvm-data/linux-node2/linux-node2.qcow2
常用管理命令¶
提示:虚拟机xml的存放位置
[root@linux-node1 ~]# ll /etc/libvirt/qemu/
以下为KVM常用的管理命令
virsh --help #查看帮助
virt-install #建立kvm虚拟机
virsh list #查看正在运行的KVM虚拟机
virsh list --all #查看所有KVM虚拟机
virsh start name #启动KVM虚拟机
virsh reboot name #重启KVM虚拟机
virsh shutdown name #正常关闭KVM虚拟机
virsh destroy name #强制关闭KVM虚拟机(类似于直接断电)
virsh suspend name #挂起KVM虚拟机
virsh resume name #恢复挂起的KVM虚拟机
virsh dumpxml name #查看KVM虚拟机配置文件
virsh edit name #编辑KVM虚拟机的xml配置文件
virsh undefine name #彻底删除KVM虚拟机,不可逆,如果想找回来,需要备份/etc/libvirt/qemu的xml文件)
virsh domid name #显示客户端ID
virsh domuuid name #显示客户端UUID
virsh dominfo #显示客户端的信息
virsh domstate #显示客户端的状态
虚拟机扩容¶
CPU扩容¶
CPU关机扩容¶
KVM是默认支持热添加CPU的核数的,但是需要要求物理机的系统与虚拟机的系统版本是一致的,由于无法限制使用虚拟机的用户使用的版本是一致的,所以有些公有云一般都会将此功能进行进行。
修改CPU配置文件的方式
virsh edit linux-node2
配置虚拟机的cpu,两种方式(启动的时候指定核数,更改xml)
(1)为了实现CPU的热添加,就需要更改Cpu的最大值,当然热添加值不能超过最大值.
[root@linux-node1 opt]# virsh edit linux-node2
<vcpu placement='auto' current="4">32</vcpu>
<vcpu placement='static'>4</vcpu>
#此参数可以设置CPU扩容的最大值,当前为1,此项修改表示最大CPU可以扩容为4核,auto表示自动
(2)关闭KVM虚拟机,并启动KVM虚拟机
[root@linux-node1 opt]# virsh shutdown linux-node2 #关闭KVM虚拟机
Domain CentOS-7-x86_64 is being shutdown
[root@linux-node1 opt]# virsh start linux-node2 #启动KVM虚拟机
Domain CentOS-7-x86_64 started
检查cpu是否扩容成功
cat /proc/cpuinfo | grep "processor"
CPU开机扩容¶
(3)热修改为2个cpu(但是无法热减少,可以热添加),
CPU高版本自动激活,低版本需要手动激活添加的CPU
[root@linux-node1 opt]# virsh setvcpus linux-node2 6 --live
提示:cpu的热添加(cpu只支持热添加,不支持热减少)
配置文件也需要修改
[root@linux-node1 opt]# virsh edit linux-node2
<vcpu placement='auto' current="6">16</vcpu>
(4) 通过vnc登录KVM虚拟机查看是否扩容成功
[root@KVM]# grep processor /proc/cpuinfo |wc -l
[root@localhost ~]# cat /proc/interrupts #查看CPU核数
CPU0 CPU1
0: 104 IO-APIC-edge timer
1: 504 IO-APIC-edge i8042
提示:CPU热添加,总数不能超过设置的最大CPU核数
(5) 在创建虚拟机时指定cpu
[root@linux-node1 ~]# virt-install --help|grep vcpus
--vcpus VCPUS 为虚拟机配置的 vcpus 数。例如:
--vcpus 5
--vcpus 5,maxcpus=10,cpuset=1-4,6,8
--vcpus sockets=2,cores=4,threads=2,
(6)检查刚刚添加的CPU是否处于工作状态,0表示不工作,1表示工作
[root@localhost ~]# cat /sys/devices/system/cpu/cpu1/online
1
提示:openstack不支持CPU热添加,单独使用KVM的话,还是不错的。
内存扩容¶
内存关机扩容¶
内存的设置拥有一个气球(balloon)机制,可以增大减少,但是也要设置一个最大值,默认并没有最大值,也可以在安装时指定。
(1) 为了实现CPU的热添加,就需要更改Cpu的最大值,当然热添加值不能超过最大值,现在我们需要设置内存的最大值
[root@linux-node1 opt]# virsh edit linux-node2
<memory unit='KiB'>4194304</memory> #修改最大支持内存扩容为4G
(2)重启虚拟机使其配置生效
[root@linux-node1 opt]# virsh shutdown linux-node2 #关闭KVM虚拟机
Domain CentOS-7-x86_64 is being shutdown
[root@linux-node1 opt]# virsh start linux-node2 #启动KVM虚拟机
Domain CentOS-7-x86_64 started
(3)查看当前KVM虚拟机内存的大小
virsh qemu-monitor-command linux-node2 --hmp --cmd info balloon
balloon: actual=1024 #当前虚拟机内存的信息
内存开机扩容¶
(4)将内存热添加到2G
virsh qemu-monitor-command linux-node2 --hmp --cmd balloon 6000
(5)再次查看内存是否热添加成功
virsh qemu-monitor-command linux-node2 --hmp --cmd info balloon
balloon: actual=2001
(6)进入虚拟机查看内容容量
[root@localhost ~]# free -h
total used free shared buff/cache available
Mem: 1.7G 81M 1.5G 8.3M 112M 1.4G
Swap: 1.0G 0B 1.0G
网络管理¶
配置桥接模式¶
KVM默认情况是NAT进行上网的,但是在生产情况,使用更多的是桥接模式,更改虚拟机为网桥模式,原理图如下,网桥的基本原理就是创建一个桥接接口br0,在物理网卡和虚拟网络接口之间传递数据
修改eth0(这里CentOS7的eth0在装机时就指定了,那如果没指定怎么办?
参考博文:http://www.xuliangwei.com/xubusi/102.html)
(1)在物理机上添加一个网卡
[root@linux-node1~]# brctl addbr br0
(2)查看虚拟机网卡信息
[root@linux-node1 ~]# brctl show #查看网卡网段信息
bridge name bridge id STP enabled interfaces
br0 8000.000000000000 no
virbr0 8000.5254009f0311 yes virbr0-nic
将br0网卡绑定桥接到eth0上
提示:执行如下命令可能会导致物理机网络断开,我们需要将如下命令设置为一个脚本,执行
brctl addbr br0 #添加桥接网卡
brctl addif br0 eth0 #将br0桥接到eth0上
ip addr del dev eth0 192.168.56.11/24 #删除eth0的IP地址
ifconfig br0 192.168.56.11/24 up #启动br0网卡
route add default gw 192.168.56.2 #添加一条默认的网关,能够上网
(3)把eth0加入网桥,使用桥接模式,给br设置ip,添加路由网关,关闭防火墙
yum -y install net-tools
brctl addif br0 eth0 && ip addr del dev eth0 192.168.1.14/24 && ifconfig br0 192.168.1.14/24 up && route add default gw 192.168.1.254
(4)编辑虚拟机的网络配置使用br0网桥模式
[root@linux-bkce-node215 ~]# virsh edit linux-node2
<interface type="bridge"> <!--虚拟机网络连接方式-->
<source network='default'/> #删除此行默认的设置,修改为如下一条的信息
<source bridge="br0"/> <!-- 当前主机网桥的名称-->
<mac address="00:16:e4:9a:b3:6a" />
<!--为虚拟机分配mac地址,务必唯一,如果是dhcp获得同样ip,引起冲突-->
</interface>
(5) 重启虚拟机,网桥模式生效,
[root@linux-node1 ~]# virsh shutdown linux-node2
[root@linux-node1 ~]# virsh start linux-node2
[root@linux-node1 ~]# virsh list
(6)此时使用ssh便可以链接到所创建的虚拟机了,在vmvare机器上使用ifconfig查看详情
[root@linux-bkce-node215 ~]# virsh console linux-node2
[root@localhost network-scripts]# pwd
/etc/sysconfig/network-scripts
[root@localhost network-scripts]# vi ifcfg-eth0
NAME=eth0
GATEWAY=192.168.1.254
DNS1=114.114.114.114
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
NETMASK=255.255.255.0
IPADDR=192.168.1.232
[root@linux-bkce-node215 ~]# ssh 192.168.1.232
root@192.168.1.232's password:
Last failed login: Mon Mar 21 16:22:09 CST 2022 from 192.168.1.215 on ssh:notty
There was 1 failed login attempt since the last successful login.
Last login: Mon Mar 21 16:19:22 2022
[root@localhost ~]# logout
Connection to 192.168.1.232 closed.
提示:需要先使用VNC连接,查看dhcp分配的IP地址,然后在使用ssh连接上
(7)此时我们在查看物理机的网卡信息如下
[root@linux-bkce-node215 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
link/ether 00:50:56:83:dd:19 brd ff:ff:ff:ff:ff:ff
inet6 fe80::250:56ff:fe83:dd19/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:74:58:1b brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:74:58:1b brd ff:ff:ff:ff:ff:ff
11: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 00:50:56:83:dd:19 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.215/24 brd 192.168.1.255 scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::250:56ff:fe83:dd19/64 scope link
valid_lft forever preferred_lft forever
12: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN group default qlen 1000
link/ether fe:54:00:c0:ef:f2 brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fec0:eff2/64 scope link
valid_lft forever preferred_lft forever
硬盘管理¶
添加数据盘¶
添加虚拟磁盘
qemu-img create -f qcow2 /data/kvm-data/linux-node2/linux-node2-sdb.qcow2 500G
qemu-img create -f qcow2 /data/kvm-data/linux-node2/linux-node2-sdc.qcow2 500G
配置虚拟机配置文件
[root@linux-bkce-node215 ~]# virsh edit linux-node2
# 添加如下标签
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/data/kvm-data/linux-node2/linux-node2-sdb.qcow2'/>
<target dev='hdb' bus='sata'/>
<address type='drive' controller='1' bus='0' target='0' unit='1'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2'/>
<source file='/data/kvm-data/linux-node2/linux-node2-sdc.qcow2'/>
<target dev='hdc' bus='sata'/>
<address type='drive' controller='2' bus='0' target='0' unit='2'/>
</disk>
重启虚拟机
[root@linux-bkce-node215 ~]# virsh shutdown linux-node2
Domain linux-node2 is being shutdown
[root@linux-bkce-node215 ~]# virsh start linux-node2
Domain linux-node2 started
进入虚拟机查看磁盘
[root@linux-bkce-node215 ~]# virsh console linux-node2
[root@linux-bkce-node215 linux-node2]# virsh console linux-node2
Connected to domain linux-node2
Escape character is ^]
CentOS Linux 7 (Core)
Kernel 3.10.0-957.el7.x86_64 on an x86_64
localhost login: root
Password:
Last login: Mon Mar 21 16:45:36 on ttyS0
[root@localhost ~]# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 100G 0 disk
└─sda1 8:1 0 100G 0 part /
sdb 8:16 0 500G 0 disk
sdc 8:32 0 500G 0 disk
[root@localhost ~]# mkfs.xfs -f /dev/sdb
[root@localhost ~]# mkfs.xfs -f /dev/sdc
参考博文:QEMU使用的镜像文件:qcow2 与 raw
http://www.ibm.com/developerworks/cn/linux/1409_qiaoly_qemuimgages/index.html
更改虚拟机中存储,硬盘设置(不建议生产环境使用硬盘的扩大收缩模式,很容易产生故障)
[root@linux-node1 ~]# qemu-img --help |grep -i "formats:"
Supported formats: vvfat vpc vmdk vhdx vdi ssh sheepdog rbd raw host_cdrom host_floppy host_device file qed qcow2 qcow parallels nbd iscsi gluster dmg tftp ftps ftp https http cloop bochs blkverify blkdebug
硬盘格式都可以通过qeum-img管理,具体qemu-img --help
全镜像格式(代表raw):设置多大就是多大,写入速度快,方便的转换为其他格式,性能最优,但是占用空间大。
稀疏格式(代表qcow2):支持压缩,快照,镜像,更小的存储空间(即用多少占多少)
[root@linux-node1 opt]# qemu-img info CentOS-7.1-x86_64.raw #查看虚拟磁盘的格式
image: CentOS-7.1-x86_64.raw
file format: raw
virtual size: 10G (10737418240 bytes)
disk size: 1.1G
从结果看出,kvm支持很多种硬盘格式
硬盘格式总体上分为两种:1为全镜像格式,2为稀疏格式
全镜像格式(典型代表raw格式),其特点:设置多大就是多大,写入速度快,方便的转换为其他格式,性能最优,但是占用空间大
稀疏模式(典型代表qcow2格式),其特点:支持压缩,快照,镜像,更小的存储空间(即用多少占多少)
硬盘格式都可以通过qemu-img管理,详情qemu-img –help
*Raw 格式与 qcow2 转化*
QEMU 软件包里面提供的 qemu-img 工具可用于 image 镜像一些常用操作。
将 raw 格式转化为 qcow2 格式的文件命令如下:
[root@linux-node1 opt]# qemu-img convert -f raw -O qcow2 CentOS-7.1-x86_64.raw CentOS-7.1-x86_64.raw.qcow2
现在我们对比两个格式的空间占用情况
[root@linux-node1 opt]# ll -h CentOS-7.1-x86_64.raw*
-rw-r--r-- 1 qemu qemu 10G Sep 3 12:09 CentOS-7.1-x86_64.raw
-rw-r--r-- 1 root root 1.1G Sep 3 12:30 CentOS-7.1-x86_64.raw.qcow2
[root@linux-node1 opt]# qemu-img info CentOS-7.1-x86_64.raw.qcow2
image: CentOS-7.1-x86_64.raw.qcow2
file format: qcow2
virtual size: 10G (10737418240 bytes)
disk size: 2.0G
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
小结
本文着重介绍了 QEMU 虚拟机使用的镜像文件 qcow2 的格式以及特性,并与 raw 格式镜像做了对比。qcow2 格式的文件虽然在性能上比rRaw 格式的有一些损失(主要体现在对于文件增量上,qcow2 格式的文件为了分配 cluster 多花费了一些时间),但是 qcow2 格式的镜像比 Raw 格式文件更小,只有在虚拟机实际占用了磁盘空间时,其文件才会增长,能方便的减少迁移花费的流量,更适用于云计算系统,同时,它还具有加密,压缩,以及快照等 raw 格式不具有的功能。
*提示:虚拟机的虚拟磁盘的IO读写效率很慢,最好使用物理机的磁盘*
kvm对接ceph¶
参考地址:https://note.youdao.com/ynoteshare1/index.html?id=4a57a77b9e241510edb8331916b0d7ba&type=note
安装libvirt¶
yum -y install qemu-kvm libvirt virt-install bridge-utils
vi /etc/libvirt/qemu.conf
user = "root"
group = "root"
systemctl start libvirtd
systemctl enable libvirtd
cat >/etc/yum.repos.d/ceph.repo<<EOF
[ceph]
name=ceph
baseurl=https://mirrors.aliyun.com/ceph/rpm-luminous/el7/x86_64/
enabled=1
gpgcheck=0
EOF
yum repolist
yum install ceph -y
配置ceph后端存储¶
把ceph的配置拷贝到/etc/ceph/目录下
/etc/ceph/ceph.client.kvm.keyring
/etc/ceph/ceph.conf
可以在ceph中加上下面的配置
[client]
rbd cache = false
rbd cache writethrough until flush = false
cache size = 67108864
rbd cache max dirty = 0
rbd cache max dirty age = 0
admin socket = /var/run/ceph/guests/$cluster-$type.$id.$pid.$cctid.asok
log file = /var/log/qemu/qemu-guest-$pid.log
rbd concurrent management ops = 20
创建相关目录
mkdir /var/run/ceph/guests/
mkdir /var/log/qemu/
cat /etc/ceph/ceph.client.kvm.keyring
[client.kvm]
key = AQDXu8pgRmItNxAAalc2ktr1KouuRxEgCBfgFQ==
cat /etc/ceph/secret.xml
<secret ephemeral='no' private='no'>
<uuid>{{ secret_uuid }}</uuid>
<usage type='ceph'>
<name>client.kvm secret</name>
</usage>
</secret>
# secret_uuid可以通过uuidgen命令获取
# client.kvm中的kvm是pool的名字,也就是ceph.client.kvm.keyring的中的[client.kvm]
[root@linux-bkce-node215 ~]# uuidgen
be2cfb27-b472-4f99-9a73-3d1dd2cc5f9b
# 将上面的xml配置导入libvirt
virsh secret-define --file /etc/ceph/secret.xml
# 给设置密钥
virsh secret-set-value --secret {{ secret_uuid }} --base64 AQDXu8pgRmItNxAAalc2ktr1KouuRxEgCBfgFQ==
# 此处的secret_uuid要和/etc/ceph/secret.xml中的uuid要一致
# 上面的密钥是ceph.client.cinder.keyring中的key。
上传镜像或者创建空磁盘¶
创建raw格式的2G空磁盘
qemu-img create -f raw rbd:kvm/new-libvirt-image:id=kvm:conf=/etc/ceph/ceph.conf 2G
查看kvm池中的文件
rbd --id kvm --conf /etc/ceph/ceph.conf --pool kvm ls
上传本地的镜像到ceph的kvm池中,并把本地的qcow2的镜像上传成raw格式
qemu-img convert -f qcow2 -O raw centos76_v1.qcow2 rbd:kvm/centos76_v1:id=kvm:conf=/etc/ceph/ceph.conf
copy镜像
rbd --id kvm --conf /etc/ceph/ceph.conf -p kvm cp centos76_v1 kvm/centos76_v1_01
virsh pool-refresh kvm
Add Ceph RBD Storage Pool to KVM/QEMU/Libvirt¶
cat >/tmp/libvirt-rbd-pool.xml <<EOF
<pool type="rbd">
<name>kvm</name>
<source>
<name>kvm</name>
<host name='10.114.198.147' port='6789' />
<host name='10.114.198.148' port='6789' />
<host name='10.114.198.149' port='6789' />
<auth username='kvm' type='ceph'>
<secret uuid='609c583e-be28-45b1-aa4b-9572d4408720'/>
</auth>
</source>
</pool>
EOF
# 导入配置
virsh pool-define /tmp/libvirt-rbd-pool.xml
# 存储池开机自启
virsh pool-autostart kvm
# 启动存储池
virsh pool-start kvm
# 查看存储池
virsh pool-list --all
创建虚机¶
virt-install -n test -r 2048 --vcpus 6 \
--description "test" --noautoconsole \
--network bridge=virbr0,model=virtio \
--disk vol=kvm/centos76_v1,format=raw,device=disk,bus=virtio \
--boot hd=kvm/centos76_v1 \
--graphics vnc,listen=0.0.0.0 \
--channel unix,path=/var/lib/libvirt/qemu/test.agent,mode=bind,target_type=virtio,name=org.qemu.guest_agent.0
kvm生产环境搭建¶
安装启动kvm
yum install qemu-kvm qemu-kvm-tools virt-manager libvirt virt-install -y
systemctl enable libvirtd.service
systemctl start libvirtd.service
创建桥接网络
brctl addbr br0 && brctl addif br0 enp130s0f0 && ip addr del dev enp130s0f0 10.0.192.17/24 && ifconfig br0 10.0.192.17/24 up && route add default gw 10.0.192.1
创建网桥
brctl addbr br1 && ifconfig br1 up
brctl addbr br2 && ifconfig br2 up
brctl addbr br3 && ifconfig br3 up
brctl addbr br4 && ifconfig br4 up
初始化硬盘并挂载
mkfs.xfs -f /dev/sdb
mkdir /data/kvm-data -p
mount /dev/sdb /data/kvm-data/
创建虚拟机
for n in $HOSTNAME
do
mkdir -p /data/kvm-data/linux-node${n} -p &&\
qemu-img create -f qcow2 /data/kvm-data/linux-node$n/linux-node$n.qcow2 100G &>/dev/null &&\
for m in 01 02 03
do
qemu-img create -f qcow2 /data/kvm-data/linux-node$n/linux-node$n-$m.qcow2 50G &>/dev/null
done
chown -R qemu.qemu /data/kvm-data/linux-node${n} &&\
virt-install --name linux-node$n --virt-type kvm --ram 16384 --vcpus 8 --disk path=/data/kvm-data/linux-node${n}/linux-node${n}.qcow2 --pxe --network bridge=br0,mac=52:54:04:15:52:$n --network bridge=br1 --network bridge=br2 --network bridge=br3 --network bridge=br4 --graphics vnc,listen=0.0.0.0 --noautoconsole &>/dev/null
if [ $? -eq 0 ];then
action "linux-node$n null virtual machine create is" /bin/true
fi
if [ $? -ne 0 ];then
action "linux-node$n null virtual machine create is" /bin/false
fi
done
qga¶
Kvm QGA(Qemu Guest Agent)部署
https://blog.mulinux.com/kvm-qemu-guest-agent/
通过iso镜像创建虚拟机
virt-install --name linux-node-moban --virt-type kvm --ram 4096 --cdrom=/tmp/CentOS-7-x86_64-Minimal-1810.iso --disk path=/data/kvm-data/linux-node-moban/linux-node-moban.qcow2 --channel unix,path=/var/lib/libvirt/qemu/linux-node-moban.agent,mode=bind,target_type=virtio,name=org.qemu.guest_agent.0 --network network=default --graphics vnc,listen=0.0.0.0 --noautoconsole
通过模版创建虚拟机
moban_file=/data/centos7.6-moban.qcow2
vmname=linux-node1
mkdir -p /data/kvm-data/${vmname}/
cp -rf $moban_file /data/kvm-data/${vmname}/${vmname}.qcow2
virt-install --name ${vmname} --virt-type kvm --ram 4096 --disk path=/data/kvm-data/${vmname}/${vmname}.qcow2 --boot hd=${vmname} --channel unix,path=/var/lib/libvirt/qemu/${vmname}.agent,mode=bind,target_type=virtio,name=org.qemu.guest_agent.0 --network network=default --graphics vnc,listen=0.0.0.0 --noautoconsole
yum -y install qemu-guest-agent
<channel type='unix'>
<source mode='bind' path='/tmp/channel.sock'/>
<target type='virtio' name='org.qemu.guest_agent.0' state='connected'/>
<alias name='channel0'/>
<address type='virtio-serial' controller='0' bus='0' port='4'/>
</channel>
virsh qemu-agent-command linux-node-moban --cmd '{"execute":"guest-info"}'
virsh set-user-password linux-node-moban --user root --password 123456
qemu-guest-agent 重置密码 及 写入文件
https://www.cnblogs.com/czp2016/p/15661996.html
base64 /root/test.sh
virsh qemu-agent-command linux-node-moban '{"execute":"guest-file-open","arguments":{"path":"/root/test.sh","mode":"w+"}}'
virsh qemu-agent-command linux-node-moban '{"execute":"guest-file-write","arguments":{"handle":1001,"buf-b64":"dGVzdOa1i+ivlTEyMzQ1"}}'
virsh qemu-agent-command linux-node-moban '{"execute":"guest-file-close","arguments":{"handle":1001}}'
vi /etc/sysconfig/qemu-ga
#BLACKLIST_RPC=guest-file-open,guest-file-close,guest-file-read,guest-file-write,guest-file-seek,guest-file-flush,guest-exec,guest-exec-status
systemctl restart qemu-guest-agent
qemu-ga 执行命令无法执行: The command guest-exec has been disabled for this instance
https://blog.csdn.net/weixin_43863487/article/details/104939023
使用virsh 对虚拟机操作 qemu-agent
https://www.cnblogs.com/bnsdmmL/p/14124784.html