本文主要介绍在一台Linux服务器上使用kvm工具创建Linux虚拟机。
背景
近年来基本上都使用docker来运行程序,虽说服务器可以同时运行多个端口不同的web服务程序,但docker更容易管理和迁移——特别是一些C++程序。不过有的程序需要更改系统时间进行测试,如果在docker环境修改时间,则宿主机也会受到影响。笔者也尝试过使用faketime库,但达不到我所预想的效果。有必要使用不同的宿主机系统运行程序。但申请资源比较麻烦,而且使用场景较小,不需要一直运行。因此,考虑在服务器上创建虚拟机linux系统。
本文安装的linux系统主要是主流的国产Linux系统。为与将来的生产环境保持一致,采用服务器版本,而不是桌面版本。
实践
设计
拟创建如下配置的linux系统:
名称:kylin-v10-my
CPU:8核心
内存:16GB
硬盘:500GB (根分区/:300GB /home:100GB、swap分区:64GB)
OS:国产操作系统,如kylin或uos,服务器版本
图形界面GUI:默认(如OS自带有GUI,则选之,不带则不选)
账号:使用root,不创建普通用户
kvm相关软件安装
yum remove qemu-kvm qemu-system-x86 -y # 卸载旧版本
yum install libvirt* qemu qemu-kvm libvirt virt-manager -y # 重新安装KVM
systemctl start libvirtd
systemctl enable libvirtd
systemctl status libvirtd # 检查状态
# 检查 KVM 模块
lsmod | grep kvm
virsh version # 检查 libvirt 版本
yum install qemu-kvm spice-vdagent spice-server
启动libvirtd后输出状态结果
# systemctl status libvirtd
● libvirtd.service - Virtualization daemon
Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2025-07-03 13:22:07 CST; 5h 13min ago
Docs: man:libvirtd(8)
https://libvirt.org
Main PID: 1884791 (libvirtd)
Tasks: 23 (limit: 32768)
Memory: 88.3M
CGroup: /system.slice/libvirtd.service
├─1884791 /usr/sbin/libvirtd --timeout 120
├─4023960 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper
└─4023961 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper
# lsmod | grep kvm
kvm_intel 245760 21
kvm 786432 1 kvm_intel
irqbypass 16384 1 kvm
# virsh version
根据库编译:libvirt 6.2.0
使用库:libvirt 6.2.0
使用的 API: QEMU 6.2.0
运行管理程序: QEMU 4.1.0
虚拟机操作实践
环境准备
创建网桥:
virsh iface-bridge em1 br0
创建虚拟机
创建虚拟机:
virt-install \
--name=kylin-v10-my \
--vcpus=4 \
--memory=16384 \
--disk /home/latelee/myos/images/kylin-v10-my.qcow2,size=500,format=qcow2 \
--cdrom=/home/latelee/myos/images/Kylin-Server-V10-SP3-2403-Release-20240426-x86_64.iso \
--network bridge=br0 \
--graphics spice,listen=0.0.0.0,defaultMode='insecure' \
--video virtio \
--os-type=linux \
--os-variant=generic \
--noautoconsole
说明:
- –name:虚拟机名称
- –vcpus:CPU核心数量,此处为4
- –memory:内存,单位为KB,此处为16GB
- –disk:指定存储的位置、虚拟机文件名、大小(单位为GB)
- –cdrom:指定安装光盘镜像文件
- –network:指定网络方式,此处为桥接,直接分配真实IP地址
- –graphics:指定用spice协议进行远程连接
远程连接
先查看开放哪个端口
# virsh domdisplay kylin-v10-my
spice://localhost:5901
在windows系统安装spice客户端VirtViewer(Remote viewer),输入地址进行连接,注意,这里的IP地址,是指服务器的IP。即远程连接工具通过服务器IP和端口,连接到虚拟机。示例如下:
spice://172.18.18.20:5901
连接成功后,就进入到系统安装界面,如下图所示。
按系统安装的一般步骤进行操作即可。
其它命令
删除虚拟机
virsh destroy kylin-v10-my
virsh undefine kylin-v10-my
rm -f /var/lib/libvirt/images/kylin-v10-my.qcow2
virsh list --all # 虚机列表
virsh domdisplay kylin-v10-my # 端口查看
virsh start kylin-v10-my # 开机
virsh reboot kylin-v10-my # 重启
virsh autostart kylin-v10-my # 重启宿主机时自动启动
克隆虚拟机
推荐命令:
virt-clone --original kylin-v10-my --name kylin-v10-my-2 --file /var/lib/libvirt/images/kylin-v10-my-2.qcow2
在会自动生成对应配置
# cat /etc/libvirt/qemu/kylin-v10-my-2.xml
该配置文件的uuid、mac地址,与原虚拟机不同。使用virsh list --all
可即时查看。
虚拟机快照
创建内部快照(存储在虚拟机磁盘内)
virsh snapshot-create-as --domain myvm --name snap1 --description "首次备份"
创建外部快照(独立磁盘文件,适合生产环境)
virsh snapshot-create-as --domain myvm --name snap2 --disk-only --diskspec vda,snapshot=external,file=/var/lib/libvirt/images/myvm-snap2.qcow2
# 创建一致性外部快照的标准流程
virsh snapshot-create-as --domain prod-vm \
--name "backup-$(date +%Y%m%d)" \
--disk-only \
--atomic \
--diskspec vda,snapshot=external,file=/backup/prod-vm-$(date +%Y%m%d).qcow2
virsh snapshot-list <虚拟机名称> # 列出所有快照
virsh snapshot-info <虚拟机名称> <快照名称> # 查看快照详细信息
virsh snapshot-current <虚拟机名称> # 查看当前快照
virsh snapshot-revert <虚拟机名称> <快照名称> # 恢复到指定快照
virsh snapshot-revert <虚拟机名称> <快照名称> --running # 恢复到指定快照并重启虚拟机
virsh snapshot-delete <虚拟机名称> <快照名称> # 删除单个快照
迁移虚拟机
主要有以下步骤:
virsh dumpxml kylin-v10-my > kylin-v10-my-new.xml
拷贝qcow2文件
压缩包
放到新的服务器上
启动
创建自定义网络
总结:
- 创建xml文件,指定网桥名称、IP网段
- 使用命令创建。
- 创建虚拟机时,指定网桥。
任意目录创建nat.xml
文件:
# cat nat.xml
<network>
<name>nat-network</name>
<forward mode='nat'/>
<bridge name='virbrnat' stp='on' delay='0'/>
<ip address='172.18.18.1' netmask='255.255.255.0'>
<dhcp>
<range start='172.18.18.10' end='172.18.18.200'/>
</dhcp>
</ip>
</network>
执行操作:
# 定义网络,此命令后,会在/etc/libvirt/qemu/networks/目录生成xml文件<name>指定名称的文件
virsh net-define nat.xml
# 启动网络,此命令后,网络变成活跃状态
virsh net-start nat-network
# 设置网络自动启动
virsh net-autostart nat-network
# 查看虚拟网桥设备
# ifconfig | grep virbrnat
virbrnat: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
其它网络命令:
virsh net-list --all # 列出所有的网络设备
virsh net-info nat-network # 查看网络详细信息
virsh net-dumpxml nat-network # 查看网络XML定义
virsh net-undefine nat-network # 删除网络
xml配置文件,原来是nat的,改为br0桥接,无法获取外部网络,待解决。
查看物理服务器信息
virsh nodeinfo
修改CPU核心数
virsh edit xxx
修改vcpu字段的数量即可。先关闭,修改,再启动。
使用经验
启动虚拟机后,对外开放的端口,可能会发生变化,需先查询,再用工具连接。
virsh domdisplay <虚拟机名称>
虚拟机维护管理
配置静态IP-kylin
vi /etc/sysconfig/network-scripts/ifcfg-ens3
DEVICE=ens3
TYPE=Ethernet
BOOTPROTO=static
IPADDR=172.18.18.100
PREFIX=25
#NETMASK=255.255.255.0
GATEWAY=10.20.5.1
DNS1=223.5.5.5
ONBOOT=yes
DELAY=0
PREFIX=25
转换得255.255.255.128
。注:=
前后的字段不能有空格
注:原来的网络:
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=dhcp
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens3
UUID=86b4e967-08ed-4bf9-b1d0-69445566ddef
DEVICE=ens3
ONBOOT=no
小结
由于目的较简单,因为本文也只限于创建并使用虚拟机。一些高阶的用法,暂时未涉及到,毕竟不是能够有专门的时间捣鼓研究的。