KVM虚拟化服务器如何创建虚拟机?网络、磁盘与资源配置教程

手上有一台闲置的物理服务器,想把开发、测试、生产环境隔开,或者想把几台老业务机器收敛到一台高配机器上——这时候自建 KVM 虚拟化是最现实的方案。KVM(Kernel-based Virtual Machine,基于内核的虚拟机)已经是 Linux 内核的一部分,配合 libvirt 做管理、qemu 做设备模拟,性能接近原生,而且完全免费。但在实操中,从"装完包"到"虚拟机能上网、能跑满磁盘",中间有不少坑:VNC 连不上、装完系统没网、磁盘 IO 奇慢、虚拟机重启后 IP 变了。本文按真实部署顺序,把 KVM 虚拟化服务器创建虚拟机的完整流程讲一遍,包括网络模式选择、磁盘格式与总线、CPU 与内存分配,以及后期的热调整。

一、部署前:确认宿主机支持虚拟化并装好组件

第一步不是装软件,而是确认 CPU 打开了硬件辅助虚拟化,并且在 BIOS 里是启用状态。很多"装完 libvirt 才发现用不了"的情况,根源都在 BIOS 里 VT-x / AMD-V 被关掉了。

# 1. 确认 CPU 支持硬件虚拟化(输出大于 0 即可)
egrep -c '(vmx|svm)' /proc/cpuinfo
# vmx = Intel VT-x,svm = AMD-V

# 2. 确认内核模块已加载
lsmod | grep kvm
# 应看到 kvm、kvm_intel 或 kvm_amd

# 3. 若模块未加载,手动加载并检查设备节点
modprobe kvm
modprobe kvm_intel      # AMD 机器用 modprobe kvm_amd
ls -l /dev/kvm

# 4. 确认宿主机自身不是虚拟机(嵌套虚拟化需额外配置)
systemd-detect-virt

组件安装。RHEL/CentOS/Rocky 系列与 Debian/Ubuntu 系列的包名不同,注意区分:

# RHEL / CentOS / Rocky / AlmaLinux
yum install -y qemu-kvm libvirt virt-install virt-manager bridge-utils libguestfs-tools
systemctl enable --now libvirtd

# Debian / Ubuntu
apt install -y qemu-kvm libvirt-daemon-system libvirt-clients virtinst bridge-utils libguestfs-tools
systemctl enable --now libvirtd

# 验证服务与默认网络
systemctl status libvirtd
virsh list --all
virsh net-list --all

装完后 libvirt 会自带一个名为 default 的 NAT 网络,网段通常是 192.168.122.0/24,宿主机上会多出一张 virbr0 网桥。它能让虚拟机访问外网,但外部无法主动访问虚拟机——这也是后面要重点改造的地方。

二、网络配置:三种模式怎么选

网络是 KVM 虚拟机最容易出问题的环节。libvirt 提供三种典型模式,选择依据是"虚拟机需不需要被外部网络直接访问"。

模式实现方式外部能否直接访问虚拟机典型场景
NAT(默认)virbr0 + iptables/nftables MASQUERADE,网段 192.168.122.0/24不能,需端口转发开发测试机、只需出网
桥接(Bridge)虚拟网卡桥接到物理网卡,虚拟机与宿主机同网段能,虚拟机有独立 IP生产业务、对外提供服务
仅主机 / 隔离网络libvirt 创建但不接外网不能集群内网、数据库内网

2.1 创建桥接网卡

生产环境几乎都要用桥接,否则每台虚拟机都要做一次端口转发,管理成本极高。CentOS 7 及以前用 ifcfg 文件,RHEL 8/9 和 Ubuntu 建议统一用 nmcli,改错的概率更低。

# 查看当前连接名(记下物理网卡的连接名,如 eth0 / ens33 / enp1s0)
nmcli connection show

# 创建桥接接口 br0
nmcli connection add type bridge con-name br0 ifname br0
nmcli connection modify br0 ipv4.addresses 192.168.1.10/24
nmcli connection modify br0 ipv4.gateway 192.168.1.1
nmcli connection modify br0 ipv4.dns "223.5.5.5 8.8.8.8"
nmcli connection modify br0 ipv4.method manual

# 把物理网卡挂到桥上(这条命令会断开一次网络,请在本地控制台操作)
nmcli connection add type bridge-slave con-name br0-slave ifname ens33 master br0

# 关闭原物理网卡连接并启用 br0
nmcli connection down ens33
nmcli connection up br0

# 验证
ip link show type bridge
brctl show
ip addr show br0

如果用传统 ifcfg 方式,配置大致是:

# /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
TYPE=Bridge
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.1.10
PREFIX=24
GATEWAY=192.168.1.1
DNS1=223.5.5.5
DELAY=0

# /etc/sysconfig/network-scripts/ifcfg-ens33
DEVICE=ens33
TYPE=Ethernet
ONBOOT=yes
BRIDGE=br0          # 关键:物理网卡不再配 IP,只做桥的从属
# 删除或注释 IPADDR / PREFIX / GATEWAY

2.2 自定义 libvirt 网络

# 查看已有网络
virsh net-list --all
virsh net-info default
virsh net-dumpxml default

# 定义一个新的隔离网络(用于集群内网)
cat > /tmp/cluster-net.xml <<'EOF'

  cluster
  
  
    
      
    
  

EOF
virsh net-define /tmp/cluster-net.xml
virsh net-start cluster
virsh net-autostart cluster

三、磁盘:格式、总线与预分配策略

KVM 虚拟机的磁盘是一个宿主机上的镜像文件(或逻辑卷 / 块设备)。格式和总线选错,性能可能差一倍以上。

镜像格式特点适用
raw无元数据开销,性能最好,可直接挂载,但不支持快照、创建即占满空间(除非用稀疏文件)性能敏感、数据库盘
qcow2写时复制、按需增长、支持快照与压缩、支持加密通用场景、需要快照

总线方面,一定要用 virtio。默认的 IDE 模拟每次 I/O 都要多次 VM Exit(虚拟机退出到宿主机),随机写性能可能只有 virtio 的十分之一。网卡同理,model=virtio 才能跑满带宽。

# 创建 40G 的 qcow2 镜像(稀疏文件,实际占用随写入增长)
qemu-img create -f qcow2 /var/lib/libvirt/images/vm01.qcow2 40G

# 创建预分配元数据的 qcow2(写入性能更稳定,创建稍慢)
qemu-img create -f qcow2 -o preallocation=metadata \
    /var/lib/libvirt/images/vm01.qcow2 40G

# 创建 raw 稀疏文件
qemu-img create -f raw /var/lib/libvirt/images/vm01.raw 40G

# 查看镜像信息与实际占用
qemu-img info /var/lib/libvirt/images/vm01.qcow2
ls -lh /var/lib/libvirt/images/vm01.qcow2

# 离线扩容(先扩镜像,再在虚拟机内扩分区与文件系统)
qemu-img resize /var/lib/libvirt/images/vm01.qcow2 +20G

# 格式转换
qemu-img convert -f qcow2 -O raw vm01.qcow2 vm01.raw

# 检查镜像一致性(操作镜像前建议做一次)
qemu-img check /var/lib/libvirt/images/vm01.qcow2

四、创建虚拟机:virt-install 完整命令

建议用 virt-install 命令行创建,便于复制、审计和批量化,图形化的 virt-manager 适合临时排查。先看看系统支持哪些 --os-variant:

osinfo-query os | egrep -i 'centos|rocky|ubuntu|debian|windows|openEuler'
# --os-variant 会告诉 libvirt 优化时钟、默认设备型号和驱动,务必填准确

一条完整的创建命令(桥接网络 + virtio 磁盘网卡 + VNC 安装):

virt-install \
  --name vm01 \
  --os-variant centos8 \
  --vcpus 2,maxvcpus=8 \
  --memory 4096,maxmemory=16384 \
  --disk path=/var/lib/libvirt/images/vm01.qcow2,format=qcow2,bus=virtio,cache=none,io=native \
  --cdrom /data/iso/CentOS-8-x86_64-Minimal.iso \
  --network bridge=br0,model=virtio \
  --graphics vnc,listen=0.0.0.0,port=5901 \
  --console pty,target_type=serial \
  --boot cdrom,hd,menu=on \
  --noautoconsole

各关键参数说明:

  • --vcpus 2,maxvcpus=8:当前 2 个 vCPU,最多可热加到 8 个,为后续扩容留口子。
  • --memory 4096,maxmemory=16384:单位 MiB,同样预留热扩容上限。
  • cache=none,io=native:绕过宿主机页缓存,配合 SSD 可降低延迟、避免双缓存;如果底层是机械盘或者内存非常紧张,可改用 cache=writeback。
  • --graphics vnc,listen=0.0.0.0:默认只监听 127.0.0.1,远程安装必须放开;生产环境应配合防火墙限制来源 IP。
  • --console pty,target_type=serial:装完系统后可用 virsh console 直接进终端,不必依赖 VNC。
  • 如果用网络安装源,把 --cdrom 换成 --location http://mirrors.example.com/centos/8/os/x86_64/ 并加 --extra-args "console=ttyS0"。
# 查看 VNC 端口,用客户端连过去完成系统安装
virsh vncdisplay vm01

# 安装过程中常用的域管理命令
virsh list --all
virsh dominfo vm01
virsh start vm01
virsh shutdown vm01     # ACPI 关机,优雅
virsh destroy vm01      # 强制断电,等同拔电源,慎用
virsh reboot vm01
virsh autostart vm01    # 宿主机开机后自动拉起
virsh autostart --disable vm01

五、资源调整:CPU、内存、磁盘的热扩容与绑定

虚拟机创建后,资源不是一成不变的。libvirt 支持相当多的在线调整,但内存只能热减不能热加超过 maxmemory,CPU 热加需要 guest 内核配合,磁盘扩容要在 guest 内做两步。

5.1 CPU 调整与绑定

# 查看 vCPU 与物理 CPU 的映射关系
virsh vcpuinfo vm01

# 把 vCPU 0 绑定到物理 CPU 2(减少跨 NUMA 访问,降低抖动)
virsh vcpupin vm01 0 2
virsh vcpupin vm01 1 3

# 热增加 vCPU(需先配置过 maxvcpus,且 guest 内要上线新 CPU)
virsh setvcpus vm01 4 --live
# guest 内确认
echo 1 > /sys/devices/system/cpu/cpu2/online
lscpu

# 配置写入持久化(--config 影响下次启动的定义)
virsh setvcpus vm01 4 --config

5.2 内存调整与 NUMA

# 热调整内存(不能超过 maxmemory)
virsh setmem vm01 8192 --live
virsh setmem vm01 8192 --config

# 查看内存实际用量(statm 中的"实际使用"比分配值更有参考价值)
virsh dommemstat vm01

# NUMA 绑定,把虚拟机固定在 node 0 上
virsh numatune vm01 --nodeset 0 --mode strict

# 查看宿主机 NUMA 拓扑,决定绑定策略
numactl --hardware
lstopo-no-graphics        # 需安装 hwloc

5.3 磁盘在线扩容(两步缺一不可)

# 第一步:宿主机上扩虚拟磁盘
virsh blockresize vm01 vda 60G
# 或 virsh blockresize --domain vm01 --path /var/lib/libvirt/images/vm01.qcow2 --size 60G

# 第二步:虚拟机内扩分区与文件系统
# 先确认磁盘已变大
lsblk
fdisk -l /dev/vda

# 场景 A:LVM
pvresize /dev/vda2
lvextend -l +100%FREE /dev/mapper/centos-root
xfs_growfs /                 # XFS
# 或 resize2fs /dev/mapper/centos-root   # ext4

# 场景 B:直接分区(无 LVM),用 growpart 扩分区号
growpart /dev/vda 2
xfs_growfs /
df -h

5.4 快照与克隆

# 创建快照(qcow2 格式支持)
virsh snapshot-create-as vm01 --name snap-before-upgrade \
    --description "2024-10-14 升级前" --atomic

virsh snapshot-list vm01
virsh snapshot-info vm01 snap-before-upgrade
virsh snapshot-revert vm01 snap-before-upgrade
virsh snapshot-delete vm01 snap-before-upgrade

# 克隆一台新虚拟机(源机需关机或处于一致状态)
virt-clone -o vm01 -n vm02 -f /var/lib/libvirt/images/vm02.qcow2
# 克隆后要改 hostname、删除 machine-id、重生成 SSH host key
cat /dev/null > /etc/machine-id
systemd-machine-id-setup
rm -f /etc/ssh/ssh_host_*
ssh-keygen -A

六、日常运维与故障排查清单

  1. 虚拟机起不来:先看 virsh list --all 状态,再看日志 /var/log/libvirt/qemu/vm01.log。
  2. libvirtd 连不上:检查 systemctl status libvirtd,普通用户需加入 libvirt 组,或使用 virsh -c qemu:///system。
  3. 虚拟机没网:确认宿主机 br0 有 IP、物理网卡已 slave 到 br0、虚拟机网卡 model=virtio、guest 内网卡已 ONBOOT=yes。
  4. 磁盘 IO 慢:确认 bus=virtio、cache=none、宿主机磁盘未做 RAID 降级、镜像未放在 NFS 上做同步写。
  5. VNC 连不上:确认 --graphics vnc,listen=0.0.0.0,防火墙放行 5900+ 端口,virsh vncdisplay 查实际端口。
  6. 时钟漂移:确认 --os-variant 正确,Linux guest 建议启用 kvm-clock,Windows guest 安装 virtio 驱动并配置 NTP。
  7. 宿主机内存被吃光:检查是否给虚拟机分配了过量内存,或宿主机开启了 KSM(Kernel Samepage Merging)导致 CPU 上升。
# 常用排查命令合集
virsh domstats vm01                    # 一次性拿到 CPU/内存/磁盘/网络统计
virsh domblklist vm01                  # 磁盘列表
virsh domiflist vm01                   # 网卡列表
virsh domifstat vm01 vnet0             # 网卡流量
virsh domblkstat vm01 vda              # 磁盘 I/O 统计
journalctl -u libvirtd -f              # libvirtd 日志
ls /var/log/libvirt/qemu/              # 各虚拟机日志目录

小结

KVM 虚拟化服务器创建虚拟机的标准路径是:确认硬件虚拟化 → 装 libvirt 组件 → 规划网络(生产用桥接)→ 建 virtio 磁盘镜像 → virt-install 创建 → VNC 装系统 → 按需做 CPU/内存/磁盘调整。看起来步骤多,但真正决定长期可用性的只有三件事:网络模式选对、磁盘总线用 virtio、资源上限在创建时就预留。这三件事在创建时花五分钟,能省掉后面无数次停机维护。

避坑建议:

  • 新建虚拟机一定要写 --os-variant,否则时钟和设备默认值可能不合适,Windows 会出现时间越走越慢。
  • 内存热加受 maxmemory 限制,创建时就要把上限设大;CPU 同理用 maxvcpus。
  • 生产环境慎用 virsh destroy,它等价于拔电源,可能造成文件系统损坏。
  • 快照不是备份。qcow2 快照链越长 I/O 越慢,且宿主机 disk 损坏时快照一起丢,重要数据必须另外做异地备份。
  • 不要把所有虚拟机的镜像放在同一块机械盘上,随机 IOPS 会成为整个宿主机的瓶颈。
  • 给宿主机留资源:建议宿主机自己保留 2-4GB 内存和 1-2 个物理核心,不要让虚拟机把资源分干净。

延伸阅读:虚拟机网络不通是自建虚拟化最高频的问题,通常与桥接配置、虚拟交换机和防火墙规则有关,可结合网络排查类文章一起看。