企业级KVM虚拟化平台搭建实战

描述

一、概述

1.1 背景介绍

企业IT基础设施经历了从物理机时代到虚拟化时代的演进。传统数据中心中,每台物理服务器运行单一应用,资源利用率普遍不足20%。硬件采购周期长、扩容慢、运维成本高,难以满足业务快速发展的需求。虚拟化技术的出现彻底改变了这一局面,通过在单台物理机上运行多个虚拟机,将资源利用率提升至60%以上,同时实现了分钟级的虚拟机创建和弹性伸缩。

KVM(Kernel-based Virtual Machine)是Linux内核内置的虚拟化解决方案,自2007年合并入Linux 2.6.20内核后,逐渐成为开源虚拟化领域的事实标准。与VMware vSphere、Microsoft Hyper-V等商业方案相比,KVM完全开源免费,性能接近原生,且与Linux生态深度集成。红帽OpenStack、Proxmox VE、oVirt等企业级私有云平台均以KVM作为底层虚拟化引擎。

2026年的KVM生态已相当成熟。Linux 6.x内核带来了显著的虚拟化性能提升,QEMU 9.x增加了对ARM64和RISC-V架构的完整支持,libvirt 10.x提供了更强大的管理能力。结合Ceph分布式存储和Open vSwitch软件定义网络,KVM已具备构建大规模企业级私有云的全部能力。

1.2 技术特点

硬件辅助虚拟化

KVM依赖CPU的硬件虚拟化扩展(Intel VT-x或AMD-V)实现高效虚拟化。硬件虚拟化通过引入新的CPU特权级别(VMX root/non-root模式),使虚拟机能够直接执行大部分指令而无需陷入宿主机处理,性能损耗控制在5%以内。相比纯软件模拟方案(如早期QEMU),性能提升数十倍。

全虚拟化与半虚拟化

KVM支持两种虚拟化模式。全虚拟化模式下,Guest OS无需修改即可运行,QEMU模拟完整的硬件环境。半虚拟化模式通过virtio驱动,Guest OS直接与宿主机通信,避免了硬件模拟开销,I/O性能接近原生。生产环境强烈建议使用virtio驱动。

内存虚拟化技术

KVM使用EPT(Extended Page Tables,Intel)或NPT(Nested Page Tables,AMD)技术加速内存虚拟化,减少地址转换开销。KSM(Kernel Same-page Merging)技术可自动合并虚拟机间的相同内存页,在运行多个相同OS的虚拟机场景下显著节省内存。Huge Pages支持减少TLB miss,提升内存访问性能。

设备直通

VFIO框架支持将物理设备(如GPU、NVMe SSD、网卡)直接分配给虚拟机,虚拟机独占设备,性能与物理机无异。SR-IOV技术允许单个物理网卡虚拟出多个虚拟功能(VF),每个VF可分配给不同虚拟机,实现高性能网络虚拟化。

热迁移能力

KVM支持在不停机的情况下将运行中的虚拟机从一台物理机迁移到另一台。热迁移过程中,虚拟机内存通过迭代复制传输,业务中断时间控制在毫秒级。这一能力是实现物理机维护、负载均衡和高可用的基础。

1.3 适用场景

服务器整合

将多个低负载的物理服务器整合到少量高配置物理机上运行,减少硬件数量和机房空间占用,降低电力和冷却成本。典型场景如将20台利用率10%的物理机整合到3台虚拟化主机上。

开发测试环境

为开发团队提供自助式虚拟机服务,开发者可快速创建与生产环境一致的测试环境。虚拟机快照支持环境的快速回滚,便于测试验证。相比云主机方案,私有云测试环境成本更低且数据不出内网。

私有云平台

大中型企业构建内部云平台,对外提供IaaS服务。业务部门通过自助门户申请虚拟机资源,IT部门统一管理物理资源池。相比公有云,私有云在数据安全、合规性和长期成本方面具有优势。

容器基础设施

Kubernetes等容器平台通常部署在虚拟机集群之上,而非直接运行在物理机上。虚拟化层提供了更好的隔离性和资源管理能力,便于集群的扩容缩容和故障恢复。

灾难恢复

虚拟机作为文件存在,便于备份和跨站点复制。结合存储复制技术,可实现分钟级RPO的异地灾备。灾难发生时,在备份站点启动虚拟机即可恢复业务。

1.4 环境要求

组件 最低配置 推荐配置 说明
CPU 支持VT-x/AMD-V Intel Xeon 4代+ / AMD EPYC 需在BIOS中启用虚拟化
内存 16GB 256GB+ 每VM至少分配2GB
存储 500GB HDD NVMe SSD + Ceph集群 虚拟机镜像和数据存储
网络 1Gbps 10Gbps/25Gbps 建议双网卡绑定
操作系统 RHEL 9 / Ubuntu 22.04 Rocky Linux 9.3 / Ubuntu 24.04 宿主机操作系统
内核版本 5.15+ 6.6+ LTS 推荐使用最新LTS内核
QEMU 8.0+ 9.1+ 虚拟机模拟器
libvirt 9.0+ 10.5+ 虚拟化管理API
virt-manager 4.0+ 4.1+ 图形化管理工具

二、详细步骤

2.1 准备工作

检查CPU虚拟化支持

部署KVM前必须确认CPU支持硬件虚拟化:

 

# 检查CPU虚拟化标志
# Intel CPU查找vmx,AMD CPU查找svm
grep -E '(vmx|svm)' /proc/cpuinfo | head -1

# 如果有输出则表示支持,如:
# flags : ... vmx ...

# 使用专用工具检查
apt install cpu-checker -y   # Debian/Ubuntu
kvm-ok

# 期望输出
INFO: /dev/kvm exists
KVM acceleration can be used

 

如果CPU支持虚拟化但/dev/kvm不存在,需要在BIOS中启用虚拟化功能(Intel VT-x / AMD-V)。

检查内核模块

 

# 查看KVM模块是否加载
lsmod | grep kvm

# 期望输出(Intel平台)
kvm_intel             385024  0
kvm                  1142784  1 kvm_intel

# AMD平台
kvm_amd               155648  0
kvm                  1142784  1 kvm_amd

# 如未加载,手动加载模块
modprobe kvm
modprobe kvm_intel  # 或 kvm_amd

 

安装KVM组件

RHEL/Rocky Linux/CentOS Stream:

 

# 安装虚拟化组件
dnf install -y qemu-kvm libvirt libvirt-client virt-install virt-viewer virt-manager

# 安装额外工具
dnf install -y bridge-utils virt-top libguestfs-tools

# 启动libvirtd服务
systemctl enable --now libvirtd

# 验证安装
virsh version

 

Ubuntu/Debian:

 

# 安装虚拟化组件
apt update
apt install -y qemu-kvm libvirt-daemon-system libvirt-clients virtinst virt-manager

# 安装额外工具
apt install -y bridge-utils libguestfs-tools cpu-checker

# 将当前用户加入libvirt组
usermod -aG libvirt $USER
usermod -aG kvm $USER

# 启动服务
systemctl enable --now libvirtd

# 验证
virsh list --all

 

配置存储池

libvirt使用存储池管理虚拟机磁盘镜像:

 

# 查看默认存储池
virsh pool-list --all

# 创建目录类型存储池
virsh pool-define-as vmpool dir --target /data/libvirt/images
virsh pool-build vmpool
virsh pool-start vmpool
virsh pool-autostart vmpool

# 验证存储池
virsh pool-info vmpool

# 输出示例
Name:           vmpool
UUID:           xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
State:          running
Persistent:     yes
Autostart:      yes
Capacity:       1.82 TiB
Allocation:     156.23 GiB
Available:      1.67 TiB

 

2.2 核心配置

配置网桥网络

生产环境虚拟机通常使用网桥模式接入网络,与物理机处于同一网段:

 

# 使用nmcli配置网桥(RHEL系)
# 创建网桥
nmcli connection add type bridge ifname br0 con-name br0

# 配置网桥IP
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 "8.8.8.8 114.114.114.114"
nmcli connection modify br0 ipv4.method manual

# 将物理网卡加入网桥
nmcli connection add type bridge-slave ifname eth0 master br0

# 关闭原网卡连接
nmcli connection down "Wired connection 1"

# 启用网桥
nmcli connection up br0

 

Ubuntu使用netplan配置:

 

# /etc/netplan/01-bridge.yaml
network:
version:2
renderer:networkd
ethernets:
    eth0:
      dhcp4:false
bridges:
    br0:
      interfaces:[eth0]
      addresses:
        -192.168.1.10/24
      routes:
        -to:default
          via:192.168.1.1
      nameservers:
        addresses:[8.8.8.8,114.114.114.114]
      parameters:
        stp:false
        forward-delay:0
# 应用配置
netplan apply

# 验证网桥
ip addr show br0
bridge link show

 

在libvirt中定义网桥网络:

 

 

  br0-network
  
  

# 定义并启动网络
virsh net-define /tmp/bridge-network.xml
virsh net-start br0-network
virsh net-autostart br0-network

# 查看网络列表
virsh net-list --all

 

配置NAT网络(隔离网络)

开发测试环境可使用NAT模式,虚拟机通过宿主机NAT访问外网:

 

 

dev-network

    
      
    



    
      
      
      
    


virsh net-define /tmp/nat-network.xml
virsh net-start dev-network
virsh net-autostart dev-network

 

配置存储后端

本地LVM存储(高性能):

 

# 创建LVM卷组用于虚拟机存储
pvcreate /dev/sdb
vgcreate vg_vm /dev/sdb

# 定义LVM存储池
virsh pool-define-as lvmpool logical --source-name vg_vm --target /dev/vg_vm
virsh pool-start lvmpool
virsh pool-autostart lvmpool

 

NFS共享存储(支持热迁移):

 

# 挂载NFS存储
mkdir -p /data/nfs-vm
mount -t nfs nfs-server:/export/vm-images /data/nfs-vm

# 配置开机自动挂载
echo "nfs-server:/export/vm-images /data/nfs-vm nfs defaults,_netdev 0 0" >> /etc/fstab

# 定义NFS存储池
virsh pool-define-as nfspool netfs --source-host nfs-server --source-path /export/vm-images --target /data/nfs-vm
virsh pool-start nfspool
virsh pool-autostart nfspool

 

libvirt配置优化

编辑/etc/libvirt/libvirtd.conf:

 

# 监听TCP连接(集群管理需要)
listen_tls = 0
listen_tcp = 1
tcp_port = "16509"
listen_addr = "0.0.0.0"
auth_tcp = "none"# 生产环境应配置SASL认证

# 日志配置
log_level = 3
log_outputs = "3/var/log/libvirt/libvirtd.log"

# 性能优化
max_clients = 5000
max_workers = 20
max_requests = 20
max_client_requests = 5

 

启用TCP监听:

 

# RHEL系
echo 'LIBVIRTD_ARGS="--listen"' >> /etc/sysconfig/libvirtd

# Ubuntu
echo 'libvirtd_opts="-l"' >> /etc/default/libvirtd

# 重启服务
systemctl restart libvirtd

 

2.3 启动和验证

创建虚拟机

使用virt-install命令行创建虚拟机:

 

# 创建CentOS虚拟机
virt-install 
  --name centos9-vm1 
  --memory 4096 
  --vcpus 2 
  --cpu host-passthrough 
  --disk path=/data/libvirt/images/centos9-vm1.qcow2,size=50,format=qcow2,bus=virtio 
  --network network=br0-network,model=virtio 
  --os-variant centos-stream9 
  --graphics vnc,listen=0.0.0.0,port=5901 
  --cdrom /data/iso/CentOS-Stream-9-latest-x86_64-dvd1.iso 
  --boot cdrom,hd 
  --noautoconsole

# 参数说明
# --cpu host-passthrough: 透传CPU特性,性能最优
# --disk bus=virtio: 使用virtio磁盘驱动
# --network model=virtio: 使用virtio网络驱动

 

使用cloud-init快速创建虚拟机(推荐):

 

# 下载cloud镜像
wget https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2

# 创建磁盘
qemu-img create -f qcow2 -F qcow2 -b CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2 centos9-vm1.qcow2 50G

# 创建cloud-init配置
cat > /tmp/cloud-init.yaml <

 

验证虚拟机运行

 

# 查看虚拟机列表
virsh list --all

# 查看虚拟机详情
virsh dominfo centos9-vm1

# 查看虚拟机IP地址
virsh domifaddr centos9-vm1

# 连接虚拟机控制台
virsh console centos9-vm1

# VNC连接(如果配置了VNC)
virt-viewer centos9-vm1

 

基本生命周期管理

 

# 启动虚拟机
virsh start centos9-vm1

# 优雅关机
virsh shutdown centos9-vm1

# 强制关机
virsh destroy centos9-vm1

# 重启
virsh reboot centos9-vm1

# 暂停(挂起到内存)
virsh suspend centos9-vm1

# 恢复
virsh resume centos9-vm1

# 设置开机自启
virsh autostart centos9-vm1

# 删除虚拟机(保留磁盘)
virsh undefine centos9-vm1

# 删除虚拟机及磁盘
virsh undefine centos9-vm1 --remove-all-storage

 

三、示例代码和配置

3.1 完整配置示例

虚拟机XML配置模板

 

 

production-vm
auto-generated

    sre-team
    e-commerce

16
16
8

 

    
    
      
    


 

    
      
    
    
    



    hvm
    
    



    
    
    
    
      
    



    
    
    


destroy
restart
restart


    /usr/libexec/qemu-kvm

     
    
      
      
      
      
    

     
    
      
      
      
      
    

     
    
      
      
      
      
      
    

     
    
      
        
      
    
    
      
    

     
    
      
    

     
    
      
      
    

     
    
      /dev/urandom
      
    

     
    
      
    


 

    
    
    
    
    
    
    
    
    


 

批量创建虚拟机脚本

 

#!/bin/bash
# batch-create-vm.sh - 批量创建虚拟机

set -e

# 配置参数
BASE_IMAGE="/data/templates/centos9-template.qcow2"
VM_DIR="/data/libvirt/images"
NETWORK="br0-network"
CLOUD_INIT_DIR="/tmp/cloud-init"

# 虚拟机配置列表
declare -A VMS=(
    ["web-server-01"]="409650"   # 名称="内存MB磁盘GB"
    ["web-server-02"]="409650"
    ["db-server-01"]="8192100"
    ["cache-server-01"]="409630"
)

# 创建cloud-init目录
mkdir -p ${CLOUD_INIT_DIR}

create_vm() {
    local name=$1
    local memory=$2
    local vcpus=$3
    local disk_size=$4

    echo"Creating VM: ${name} (Memory: ${memory}MB, CPU: ${vcpus}, Disk: ${disk_size}GB)"

    # 创建磁盘
    qemu-img create -f qcow2 -F qcow2 -b ${BASE_IMAGE}${VM_DIR}/${name}.qcow2 ${disk_size}G

    # 生成cloud-init配置
    cat > ${CLOUD_INIT_DIR}/${name}-cloud.yaml </dev/null | grep -oE '([0-9]{1,3}.){3}[0-9]{1,3}' | head -1)
    echo"  ${vm}: ${ip:-'Not assigned yet'}"
done

 

虚拟机热迁移脚本

 

#!/bin/bash
# live-migrate.sh - 虚拟机热迁移脚本

VM_NAME=$1
DEST_HOST=$2
SHARED_STORAGE="/data/nfs-vm"# 共享存储路径

if [[ -z "$VM_NAME" || -z "$DEST_HOST" ]]; then
    echo"Usage: $0  "
    exit 1
fi

# 检查虚拟机状态
vm_state=$(virsh domstate "$VM_NAME" 2>/dev/null)
if [[ "$vm_state" != "running" ]]; then
    echo"Error: VM $VM_NAME is not running (state: $vm_state)"
    exit 1
fi

# 检查目标主机连通性
if ! virsh -c qemu+ssh://${DEST_HOST}/system list >/dev/null 2>&1; then
    echo"Error: Cannot connect to destination host $DEST_HOST"
    exit 1
fi

# 检查共享存储
disk_path=$(virsh domblklist "$VM_NAME" | grep -E '.qcow2' | awk '{print $2}')
if [[ ! "$disk_path" =~ ^${SHARED_STORAGE} ]]; then
    echo"Error: VM disk is not on shared storage. Live migration requires shared storage."
    echo"Disk path: $disk_path"
    exit 1
fi

echo"Starting live migration of $VM_NAME to $DEST_HOST..."

# 执行热迁移
virsh migrate 
    --live 
    --persistent 
    --undefinesource 
    --verbose 
    --compressed 
    --auto-converge 
    "$VM_NAME" 
    "qemu+ssh://${DEST_HOST}/system"

if [[ $? -eq 0 ]]; then
    echo"Migration completed successfully"

    # 验证迁移结果
    echo"Verifying on destination host..."
    virsh -c qemu+ssh://${DEST_HOST}/system dominfo "$VM_NAME"
else
    echo"Migration failed"
    exit 1
fi

 

3.2 实际应用案例

案例一:电商公司私有云平台

某电商公司年GMV 50亿,原有30台物理服务器分散部署各类应用,存在以下问题:

资源利用率不均,部分服务器负载不足10%

扩容周期长,新业务上线需要数周采购部署

灾备能力弱,单机故障影响业务可用性

解决方案:采用KVM构建私有云平台,配置如下:

 

硬件配置:
- 5台Dell R750xa服务器(双路Xeon 8380,512GB内存,8x 1.92TB NVMe)
- 2台存储服务器构建Ceph集群(24x 10TB HDD + 4x 3.84TB NVMe)
- 2台万兆交换机做网络冗余

软件架构:
- 宿主机:Rocky Linux 9.3 + KVM/QEMU 9.0
- 管理平台:Proxmox VE 8.1(提供Web管理界面)
- 存储:Ceph Pacific(RBD作为虚拟机磁盘后端)
- 网络:Open vSwitch + VLAN隔离

 

实施效果:

物理服务器从30台减少到5台,机房空间节省80%

资源利用率提升到60%,年电费节省约15万

新虚拟机创建时间从2周缩短到5分钟

通过热迁移实现物理机维护期间零业务中断

案例二:金融机构开发测试云

某银行科技部门需要为200+开发人员提供测试环境,原有方案是每人分配固定虚拟机,存在资源浪费和环境不一致问题。

解决方案:构建自助式开发测试云

 

# 虚拟机模板配置
templates:
-name:dev-centos9-small
    vcpus:2
    memory:4096
    disk:50G
    description:开发测试小规格

-name:dev-centos9-medium
    vcpus:4
    memory:8192
    disk:100G
    description:开发测试中规格

-name:db-mysql8-template
    vcpus:4
    memory:16384
    disk:200G
    preinstalled:mysql-8.0
    description:MySQL数据库模板

# 资源配额
quotas:
per_user:
    max_vms:5
    max_vcpus:16
    max_memory:32768
    max_storage:500G

per_project:
    max_vms:50
    max_vcpus:200
    max_memory:512000
    max_storage:5T

 

配合WebVirtCloud开源管理界面,实现:

开发人员自助申请、创建、管理虚拟机

虚拟机自动过期回收(默认7天,可申请延期)

快照功能支持环境保存和快速回滚

与LDAP集成实现统一身份认证

案例三:GPU虚拟化机器学习平台

AI团队需要共享使用GPU资源进行模型训练和推理,直接使用物理机存在资源争抢问题。

解决方案:基于KVM+vGPU构建GPU虚拟化平台

 

# 配置NVIDIA vGPU(需要NVIDIA vGPU软件许可)

# 1. 安装vGPU管理器
rpm -ivh nvidia-vgpu-kvm-xxx.rpm

# 2. 配置mdev设备
# 查看支持的vGPU类型
ls /sys/class/mdev_bus/000000.0/mdev_supported_types/

# 创建vGPU实例
echo"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" > /sys/class/mdev_bus/000000.0/mdev_supported_types/nvidia-256/create

# 3. 虚拟机配置GPU直通
cat >> vm-gpu.xml <
  
    
  EOF

 

另一种方案是使用SR-IOV直通(适用于NVIDIA A100等支持MIG的GPU):

 

# 配置MIG模式
nvidia-smi -i 0 -mig 1

# 创建GPU实例
nvidia-smi mig -cgi 9,9,9,9,9,9,9 -C

# 使用VFIO直通给虚拟机

 

四、最佳实践和注意事项

4.1 最佳实践

性能优化

CPU优化:

 

# 使用host-passthrough模式透传CPU特性
# XML配置


# CPU绑定(避免NUMA跨节点访问)
virsh vcpupin vm-name 0 2
virsh vcpupin vm-name 1 3

# 查看NUMA拓扑
numactl -H
virsh numatune vm-name

 

内存优化:

 

# 启用大页内存
# 分配2MB大页
echo 4096 > /proc/sys/vm/nr_hugepages

# 永久配置
echo"vm.nr_hugepages=4096" >> /etc/sysctl.conf

# XML配置使用大页

  


# 启用KSM(相同内存页合并)
echo 1 > /sys/kernel/mm/ksm/run
echo 1000 > /sys/kernel/mm/ksm/sleep_millisecs

 

磁盘I/O优化:

 

# 使用virtio-blk或virtio-scsi
# 配置cache模式
# - none: 直接I/O,适合数据库(需要Guest OS有回写缓存)
# - writeback: 宿主机回写缓存(性能好但不安全)
# - writethrough: 写穿透(安全但性能差)

# XML配置

  
  ...


# 启用TRIM支持(qcow2磁盘瘦身)
# Guest内执行
fstrim -av

 

网络优化:

 

# 使用vhost-net加速

  
    # 多队列


# 启用多队列virtio-net(Guest内)
ethtool -L eth0 combined 4

# SR-IOV直通(最高性能)
# 启用SR-IOV
echo 4 > /sys/class/net/eth0/device/sriov_numvfs

# 直通VF给虚拟机

  
    
 

 

安全加固

 

# 1. 限制libvirt访问
# 使用UNIX socket认证
unix_sock_group = "libvirt"
unix_sock_ro_perms = "0770"
unix_sock_rw_perms = "0770"

# 2. 启用SELinux/AppArmor
# SELinux配置
semanage boolean -m --on virt_use_fusefs
semanage boolean -m --on virt_use_nfs

# 3. 配置sVirt隔离
# 确保每个VM有独立的SELinux上下文


# 4. 限制虚拟机资源

  20
  16



  500


# 5. 网络隔离
# 使用VLAN或SDN隔离不同租户/业务

  
  
    
  

 

高可用配置

 

# 方案一:基于共享存储的HA
# 所有宿主机挂载相同NFS/Ceph存储
# 任意宿主机故障时,在其他节点启动VM

# 监控脚本示例
#!/bin/bash
HOSTS="kvm1 kvm2 kvm3"
SHARED_DIR="/data/nfs-vm"

for host in$HOSTS; do
    if ! ssh $host"virsh list" >/dev/null 2>&1; then
        echo"Host $host is down, starting VMs on backup host..."
        # 获取故障主机的VM列表并在备用主机启动
        for xml in $(ls ${SHARED_DIR}/configs/${host}/*.xml); do
            virsh define $xml
            virsh start $(basename $xml .xml)
        done
    fi
done

# 方案二:使用Pacemaker/Corosync构建集群
# 安装集群软件
dnf install pacemaker corosync pcs fence-agents-all

# 配置集群
pcs cluster setup --name kvm-cluster kvm1 kvm2 kvm3
pcs cluster start --all
pcs cluster enable --all

# 配置虚拟机资源
pcs resource create vm-webapp ocfVirtualDomain 
  config="/etc/libvirt/qemu/webapp.xml" 
  hypervisor="qemu:///system" 
  migration_transport="ssh" 
  op start timeout="120s" 
  op stop timeout="120s" 
  op monitor timeout="30s" interval="10s" 
  meta allow-migrate="true"

 

4.2 注意事项

问题类型 典型表现 根本原因 解决方案
虚拟机启动失败 "cannot access storage file" 存储权限或SELinux阻止 chown qemu:qemu  或调整SELinux
网络不通 Guest无法获取IP 网桥配置错误或防火墙规则 检查br配置、firewalld/iptables
性能差 I/O延迟高 未使用virtio驱动 安装virtio驱动,配置cache=none
热迁移失败 "unable to connect" 目标主机libvirt未监听TCP 启用listen_tcp,检查防火墙
CPU利用率虚高 steal time高 vCPU超分过度 减少vCPU超分比例(建议<3:1)
内存不足 OOM Killer杀进程 内存超分过度或未配balloon 配置balloon驱动,减少超分
快照失败 "domain is not active" 内部快照需要VM运行 使用外部快照或在VM运行时执行
Windows蓝屏 WHEA错误 CPU特性不兼容 使用host-model或指定CPU型号

磁盘空间管理

 

# qcow2镜像会随使用增长,需要定期瘦身

# 方法1:Guest内TRIM + 镜像压缩
# Guest执行
fstrim -av

# 宿主机压缩镜像(需要停机)
virsh shutdown vm-name
qemu-img convert -O qcow2 -c vm.qcow2 vm-new.qcow2
mv vm-new.qcow2 vm.qcow2
virsh start vm-name

# 方法2:在线瘦身(QEMU 4.0+)
virsh blockresize vm-name vda --size 50G
# Guest内扩展分区

# 监控磁盘实际使用
qemu-img info --output=json vm.qcow2 | jq '.["actual-size"]'

 

五、故障排查和监控

5.1 故障排查

虚拟机无法启动

 

# 步骤1:查看详细错误信息
virsh start vm-name 2>&1

# 步骤2:检查libvirt日志
tail -100 /var/log/libvirt/qemu/vm-name.log
journalctl -u libvirtd -f

# 步骤3:验证XML配置
virsh dumpxml vm-name > /tmp/vm.xml
virt-xml-validate /tmp/vm.xml

# 步骤4:检查存储和权限
ls -la /data/libvirt/images/vm-name.qcow2
# 确保属主是qemu:qemu(RHEL)或libvirt-qemu:kvm(Ubuntu)

# 步骤5:检查SELinux
ausearch -m avc -ts recent
# 如有SELinux拒绝,执行
restorecon -Rv /data/libvirt/images/

 

网络故障排查

 

# 检查网桥状态
ip link show br0
bridge link show

# 检查虚拟机网卡
virsh domiflist vm-name

# 检查TAP设备
ip link show | grep tap

# 检查ARP表
ip neigh show

# 抓包分析
tcpdump -i br0 -n host 192.168.1.100

# 检查libvirt网络
virsh net-info br0-network
virsh net-dhcp-leases br0-network

 

性能问题诊断

 

# CPU相关
# 查看vCPU与物理CPU映射
virsh vcpuinfo vm-name

# 查看steal time(Guest内)
vmstat 1

# 查看CPU调度延迟
perf kvm stat live

# 内存相关
# 查看KSM状态
cat /sys/kernel/mm/ksm/pages_sharing
cat /sys/kernel/mm/ksm/pages_shared

# 查看balloon状态
virsh dommemstat vm-name

# I/O相关
# 查看块设备统计
virsh domblkstat vm-name vda

# 使用blktrace跟踪
blktrace -d /dev/sdb -o - | blkparse -i -

# 网络相关
# 查看网络统计
virsh domifstat vm-name vnet0

# 查看vhost-net使用情况
ethtool -S vnet0

 

5.2 性能监控

virt-top实时监控

 

# 安装
dnf install virt-top

# 运行
virt-top

# 输出示例
virt-top 0915 - x86_64 8/8CPU 1200MHz 64304MB
3 domains, 1 active, 1 running, 0 sleeping, 0 paused, 2 inactive D:0 O:0 X:0
CPU: 12.5%  Mem: 24576 MB (24576 MB by guests)

   ID S RDRQ WRRQ RXBY TXBY %CPU %MEM    TIME   NAME
    5 R    0  156  91K  12K  8.3 25.0   5:32.61 production-vm

 

Prometheus + libvirt-exporter监控

 

# docker-compose.yml
version:'3'
services:
libvirt-exporter:
    image:alekseifaikin/libvirt-exporter:latest
    volumes:
      -/var/run/libvirt/libvirt-sock:/var/run/libvirt/libvirt-sock:ro
    ports:
      -"9177:9177"
    command:--libvirt.uri="qemu:///system"

 

关键监控指标:

 

# Prometheus告警规则
groups:
-name:kvm
    rules:
      -alert:VMHighCPU
        expr:libvirt_domain_info_cpu_time_seconds_total>90
        for:5m
        labels:
          severity:warning
        annotations:
          summary:"VM CPU使用率过高"

      -alert:VMMemoryPressure
        expr:libvirt_domain_info_memory_actual_bytes/libvirt_domain_info_memory_maximum_bytes>0.95
        for:5m
        labels:
          severity:warning
        annotations:
          summary:"VM内存使用率过高"

      -alert:VMDiskIOHigh
        expr:rate(libvirt_domain_block_stats_write_bytes_total[5m])>100000000
        for:5m
        labels:
          severity:info
        annotations:
          summary:"VM磁盘写入速率高"

 

Grafana仪表板

 

{
  "title": "KVM虚拟机监控",
"panels": [
    {
      "title": "VM CPU使用率",
      "type": "graph",
      "targets": [
        {
          "expr": "rate(libvirt_domain_info_cpu_time_seconds_total[1m]) * 100",
          "legendFormat": "{{domain}}"
        }
      ]
    },
    {
      "title": "VM内存使用",
      "type": "graph",
      "targets": [
        {
          "expr": "libvirt_domain_info_memory_actual_bytes / 1024 / 1024 / 1024",
          "legendFormat": "{{domain}}"
        }
      ]
    },
    {
      "title": "VM磁盘IOPS",
      "type": "graph",
      "targets": [
        {
          "expr": "rate(libvirt_domain_block_stats_read_requests_total[1m])",
          "legendFormat": "{{domain}} read"
        },
        {
          "expr": "rate(libvirt_domain_block_stats_write_requests_total[1m])",
          "legendFormat": "{{domain}} write"
        }
      ]
    }
  ]
}

 

5.3 备份与恢复

虚拟机备份策略

 

#!/bin/bash
# vm-backup.sh - 虚拟机完整备份脚本

VM_NAME=$1
BACKUP_DIR="/backup/vms/$(date +%Y%m%d)"
mkdir -p ${BACKUP_DIR}

# 方法1:关机备份(最可靠)
virsh shutdown ${VM_NAME}
sleep 30

# 备份磁盘
cp /data/libvirt/images/${VM_NAME}.qcow2 ${BACKUP_DIR}/

# 备份配置
virsh dumpxml ${VM_NAME} > ${BACKUP_DIR}/${VM_NAME}.xml

virsh start ${VM_NAME}

# 方法2:在线快照备份
# 创建外部快照
virsh snapshot-create-as ${VM_NAME} backup-snap 
  --disk-only 
  --atomic 
  --diskspec vda,snapshot=external,file=${BACKUP_DIR}/${VM_NAME}-snap.qcow2

# 备份原始磁盘(此时已变为只读backing file)
cp /data/libvirt/images/${VM_NAME}.qcow2 ${BACKUP_DIR}/${VM_NAME}-backup.qcow2

# 合并快照(块提交)
virsh blockcommit ${VM_NAME} vda 
  --active 
  --pivot 
  --verbose

# 清理快照文件
rm ${BACKUP_DIR}/${VM_NAME}-snap.qcow2

 

增量备份(使用dirty bitmap)

 

# 启用脏页追踪(QEMU 4.0+)
virsh qemu-monitor-command ${VM_NAME} --pretty 
  '{"execute": "block-dirty-bitmap-add", "arguments": {"node": "drive-virtio-disk0", "name": "backup-bitmap"}}'

# 执行增量备份
virsh qemu-monitor-command ${VM_NAME} --pretty 
  '{"execute": "drive-backup", "arguments": {"device": "drive-virtio-disk0", "sync": "incremental", "bitmap": "backup-bitmap", "target": "/backup/vms/vm-incr.qcow2", "format": "qcow2"}}'

 

恢复虚拟机

 

# 从备份恢复
# 1. 复制磁盘镜像
cp /backup/vms/20250109/vm-name.qcow2 /data/libvirt/images/

# 2. 恢复配置
virsh define /backup/vms/20250109/vm-name.xml

# 3. 启动虚拟机
virsh start vm-name

# 快照回滚
# 查看快照列表
virsh snapshot-list vm-name

# 回滚到指定快照
virsh snapshot-revert vm-name snapshot-name

# 删除快照
virsh snapshot-delete vm-name snapshot-name

 

六、总结

6.1 技术要点回顾

KVM作为Linux内核原生的虚拟化技术,具备高性能、开源免费、生态丰富的优势,是构建企业级私有云的理想选择。核心技术栈包括:

KVM内核模块提供CPU和内存虚拟化

QEMU提供设备模拟和虚拟机管理

libvirt提供统一的管理API和工具

virtio提供高性能的半虚拟化I/O

生产环境部署要点:

CPU使用host-passthrough模式最大化性能

存储使用virtio-blk/scsi配合cache=none确保数据安全

网络使用virtio-net配合vhost-net或SR-IOV获得接近原生性能

大页内存和NUMA绑定用于性能敏感场景

共享存储是实现热迁移和高可用的前提

运维管理要点:

制定合理的资源超分比例(CPU 3:1,内存 1.5:1为参考值)

建立完善的备份恢复机制

监控关键指标,设置告警阈值

定期进行灾难恢复演练

6.2 进阶学习方向

容器化管理平台

学习Proxmox VE、oVirt等开源虚拟化管理平台,它们提供了Web界面、用户权限管理、资源配额等企业级功能,比直接使用libvirt更适合生产环境。

OpenStack私有云

OpenStack是更大规模私有云的选择,提供了计算(Nova)、网络(Neutron)、存储(Cinder/Swift)、镜像(Glance)等完整的云服务组件。学习OpenStack可以理解云平台的完整架构。

软件定义网络

深入学习Open vSwitch和Linux网络虚拟化技术,掌握VXLAN、GRE等overlay网络实现,理解SDN控制器如何管理虚拟网络。

分布式存储

学习Ceph分布式存储系统,掌握RBD块存储与KVM的集成,实现存储的高可用和弹性扩展。

6.3 参考资料

KVM官方网站:https://www.linux-kvm.org/

libvirt官方文档:https://libvirt.org/docs.html

QEMU文档:https://www.qemu.org/docs/master/

Red Hat虚拟化文档:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/configuring_and_managing_virtualization/

Proxmox VE:https://pve.proxmox.com/wiki/Main_Page

oVirt项目:https://www.ovirt.org/documentation/

附录

A. 命令速查表

操作 命令
列出所有VM virsh list --all
启动VM virsh start
关闭VM virsh shutdown
强制关机 virsh destroy
重启VM virsh reboot
暂停VM virsh suspend
恢复VM virsh resume
删除VM virsh undefine
查看VM信息 virsh dominfo
查看VM配置 virsh dumpxml
编辑VM配置 virsh edit
连接控制台 virsh console
查看VNC端口 virsh vncdisplay
创建快照 virsh snapshot-create-as
恢复快照 virsh snapshot-revert
热迁移 virsh migrate --live qemu+ssh://host/system
查看网络 virsh net-list --all
查看存储池 virsh pool-list --all
查看块设备 virsh domblklist
查看网卡 virsh domiflist
查看IP地址 virsh domifaddr

B. 配置参数详解

libvirt domain XML核心元素

元素 说明 示例值
虚拟机名称 production-vm
最大内存 16
vCPU数量 8
CPU模式 host-passthrough / host-model / custom
虚拟化类型 hvm(全虚拟化)
磁盘类型 file / block / network
缓存模式 none / writeback / writethrough
网络类型 bridge / network / direct
图形类型 vnc / spice
通道设备 qemu-ga / spice-vdagent

qemu-img常用命令

操作 命令
创建磁盘 qemu-img create -f qcow2 disk.qcow2 50G
查看信息 qemu-img info disk.qcow2
格式转换 qemu-img convert -f raw -O qcow2 disk.raw disk.qcow2
压缩镜像 qemu-img convert -O qcow2 -c in.qcow2 out.qcow2
调整大小 qemu-img resize disk.qcow2 +10G
创建快照 qemu-img snapshot -c snap1 disk.qcow2
基于backing创建 qemu-img create -f qcow2 -b base.qcow2 new.qcow2
提交更改 qemu-img commit overlay.qcow2
检查一致性 qemu-img check disk.qcow2

C. 术语表

术语 英文 说明
宿主机 Host 运行虚拟机的物理服务器
虚拟机 Guest/VM 在宿主机上运行的虚拟化实例
全虚拟化 Full Virtualization Guest OS无需修改即可运行
半虚拟化 Para-virtualization Guest使用特殊驱动与Host通信
硬件辅助虚拟化 Hardware-assisted 使用CPU VT-x/AMD-V扩展
直通 Passthrough 将物理设备直接分配给虚拟机
超分 Overcommit 分配的虚拟资源超过物理资源
热迁移 Live Migration 不停机迁移运行中的虚拟机
快照 Snapshot 保存虚拟机某一时刻的状态
存储池 Storage Pool libvirt管理的存储资源集合
NUMA Non-Uniform Memory Access 非一致性内存访问架构
KSM Kernel Same-page Merging 内核相同页合并技术
大页 Huge Pages 使用更大的内存页减少TLB miss
virtio Virtual I/O 高性能半虚拟化I/O框架
vhost Virtual Host 内核态virtio后端加速
SR-IOV Single Root I/O Virtualization 单根I/O虚拟化技术

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分