在双路物理CPU机器上安装Ubuntu并部署KVM以实现系统多开,并追求性能最优,需要从硬件、宿主机系统、KVM配置、虚拟机配置等多个层面进行优化。
以下是详细的操作指南和优化建议:
阶段一:BIOS/UEFI 设置优化 (重启进入)
-
启用虚拟化技术:
-
Intel CPU: Intel VT-x (Virtualization Technology)
-
AMD CPU: AMD-V (SVM - Secure Virtual Machine)
-
通常在 CPU Configuration 或 Advanced Settings 中。
-
-
启用 IOMMU (Input/Output Memory Management Unit):
-
Intel CPU: Intel VT-d (Virtualization Technology for Directed I/O)
-
AMD CPU: AMD-Vi
-
这对于PCI设备直通 (passthrough) 非常重要,能显著提升某些VM的I/O性能。
-
-
禁用不必要的设备:
-
如果某些板载设备(如串口、并口、不用的声卡)VM用不到,可以在BIOS中禁用,以释放中断资源。
-
-
内存设置:
-
确保内存运行在支持的最高频率。
-
如果支持,启用NUMA (Non-Uniform Memory Access)。双路CPU几乎必然是NUMA架构。
-
-
电源管理:
-
将电源管理配置文件设置为 "高性能" (High Performance) 或类似选项。避免节能模式降低CPU频率。
-
禁用C-states (CPU idle states) 或者使用 intel_idle.max_cstate=0 或 processor.max_cstate=0 内核参数(后续宿主机优化中会提到),以减少CPU唤醒延迟,但会增加功耗。需要权衡。
-
阶段二:Ubuntu Server 安装
-
选择最新LTS版本: 推荐使用最新的Ubuntu Server LTS版本(如22.04 LTS),以获得较新的内核和KVM/QEMU版本,通常包含性能改进和新特性。
-
最小化安装: 选择 "Minimal installation" 或只安装必要的核心组件,避免不必要的软件包和服务消耗资源。
-
磁盘分区:
-
OS盘: 建议使用SSD,分配足够的空间给 / (根目录) 和 /boot。
-
VM存储盘:
-
高性能方案: 使用高速NVMe SSD或SSD RAID阵列。
-
大容量方案: 可以使用HDD RAID,但性能会远低于SSD。
-
分区策略:
-
LVM (Logical Volume Manager): 推荐使用LVM管理VM存储,方便动态调整、快照等。在LVM上创建逻辑卷来存放VM镜像。
-
单独分区: 也可以直接使用单独的分区(如 /var/lib/libvirt/images 挂载到独立的高速磁盘分区)。
-
-
-
Swap分区: 如果物理内存充足(例如64GB+),可以设置较小的Swap(如4-8GB)或不设置,依赖物理内存。如果内存可能紧张,适当设置Swap。
-
阶段三:KVM及相关工具安装
sudo apt update
sudo apt upgrade -y
# 安装KVM及管理工具
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virt-manager cpu-checker
# 检查KVM是否可用
sudo kvm-ok
# 输出应包含 "KVM acceleration can be used"
# 将当前用户添加到libvirt和kvm组,以便无需sudo管理VM
sudo adduser $(whoami) libvirt
sudo adduser $(whoami) kvm
# 注意:需要重新登录或重启使组更改生效
# 启动并设置libvirtd服务开机自启
sudo systemctl enable --now libvirtd
sudo systemctl status libvirtd
content_copydownload
Use code with caution.Bash
阶段四:宿主机系统性能优化
-
CPU调速器 (CPU Governor):
-
将其设置为 performance 模式,让CPU以最高频率运行。
sudo apt install cpufrequtils -y echo 'GOVERNOR="performance"' | sudo tee /etc/default/cpufrequtils sudo systemctl disable ondemand # 如果存在 sudo systemctl restart cpufrequtils # 或重启系统 # 验证 cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
content_copydownload
Use code with caution.Bash -
-
NUMA优化: 双路CPU系统是NUMA架构,优化NUMA至关重要。
-
安装NUMA工具:
sudo apt install numactl -y
content_copydownload
Use code with caution.Bash -
查看NUMA拓扑:
numactl --hardware lscpu | grep NUMA
content_copydownload
Use code with caution.Bash -
绑定服务到NUMA节点: 尽量将libvirtd服务和相关的qemu-system-*进程绑定到特定的NUMA节点,或者至少让它们均匀分布。通常libvirtd自身不需要严格绑定,但它启动的QEMU进程(即VM)需要。
-
IRQ平衡: 确保irqbalance服务运行,它会尝试将硬件中断分配到不同的CPU核心,避免单核瓶颈。
sudo systemctl enable --now irqbalance
content_copydownload
Use code with caution.Bash对于高性能网络和存储,有时需要手动调整IRQ亲和性,将特定设备的IRQ绑定到VM vCPU所在的NUMA节点的CPU核心上。
-
-
内核参数优化 (GRUB):
-
编辑 /etc/default/grub 文件,修改 GRUB_CMDLINE_LINUX_DEFAULT 行。
-
常用参数:
-
intel_iommu=on 或 amd_iommu=on (如果BIOS中已启用,这里可以再次确认或强制启用,对PCI直通重要)
-
isolcpus=<cpu_list>: 隔离部分CPU核心专门给VM使用,宿主机不调度普通进程到这些核心。需要仔细规划,例如将某些核心完全留给特定高性能VM。
-
nohz_full=<cpu_list>: 针对isolcpus指定的CPU核心禁用内核时钟滴答,减少VM抖动。
-
rcu_nocbs=<cpu_list>: 减少RCU回调对隔离CPU的干扰。
-
transparent_hugepage=never 或 transparent_hugepage=madvise:
-
never: 完全禁用透明大页,手动为VM配置静态大页 (HugePages) 性能更好。
-
madvise: 仅在应用程序通过madvise()请求时使用THP,是一个折中。
-
对于KVM,如果打算使用静态HugePages,则应禁用THP。
-
-
elevator=noop 或 elevator=none (对于SSD/NVMe): 设置I/O调度器为 noop (或 none for NVMe),因为SSD有自己的内部调度逻辑。
-
也可以通过udev规则设置: echo noop > /sys/block/sdX/queue/scheduler
-
-
-
示例:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on transparent_hugepage=never elevator=none" -
更新GRUB后生效:
sudo update-grub sudo reboot
content_copydownload
Use code with caution.Bash
-
-
HugePages (静态大页):
-
减少TLB (Translation Lookaside Buffer) miss,提高内存密集型应用性能。
-
VM内存应配置为使用HugePages。
-
计算所需大页数量: (VM总内存 / HugePage大小)。常见HugePage大小为2MB或1GB。
# 查看支持的HugePage大小 cat /proc/meminfo | grep Hugepagesize # 假设Hugepagesize: 2048 kB (2MB) # 如果要给VM分配32GB内存,需要 32 * 1024 / 2 = 16384 个2MB大页 # 预留 (在 /etc/sysctl.conf 或 .conf 文件中) # sudo sysctl -w vm.nr_hugepages=16384 # 或在启动时通过内核参数:hugepages=16384 # 永久生效: echo "vm.nr_hugepages=16384" | sudo tee -a /etc/sysctl.conf sudo sysctl -p
content_copydownload
Use code with caution.Bash -
确保在VM的XML配置中启用HugePages。
-
-
网络优化:
-
使用桥接网络 (Bridged Networking): virsh net-define, virsh net-start, virsh net-autostart 或使用 virt-manager 创建。桥接提供接近物理网络的性能,VM像独立主机一样在局域网中。
-
vhost-net: 确保启用。KVM默认会使用vhost-net,它将网络包处理移到内核空间,减少上下文切换,提高性能。
lsmod | grep vhost_net # 应该能看到模块加载
content_copydownload
Use code with caution.Bash -
SR-IOV (Single Root I/O Virtualization): 如果网卡和主板支持,这是网络性能的极致。它允许物理网卡虚拟出多个VF (Virtual Function),直接分配给VM,VM拥有近乎独占的网卡硬件资源。配置较复杂。
-
阶段五:虚拟机 (VM) 创建与优化
使用 virt-manager (图形化) 或 virsh (命令行) 创建和管理VM。以下是优化点,主要通过编辑VM的XML配置文件 (virsh edit <vm_name>) 实现。
-
CPU配置 (<vcpu>, <cputune>):
-
CPU模式 (<cpu mode='...' ...>):
-
host-passthrough: 将宿主机CPU特性完整透传给VM,通常性能最好,但VM迁移可能受限于目标主机的CPU型号。
-
host-model: 模拟宿主机CPU型号,提供较好的性能和一定的迁移兼容性。
-
避免使用通用CPU型号 (如 qemu64, kvm64),除非为了最大化迁移兼容性。
-
-
vCPU数量 (<vcpu placement='static' current='X'>X</vcpu>): 按需分配,不要过度分配。current属性设为与最大vcpu数一致。
-
CPU钉扎/亲和性 (<vcpupin>):
-
关键优化! 将VM的vCPU绑定到宿主机的特定物理核心上,特别是绑定到同一NUMA节点的核心上。
-
避免VM的vCPU在不同NUMA节点的物理核心间迁移,这会导致严重的性能下降。
-
示例 (假设VM有2个vCPU,要绑定到物理CPU 0和1):
<cputune> <vcpupin vcpu="0" cpuset="0"/> <vcpupin vcpu="1" cpuset="1"/> <!-- 如果有更多vCPU和物理核心,继续添加 --> </cputune>
content_copydownload
Use code with caution.Xml
-
-
NUMA感知 (<numatune>):
-
将VM的内存也分配到其vCPU所在的NUMA节点上。
-
示例 (VM内存分配到宿主机NUMA节点0):
<numatune> <memory mode="strict" nodeset="0"/> <!-- 如果VM本身也模拟NUMA,则需要更复杂的配置 --> </numatune>
content_copydownload
Use code with caution.Xml -
如果VM本身也需要模拟NUMA架构(例如,大型数据库VM),则需要更细致的配置,将VM的虚拟NUMA节点映射到宿主机的物理NUMA节点。
<cpu ...> <numa> <cell id='0' cpus='0-1' memory='2048' unit='MiB'/> <!-- VM的NUMA节点0用vCPU 0-1,2GB内存 --> <!-- ... --> </numa> </cpu> <numatune> <memnode cellid='0' mode='strict' nodeset='0'/> <!-- VM节点0的内存来自宿主机节点0 --> </numatune>
content_copydownload
Use code with caution.Xml
-
-
-
内存配置 (<memory>, <memoryBacking>):
-
分配大小: 按需分配。
-
HugePages:
<memoryBacking> <hugepages/> </memoryBacking>
content_copydownload
Use code with caution.Xml确保宿主机已配置足够的HugePages。
-
内存锁定 (<locked/>): 防止VM内存被交换到磁盘。
<memoryBacking> <hugepages/> <locked/> </memoryBacking>
content_copydownload
Use code with caution.Xml
-
-
磁盘I/O优化 (<disk>):
-
磁盘总线 (<disk type='file' device='disk'> <driver name='qemu' type='...' cache='...' io='...'/> ... </disk>):
-
virtio-blk: 传统的半虚拟化块设备,性能不错。
-
virtio-scsi: 更现代,支持更多SCSI特性(如TRIM/UNMAP),通常推荐用于SSD。需要 <controller type='scsi' model='virtio-scsi'/>。
-
-
镜像格式 (type):
-
raw: 性能最好,无额外开销,但不支持快照、动态扩展等特性。
-
qcow2: 功能丰富(快照、写时复制、压缩、加密),但有性能开销。
-
优化qcow2:
-
preallocation=metadata 或 preallocation=falloc (创建时预分配,减少碎片)。
-
lazy_refcounts=on (新版本qemu)。
-
-
-
-
缓存模式 (cache):
-
none: 宿主机不缓存,VM直接访问存储,适合VM内部有良好缓存机制或数据库等应用。通常是SSD的最佳选择。
-
writethrough: 写操作同时写入宿主机缓存和物理磁盘,数据安全,但写入慢。
-
writeback: 写操作先写入宿主机缓存,后异步写入物理磁盘,写入快,但宿主机崩溃可能丢数据。
-
directsync: 类似none,但使用O_DIRECT | O_SYNC。
-
unsafe: 仅用于测试,完全依赖宿主机缓存,不保证数据一致性。
-
-
I/O模式 (io):
-
native: 使用Linux AIO (Asynchronous I/O),通常是最佳性能选择。
-
threads: 使用QEMU用户空间的线程池处理I/O。
-
-
I/O线程 (<iothreads>X</iothreads>, <iothreadids>):
-
为VM分配专用的I/O处理线程,减少主QEMU线程的I/O压力。
-
示例 (分配1个iothread):
<iothreads>1</iothreads> ... <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none' io='native'/> <source file='/path/to/vm.qcow2'/> <target dev='vda' bus='virtio'/> <iotune> <!-- 可选,精细控制 --> <total_bytes_sec>...</total_bytes_sec> <total_iops_sec>...</total_iops_sec> </iotune> <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> <iothread_ids> <!-- 仅virtio-scsi支持绑定到特定iothread --> <iothread id="1"/> </iothread_ids> </disk>
content_copydownload
Use code with caution.Xml -
对于virtio-blk,可以通过 driver ... queue_size=N 调整队列深度,并结合 <blkiotune> 进行IO限速。
-
-
块大小 (<blockio logical_block_size='512' physical_block_size='4096'/>): 如果底层物理磁盘是4K扇区 (Advanced Format),对齐VM的块大小可以提高性能。
-
-
网络I/O优化 (<interface>):
-
设备模型 (<model type='virtio'/>): 始终使用 virtio (virtio-net),这是半虚拟化网卡,性能远超模拟的 e1000 或 rtl8139。
-
多队列Virtio-net (queues='N'):
-
允许VM有多个收发队列,每个队列可以由不同的vCPU处理,提高网络吞吐和并发。
-
N 通常设置为VM的vCPU数量,但不超过网卡物理队列数(如果是SR-IOV)或宿主机支持的队列数。
-
示例:
<interface type='bridge'> <source bridge='br0'/> <model type='virtio'/> <driver name='vhost' queues='4'/> <!-- 假设VM有4个vCPU --> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface>
content_copydownload
Use code with caution.Xml
-
-
SR-IOV (如前所述): 如果硬件支持,配置 <interface type='hostdev' managed='yes'> 并指定PF的VF。
-
-
显卡 (<video>):
-
对于服务器VM,通常不需要强大的图形性能。使用 virtio 显卡模型,或 none (如果通过串行控制台管理)。
-
<model type='virtio' heads='1' primary='yes'/>
-
如果完全不需要图形界面,可以移除<graphics>和<video>部分,仅保留<console>。
-
阶段六:虚拟机内部 (Guest OS) 优化
-
安装Virtio驱动: 现代Linux发行版通常自带Virtio驱动。Windows VM需要手动安装Virtio驱动 (从Fedora项目下载ISO)。
-
Guest OS调优:
-
关闭不必要的服务。
-
I/O调度器: 对于virtio-blk或virtio-scsi设备,在VM内部也建议使用 noop 或 none (NVMe) 或 mq-deadline (新内核)。
# 在VM内部执行 echo 'noop' > /sys/block/vda/queue/scheduler # 假设VM磁盘是vda
content_copydownload
Use code with caution.Bash -
网络参数: 调整TCP/IP栈参数,如增大缓冲区等,根据应用类型而定。
-
时间同步: 确保VM时间与宿主机同步,KVM通常会自动处理,但检查一下没坏处 (chrony 或 systemd-timesyncd)。
-
阶段七:持续监控与调整
-
宿主机监控:
-
top, htop (查看CPU、内存占用)
-
vmstat, iostat, sar (系统活动、I/O统计)
-
numastat -m <qemu_pid> (查看VM在NUMA节点间的内存分布)
-
perf top -p <qemu_pid> (分析VM进程的热点函数)
-
virsh domstats <vm_name> (获取VM的各种统计信息)
-
virt-top (类似top,但针对VM)
-
-
VM内部监控: 使用VM内部的监控工具。
-
基准测试: 在优化前后进行基准测试(如 fio for disk I/O, iperf for network, sysbench for CPU/memory),量化优化效果。
-
迭代优化: 性能优化是一个持续的过程。根据监控结果和应用需求,不断调整配置。
重要注意事项:
-
** workload特性:** 不同的VM应用(如Web服务器、数据库、计算密集型任务)对资源的需求和瓶颈点不同,优化策略应有所侧重。
-
稳定性优先: 不要为了极致性能而牺牲稳定性。某些激进的优化可能导致系统不稳定。
-
逐步调整: 每次只修改一个或少数几个相关参数,测试效果,避免一次性改动过多难以定位问题。
-
备份: 在进行重大配置更改前,备份宿主机和VM的重要数据及配置文件。
-
文档: 记录你的优化步骤和参数,方便后续维护和问题排查。
对于双路CPU,NUMA亲和性 (CPU和内存绑定到同一NUMA节点) 是最关键的优化点之一。其次是使用Virtio驱动和设备,然后是磁盘I/O (缓存模式、I/O模式、镜像格式) 和网络I/O (多队列、vhost-net)。HugePages对内存密集型应用也非常有益。
遵循这些步骤,你的KVM环境应该能达到相当高的性能水平。祝你成功!