尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

手把手教你用QEMU-KVM命令行创建虚拟机并配置桥接网络

手把手教你用QEMU-KVM命令行创建虚拟机并配置桥接网络 1. 项目概述为什么选择QEMU-KVM与桥接网络在服务器虚拟化和个人开发环境搭建的领域里我们有很多选择比如VMware Workstation、VirtualBox或者云服务商提供的各种托管方案。但如果你追求的是极致的性能、对硬件资源的完全掌控以及深入理解虚拟化技术的底层运作那么直接使用QEMU配合KVMKernel-based Virtual Machine内核模块无疑是一条“硬核”但回报丰厚的路径。这次要聊的就是用qemu-system-x86_64这个命令行工具手动创建一台KVM虚拟机并为其配置桥接网络让虚拟机像一台物理机一样直接“插”在你的局域网里。简单来说qemu-system-x86_64是QEMU项目里针对x86_64架构的完整系统模拟器。它本身可以模拟CPU、内存、各种外设但模拟意味着性能损耗。而KVM是Linux内核的一个模块它允许QEMU利用CPU的硬件虚拟化扩展Intel VT-x或AMD-V将大部分CPU和内存的指令直接交由硬件执行从而获得近乎原生Native的性能。所以我们常说的“QEMU-KVM”其实是QEMU作为设备模拟和管理前端KVM作为高性能的加速后端两者珠联璧合。那么为什么要费这么大劲用命令行而不是点几下鼠标就用图形化工具搞定呢首先极致轻量。没有图形化管理界面的开销资源占用极低特别适合在无图形界面的服务器上部署。其次高度可定制。从CPU拓扑、内存大页、磁盘总线类型到虚拟网卡型号每一个参数你都能精确控制这对于性能调优和特定场景测试至关重要。最后学习价值。这个过程能让你透彻理解虚拟机的生命周期、虚拟设备的挂载原理以及Linux网络栈中桥接、网卡、Tap设备是如何协同工作的。当你下次遇到云主机网络问题时底层的知识会让你排查起来更有底气。配置桥接网络则是为了让虚拟机获得与宿主机同等的网络地位。在默认的NAT模式下虚拟机通过宿主机“上网”外部网络无法直接访问虚拟机。而桥接模式下虚拟机的虚拟网卡会通过一个“桥”bridge连接到你的物理网络它会被分配一个和宿主机同网段的IP地址就像一台新接入局域网的电脑。这对于需要对外提供服务如Web服务器、需要与其他物理设备通信如智能家居设备或者进行网络测试的场景是必不可少的。接下来我会带你从零开始手把手走通整个流程。我会假设你在一台安装了Linux发行版如Ubuntu 22.04、CentOS Stream 9或Rocky Linux 9的机器上操作并拥有root或sudo权限。过程中遇到的坑和技巧都是我在多次部署中实实在在踩过和总结的。2. 环境准备与核心组件解析在动手敲命令之前我们必须把地基打牢。这一部分我们来彻底搞清楚需要哪些软件以及它们各自扮演什么角色。很多人安装失败或者网络不通问题往往就出在环境准备不充分上。2.1 宿主机系统与硬件要求你的宿主机操作系统必须是Linux因为KVM是Linux内核的特性。主流的发行版都可以我个人更推荐使用像Ubuntu Server LTS、Rocky Linux、AlmaLinux这类企业级或长期支持的版本它们的软件包更新和社区支持更稳定。硬件方面有三个硬性检查点CPU虚拟化支持这是KVM工作的基础。你需要确认你的CPU是Intel支持VT-x或AMD支持AMD-V的并且该功能在BIOS/UEFI中已经启用。# 检查CPU是否支持硬件虚拟化 grep -E ‘(vmx|svm)’ /proc/cpuinfo如果命令有输出vmx对应Intelsvm对应AMD则说明支持。如果没有输出你需要重启进入BIOS在“Advanced”或“Security”设置里找到“Virtualization Technology”或类似选项并启用它。64位系统因为我们要创建的是x86_64架构的虚拟机所以宿主机也必须是64位系统。uname -m输出应为x86_64或aarch64如果是ARM架构则需使用qemu-system-aarch64这是另一个话题了。内核模块确保当前运行的内核包含了KVM模块。现代Linux发行版的内核通常都已编译进去。lsmod | grep kvm你应该能看到kvm_intel或kvm_amd以及kvm模块。如果没有可能需要安装linux-modules-extra包或重新编译内核但这在标准安装中极少见。2.2 核心软件包安装我们需要安装三组软件包QEMU、KVM管理工具以及网络桥接工具。# 对于基于Debian/Ubuntu的系统 sudo apt update sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager # 对于基于RHEL/Rocky/AlmaLinux/CentOS Stream的系统 sudo dnf update sudo dnf install -y qemu-kvm libvirt virt-install virt-viewer bridge-utils virt-manager我来解释一下每个包的作用qemu-kvm: 这是核心包提供了qemu-system-x86_64二进制文件以及与KVM加速整合的组件。libvirt: 这是一个管理虚拟化平台的工具包包含守护进程libvirtd和客户端API。它本身不是必须的但很多高级工具如virt-manager依赖它而且它提供了更便捷的虚拟机生命周期管理。我们虽然用命令行启动但安装它有利于环境完整。virt-install: 一个用于从命令行创建虚拟机的强大工具。它本质上是一个封装了复杂qemu命令的脚本。但请注意我们这篇文章的核心是直接使用qemu-system-x86_64所以不会用它。安装它只是为了环境兼容有时其他组件依赖它。bridge-utils: 提供了管理网络桥接设备的传统工具brctl。虽然现在更推荐用ip命令但有些脚本或教程仍会用到它装上备用。virt-manager: 一个图形化管理工具。在无图形界面的服务器上可以不装。在桌面环境装上它可以用来验证KVM是否正常工作或者作为备用管理手段。安装完成后建议将当前用户加入libvirt和kvm组以便无需root权限就能管理虚拟机这在进行日常操作时更方便安全sudo usermod -aG libvirt,kvm $USER注意你需要注销并重新登录或者开启一个新的shell会话这个组权限变更才会生效。你可以用groups命令来确认是否已加入。2.3 网络桥接原理浅析这是理解后续操作的关键。在典型的Linux系统中你的物理网卡比如enp3s0或eth0直接配置了IP地址用于与外界通信。当我们创建桥接网络时我们会建立一个虚拟的网络桥接设备比如br0。你可以把它想象成一个虚拟的网络交换机。然后我们将物理网卡“接入”这个交换机也就是让物理网卡成为桥接设备的一个“端口”port这个过程会清空物理网卡自身的IP配置。最后虚拟机的虚拟网卡在宿主机端表现为一个tap设备也“接入”这个交换机。这样数据流的路径就变成了虚拟机 -tap设备 -br0虚拟交换机- 物理网卡 - 外部网络。对于局域网内的其他设备而言虚拟机就是一台拥有独立MAC和IP地址的普通设备。重要提示配置桥接网络会暂时中断你宿主机通过该物理网卡进行的网络连接。因此强烈建议在本地控制台非SSH连接进行操作或者你有另一块网卡/另一种连接方式如Wi-Fi作为备用。如果只有单网卡且通过SSH连接错误的配置可能导致你失去连接。3. 配置宿主机桥接网络理论清楚了现在开始实战。我们将分步在宿主机上创建一个持久的桥接网络。这里我演示两种主流方法使用NetplanUbuntu 22.04及以后、部分新版本Debian和使用NetworkManager/network-scriptsRHEL系列传统方式。请根据你的系统选择。3.1 方法一在Ubuntu/Debian (使用Netplan)上配置Netplan是Ubuntu引入的新的网络配置工具使用YAML文件进行配置清晰易读。备份原配置首先找到你当前的Netplan配置文件通常在/etc/netplan/目录下文件名可能是00-installer-config.yaml或01-netcfg.yaml。cd /etc/netplan ls -la sudo cp 你的配置文件.yaml 你的配置文件.yaml.backup编辑配置文件使用文本编辑器如vim或nano打开该文件。假设你的物理网卡名是enp3s0请用ip link命令确认你的实际网卡名。sudo vim /etc/netplan/01-netcfg.yaml将内容修改为如下所示注意YAML的缩进非常严格必须使用空格不要用Tabnetwork: version: 2 ethernets: enp3s0: # 你的物理网卡名称 dhcp4: no # 禁用物理网卡自身的DHCP optional: true bridges: br0: # 桥接设备名称 interfaces: [enp3s0] # 将物理网卡加入桥接 dhcp4: yes # 让桥接设备通过DHCP获取IP # 如果你需要静态IP请使用以下配置代替 dhcp4: yes # addresses: # - 192.168.1.100/24 # 你的静态IP和子网掩码 # gateway4: 192.168.1.1 # 你的网关 # nameservers: # addresses: [8.8.8.8, 1.1.1.1] # DNS服务器 parameters: stp: false # 对于简单网络可以关闭生成树协议以加快收敛 forward-delay: 0 optional: true关键点ethernets:部分下你的物理网卡配置被简化为仅声明dhcp4: no意味着它不再直接持有IP地址变成一个纯粹的“端口”。bridges:部分下我们定义了br0并通过interfaces:列表将物理网卡enp3s0关联到桥上。IP地址无论是DHCP还是静态现在配置在br0上而不是enp3s0上。应用配置sudo netplan apply如果配置有语法错误netplan apply会报错。如果应用成功你的网络会短暂中断然后恢复。现在运行ip addr show你应该看到br0设备拥有了IP地址而enp3s0设备没有IP地址。3.2 方法二在RHEL/Rocky/CentOS (使用NetworkManager)上配置在RHEL 8/9及衍生版中推荐使用nmcliNetworkManager的命令行工具来管理连接它比直接写ifcfg文件更可靠。创建桥接连接sudo nmcli connection add type bridge con-name br0 ifname br0这创建了一个名为“br0”的桥接连接对应的设备名也是br0。为桥接配置IP这里以DHCP为例sudo nmcli connection modify br0 ipv4.method auto # 启用DHCP # 如果需要静态IP请使用 # sudo nmcli connection modify br0 ipv4.method manual ipv4.addresses 192.168.1.100/24 ipv4.gateway 192.168.1.1 ipv4.dns “8.8.8.8”将物理网卡加入桥接假设你的物理网卡连接名是Wired connection 1可以通过nmcli connection show查看设备名是enp3s0。# 首先找到你的物理网卡对应的连接名 nmcli connection show # 假设连接名是 “有线连接 1” 或 “enp3s0” sudo nmcli connection modify “有线连接 1” master br0 slave-type bridge # 或者直接使用设备名对应的连接 # sudo nmcli connection modify enp3s0 master br0 slave-type bridge这个操作会修改物理网卡的连接配置将其设置为桥接br0的一个端口slave。激活连接并重启网络sudo nmcli connection up br0 sudo nmcli connection up “有线连接 1” # 或你的物理网卡连接名同样使用ip addr show检查br0是否获得了IP。3.3 验证桥接配置无论用哪种方法配置完成后请务必验证ip addr show br0 # 应该显示 br0 有 inet (IPv4) 地址 bridge link show # 或使用老命令 brctl show brctl showbridge link show或brctl show的输出中你应该能看到你的物理网卡如enp3s0被列为br0的一个端口。这证明桥接已经成功建立。4. 准备虚拟机磁盘与安装介质网络搞定接下来准备虚拟机的“硬盘”和“安装光盘”。我们将完全使用命令行工具完成。4.1 创建虚拟磁盘镜像虚拟机的磁盘在宿主机上就是一个文件。QEMU支持多种镜像格式最常用的是QCOW2 (QEMU Copy On Write)。它的优点是支持快照、动态增长只用多少占多少物理空间、压缩和加密是生产环境的首选。我们使用qemu-img命令来创建磁盘镜像。假设我们为虚拟机创建一个名为myvm.qcow2、容量为20GB的磁盘qemu-img create -f qcow2 /var/lib/libvirt/images/myvm.qcow2 20G-f qcow2: 指定格式为QCOW2。/var/lib/libvirt/images/: 这是libvirt默认存放镜像的目录权限设置通常比较合理。你也可以放在其他位置比如你的家目录下但要确保QEMU进程有读写权限。20G: 磁盘容量。这里的“G”是GB。你也可以用“M”表示MB。执行后用ls -lh查看你会发现文件实际大小很小几百KB因为它是一个稀疏文件只有在写入数据时才会真正占用物理空间。实操心得对于性能要求极高的场景如数据库可以考虑使用raw格式-f raw或直接使用物理磁盘分区/LVM逻辑卷。Raw格式性能损耗最小但缺乏QCOW2的高级功能。另一个折衷方案是使用-o preallocationmetadata选项创建QCOW2镜像它不会预分配全部空间但会预先分配元数据能在一定程度上改善性能。4.2 获取操作系统安装镜像你需要下载你想要安装的操作系统的ISO镜像文件。例如Ubuntu Server: 从 Ubuntu 官网下载。Rocky Linux: 从 Rocky Linux 官网下载。Windows: 从 Microsoft 官网下载需要授权。将下载好的ISO文件放在一个方便的路径例如/var/lib/libvirt/images/iso/目录下。记得检查文件的读写权限。5. 使用qemu-system-x86_64命令行启动安装这是最核心的部分。我们将拼装一个完整的qemu-system-x86_64命令来启动虚拟机并开始安装操作系统。这个命令参数较多我们分段解释。5.1 基础启动命令结构一个最基础的启动命令框架如下sudo qemu-system-x86_64 \ -enable-kvm \ -name “MyFirstKVMVM” \ -cpu host \ -smp 2 \ -m 4096 \ -drive file/var/lib/libvirt/images/myvm.qcow2,formatqcow2 \ -cdrom /var/lib/libvirt/images/iso/ubuntu-22.04.3-live-server-amd64.iso \ -boot orderdc \ -netdev bridge,brbr0,idnet0 \ -device virtio-net-pci,netdevnet0,mac52:54:00:12:34:56 \ -vga qxl \ -display spice-app让我们逐一拆解这些参数-enable-kvm:最关键的参数启用KVM硬件加速。没有它QEMU将进行纯软件模拟速度极慢。-name “MyFirstKVMVM”: 为虚拟机设置一个名称方便标识。-cpu host: 向虚拟机暴露宿主机CPU的所有特性获得最佳性能和兼容性。你也可以用-cpu host,migratableoff来暴露更多特性但可能影响迁移。-smp 2: 为虚拟机分配2个虚拟CPU核心。根据宿主机资源情况调整。-m 4096: 为虚拟机分配4096MB4GB内存。-drive file…: 指定虚拟机的硬盘镜像文件路径和格式。-cdrom …: 指定安装介质的ISO文件路径。这相当于给虚拟机插了一张光盘。-boot orderdc: 设置启动顺序。orderdc表示先尝试光盘d启动再尝试硬盘c。这确保了首次启动时从ISO安装。-netdev …和-device …: 这一对参数共同定义了网络。-netdev bridge,brbr0,idnet0: 创建一个后端类型为“桥接”的网络设备连接到宿主机的br0网桥并给它一个ID叫net0。-device virtio-net-pci,netdevnet0,mac…: 创建一个前端设备型号是virtio-net-pci一种高性能的半虚拟化网卡并将其连接到后端net0。mac指定了虚拟网卡的MAC地址你可以自定义但最好保证在局域网内唯一。这里以52:54:00开头是QEMU的默认OUI组织唯一标识符比较安全。-vga qxl和-display spice-app: 这两个参数配合提供了比默认VGA更好的图形显示支持并通过SPICE协议输出。spice-app会尝试启动一个本地的SPICE客户端来显示虚拟机画面。如果你的系统没有SPICE客户端可以改用-display sdl或-display gtk甚至-display none无图形适用于纯服务器安装并通过VNC/串口连接。5.2 启动安装与后续操作在终端中执行上述完整命令确保路径正确。如果一切顺利一个新的窗口SPICE客户端会弹出显示虚拟机的启动画面并开始从ISO引导。接下来的操作就和在物理机上安装系统一模一样了在安装程序中选择语言、键盘布局。配置网络时你应该能看到通过DHCP自动获取到的IP地址与宿主机同网段这证明桥接网络成功了。分区时选择我们创建的虚拟磁盘在Ubuntu安装中可能会显示为/dev/vda。完成安装后安装程序通常会提示重启。重启后虚拟机会再次从光盘启动因为我们的-boot orderdc设置没有变。此时你需要关闭虚拟机窗口或发送关机信号然后修改启动命令移除或注释掉-cdrom参数并将-boot orderdc改为-boot orderc优先从硬盘启动。修改后的启动命令类似这样sudo qemu-system-x86_64 \ -enable-kvm \ -name “MyFirstKVMVM” \ -cpu host \ -smp 2 \ -m 4096 \ -drive file/var/lib/libvirt/images/myvm.qcow2,formatqcow2 \ -boot orderc \ -netdev bridge,brbr0,idnet0 \ -device virtio-net-pci,netdevnet0,mac52:54:00:12:34:56 \ -vga qxl \ -display spice-app再次执行这个命令虚拟机就会从硬盘正常启动进入你刚安装好的操作系统。5.3 无图形界面安装与VNC访问对于没有图形界面的服务器或者你想通过SSH远程管理安装过程可以使用VNC。将-display参数替换为VNC设置-vnc :1 -k en-us-vnc :1: 在5901端口59001启动VNC服务器。:0对应5900端口以此类推。-k en-us: 设置键盘布局。启动后你可以在另一台有图形界面的电脑上使用VNC客户端如TigerVNC, RealVNC连接到宿主机IP:5901来查看和控制虚拟机界面。为了安全可以设置VNC密码-vnc :1,password -k en-us启动后需要在QEMU monitor默认按CtrlAlt2切换中输入change vnc password来设置密码。更安全的方式是使用SSH隧道转发VNC端口。6. 高级配置与性能调优虚拟机跑起来只是第一步让它跑得又快又稳才是我们的目标。这里分享几个关键的性能调优点。6.1 使用Virtio驱动与准虚拟化“准虚拟化”Paravirtualization是一种让虚拟机知道自己运行在虚拟环境中的技术通过特殊的驱动Virtio与宿主机高效协作性能远优于完全模拟的设备。我们在前面已经用到了Virtio网卡-device virtio-net-pci。对于磁盘我们也应该使用Virtio。修改-drive参数-drive file/var/lib/libvirt/images/myvm.qcow2,formatqcow2,ifvirtio,cachewriteback,discardunmapifvirtio: 指定磁盘总线为Virtio。cachewriteback: 设置缓存模式为回写Writeback。这是性能最好的模式但存在极小的数据丢失风险宿主机突然断电。对于非关键数据推荐使用。cachenone性能最好且最安全但要求宿主机使用电池备份的RAID卡或类似设备。cachewritethrough最安全但性能差。discardunmap: 启用TRIM/UNMAP支持当虚拟机内删除文件时能通知宿主机的存储系统回收空间对于SSD和精简配置的存储很有用。注意要使Virtio磁盘在安装时被识别你需要在安装操作系统的启动阶段加载Virtio驱动。对于Linux发行版现代内核通常已内置。对于Windows你需要下载virtio-win的ISO镜像在安装时“加载驱动程序”并选择它。6.2 CPU与内存优化CPU绑定CPU Pinning 可以将虚拟机的vCPU固定映射到宿主机的特定物理CPU核心上减少缓存失效和上下文切换提升性能尤其对延迟敏感的应用有益。使用-numa和-smp参数配合。-smp 2,sockets1,cores2,threads1 -numa node,cpus0-1,nodeid0这定义了1个CPU插槽2个核心无超线程。更精细的绑定需要使用taskset或通过libvirt的cpuset配置。大页内存Huge Pages 使用大页内存可以减少TLB转译后备缓冲器未命中的次数显著提升内存访问密集型应用如数据库、科学计算的性能。这需要在宿主机上先配置大页内存然后在QEMU命令中通过-mem-path和-mem-prealloc参数来使用。# 宿主机预留大页例如预留1024个2MB的大页 echo 1024 /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages # 在QEMU命令中添加 -mem-path /dev/hugepages -mem-prealloc注意-mem-prealloc会在启动时立即分配所有内存确保分配到大页上。6.3 图形与声音设备对于桌面虚拟机你可能需要更好的图形和声音支持。图形加速 可以使用-device virtio-vga或-device qxl并配合-display spice-app来获得较好的2D性能。对于3D加速如Windows虚拟机中运行3D游戏或CAD可以尝试-device virtio-gpu-pciLinux guest支持较好或直通物理显卡GPU Passthrough后者非常复杂需要CPU和主板支持VT-d/AMD-Vi。声音 添加-device AC97或-device intel-hda -device hda-duplex来模拟声卡。SPICE协议本身也支持音频传输。7. 常见问题与排查技巧实录即使按照步骤操作也难免会遇到问题。这里记录了几个最常见的问题和我的排查思路。7.1 网络问题虚拟机无法获取IP或无法上网这是最高频的问题。检查桥接状态在宿主机上运行ip addr show br0和bridge link show。确认br0有IP且物理网卡是br0的从设备master br0 state UP。检查防火墙宿主机防火墙firewalld或ufw可能会阻止桥接流量。一个简单的测试方法是暂时关闭防火墙# 对于firewalld sudo systemctl stop firewalld # 对于ufw sudo ufw disable注意测试后请根据安全策略重新配置。通常需要允许libvirt区域或br0接口的流量。检查虚拟机内网卡进入虚拟机用ip addr或ifconfig查看网卡是否识别如ens3或eth0。如果没有可能是Virtio驱动未安装。对于Linux尝试加载模块modprobe virtio_net。对于Windows需安装virtio-win驱动。检查DHCP服务确认你的局域网内存在DHCP服务器通常是路由器。如果没有你需要在虚拟机内手动配置静态IP。检查MAC地址冲突确保你设置的MAC地址在局域网内是唯一的。如果冲突虚拟机可能无法正常通信。7.2 性能问题虚拟机运行缓慢确认KVM已启用在QEMU启动时查看终端输出是否有KVM acceleration enabled的提示。也可以在虚拟机内运行lscpu查看“Virtualization”一项是否显示为VT-x或AMD-V。检查CPU/内存分配是否分配过多资源导致宿主机本身卡顿使用top或htop监控宿主机资源使用情况。检查磁盘I/O模式确认使用了ifvirtio和合适的cache模式。使用iostat或iotop工具监控磁盘I/O性能。如果磁盘是机械硬盘性能瓶颈可能在此。关闭节能特性在宿主机BIOS和系统设置中将CPU的节能模式如C-states, P-states调整为性能模式。7.3 启动失败QEMU报错或虚拟机无法引导权限问题你是否使用sudo运行或者你的用户是否在kvm和libvirt组中尝试用sudo执行。镜像文件路径错误仔细检查-drive和-cdrom参数中的文件路径是否存在是否有读取权限。UEFI vs BIOS现代操作系统和机器多使用UEFI启动。如果你的镜像需要UEFIQEMU需要OVMFUEFI固件。安装edk2-ovmf包在Ubuntu上或edk2-ovmf在RHEL上并在启动命令中添加-bios /usr/share/edk2/ovmf/OVMF_CODE.fd查看QEMU Monitor启动时按CtrlAlt2可以切换到QEMU Monitor输入info status查看状态info block查看磁盘info network查看网络。按CtrlAlt1切回虚拟机屏幕。7.4 管理问题如何优雅地关机和后台运行在虚拟机内关机就像物理机一样在虚拟机操作系统内执行关机命令如sudo shutdown -h now。从宿主机发送关机信号可以向QEMU进程发送SIGTERM信号但这不是最优雅的方式。更好的方法是连接到QEMU MonitorCtrlAlt2或通过-monitor参数指定的socket然后输入system_powerdown命令这会触发虚拟机内ACPI关机事件。后台运行在命令末尾添加-daemonize参数可以让QEMU在后台运行。但这样你就失去了图形界面和控制台。更常见的做法是结合-display none和-vnc或-serial重定向到文件/网络然后使用nohup或screen/tmux会话在后台启动。使用libvirt管理虽然我们直接用了QEMU命令但安装好的虚拟机可以通过virshlibvirt命令行工具来管理。你可以将我们的启动参数写成一个XML文件然后用virsh define myvm.xml和virsh start myvm来启动之后就能用virsh shutdown、virsh destroy、virsh console等命令进行生命周期管理这比直接操作QEMU进程方便得多。
返回列表