银河麒麟V10 KVM虚拟化部署与桥接网络排障实战 1. 整体设计与方案选型1.1 为什么选择KVM而不是其他虚拟化方案银河麒麟高级服务器操作系统在国产化替代和信创项目中出镜率极高尤其是V10版本无论是党政机关还是金融、能源、教育行业都能看到它的身影。而在服务器上跑虚拟机这件事很多朋友第一反应是装VMware Workstation或者VirtualBox但放在服务器场景里这两个方案其实都不太合适。VMware Workstation本身是个桌面级产品依赖图形界面做管理在无头服务器上跑起来既笨重又浪费资源更不用说它还需要独立的授权成本。VirtualBox虽然在桌面端好用但性能损耗相对明显在大规模生产环境里很少被认真考虑。而KVMKernel-based Virtual Machine是Linux内核原生的虚拟化模块直接利用CPU的硬件虚拟化能力在半虚拟化和全虚拟化场景下都有接近物理机的性能表现。更重要的是银河麒麟的服务器版本官方对KVM有完整的适配和文档支持通过libvirt工具链可以完成虚机创建、生命周期管理、动态迁移等一系列操作。这意味着你不需要额外购买商业虚拟化软件也不需要依赖某个特定图形工具只需要一台带虚拟化能力的CPU就能把整套虚拟化环境搭起来。还有一个关键点KVM是内核级组件和银河麒麟的os以及内核版本深度绑定不会出现“装个第三方软件导致系统库冲突”这类坑。对于需要长期稳定运行的生产服务器来说这种内核原生方案在可靠性和维护成本上都更占优势。1.2 环境准备与版本确认动手之前先把环境摸清楚。我这次实操用的系统是银河麒麟高级服务器操作系统V10 SP1内核版本是4.19系列。需要说明的是不同的小版本之间软件包名称和默认配置可能会有细微差异但整体流程是通用的。第一步确认CPU是否支持硬件虚拟化。KVM必须依赖Intel VT-x或AMD-V否则装好了也用不了。用下面这个命令检查grep -E (vmx|svm) /proc/cpuinfo如果输出里能看到vmxIntel或者svmAMD说明CPU硬件虚拟化已经开启。如果没有输出需要进BIOS/UEFI里找找Intel Virtualization Technology或者SVM Mode这类选项把它打开。第二步确认系统版本和架构cat /etc/os-release uname -a我这次用的是x86_64架构处理的是Intel志强系列CPU。如果你手里是ARM架构的机器比如飞腾、鲲鹏安装思路类似但虚拟化扩展检查的命令可能不同ARM架构一般通过/proc/cpuinfo里的hyp标志来判断。第三步确保系统里有足够的内存和磁盘空间。创建虚拟机不是光有个KVM就完事每台虚机要划分独立的CPU核数、内存大小和磁盘镜像文件。我建议至少预留20GB以上的空闲磁盘空间以及至少4GB的可用内存否则后面创建虚机时会很局促。另外操作全程需要root权限或者至少一个能通过sudo切换到root的账户。KVM的很多配置操作都需要修改系统级文件普通用户没有这个权限。2. 核心细节解析与实操要点2.1 KVM相关内核模块与软件包银河麒麟基于Linux内核开发KVM对应的内核模块在系统里是默认存在的但默认不一定加载。先检查一下模块是否已经加载lsmod | grep kvm正常情况下应该看到kvm_intel或kvm_amd模块以及kvm模块。如果什么都没输出可以用modprobe手动加载modprobe kvm modprobe kvm_intel注意Intel平台加载kvm_intelAMD平台加载kvm_amd别搞混了。加载完之后用lsmod | grep kvm再确认一次。软件包方面银河麒麟的默认软件源里包含了KVM全套组件不需要额外配置第三方源。主要需要安装的包有yum install -y qemu-kvm libvirt virt-install bridge-utils这几个包的分工很明确qemu-kvm提供底层的模拟器负责实际运行虚拟机libvirt是虚拟化管理库提供统一的管理接口virt-install是命令行下创建虚拟机的工具bridge-utils用来管理Linux网桥后面配置虚拟网络要用。顺便提一句如果生产环境需要图形化管理界面可以额外装virt-manager和virt-viewer这两个是图形工具适合有桌面环境的机器。在纯服务器环境里我用得最多的还是命令行工具脚本化方便管理效率也更高。2.2 BIOS/固件虚拟化支持检查很多人装KVM时卡在第一步模块加载报错或者创建虚拟机时提示“KVM不可用”。这时候八成是BIOS里的虚拟化开关没打开。进入BIOS的方法各品牌不一样但大多是开机时按Del或F2。进去之后找“Advanced”或者“Processor Configuration”这类菜单里面一般有Intel Virtualization TechnologyIntel平台或者SVM ModeAMD平台把它设为Enabled。这里有个容易忽略的细节有些服务器主板默认开了虚拟化但如果你是在VMware或VirtualBox里再嵌套跑KVM所谓的嵌套虚拟化那么宿主虚拟化软件也要开启对应的嵌套虚拟化选项。比如在VMware Workstation里需要给虚拟机开启“Virtualize Intel VT-x/EPT or AMD-V/RVI”选项。我在实验环境里就遇到过一次这个问题外层的虚拟机软件没开嵌套虚拟化里面装好的银河麒麟再怎么检查都提示不支持KVM排查了半天才发现是这么回事。系统层面确认虚拟化是否可用的命令是virsh capabilities | grep -i vmx如果输出里有vmx字段说明libvirt已经检测到了硬件虚拟化能力。没有输出就说明CPU虚拟化没生效先回BIOS确认。还有个排查技巧用dmesg | grep kvm查看内核日志。如果加载模块时报错日志里会明确告诉你原因比如“KVM: disabled by BIOS”那就不用折腾系统了直接去开BIOS开关。3. 实操过程与核心环节实现3.1 安装KVM相关软件包环境确认无误之后开始安装。银河麒麟的软件包管理兼容yum/dnf安装命令和CentOS/RHEL系列基本一致。yum install -y qemu-kvm libvirt virt-install bridge-utils安装过程如果提示找不到软件包建议先执行一下yum clean all yum makecache把元数据缓存刷新一遍。有些刚装好的系统还没同步软件源直接装会报错。装完之后验证一下安装结果rpm -qa | grep -E qemu|libvirt|virt-install确认关键包都在。另外建议装一个云镜像工具后面用镜像创建虚拟机时会用到yum install -y qemu-imgqemu-img是管理磁盘镜像的核心工具创建虚拟机磁盘文件、查看镜像信息都靠它虽然virt-install内部也会调用但单独安装一个方便手工操作。3.2 启动libvirtd服务libvirtd是KVM虚拟化环境的核心守护进程所有virsh和virt-install操作都得经过它。装完包之后先启动服务再设置开机自启systemctl start libvirtd systemctl enable libvirtd systemctl status libvirtd看到active (running)状态就说明服务正常了。很多新手在这里会卡住报错“Failed to start libvirtd.service”原因通常是内核模块没加载libvirtd启动时检测不到KVM能力。AppArmor/SELinux策略限制银河麒麟默认SELinux可能是enforcing状态。之前装过其他虚拟化软件和libvirtd的配置冲突。遇到启动失败先看详细日志journalctl -u libvirtd -n 50日志里会写清楚失败原因对症处理。SELinux的问题临时可以先setenforce 0测试如果确认是SELinux拦截再写对应策略不要直接关掉SELinux了事生产环境安全还是要保障。启动成功之后执行virsh list --all应该能正常返回虚拟列表当前为空说明libvirt已经能正常工作了。3.3 配置桥接网络KVM默认会创建一个NAT网络virbr0虚拟机可以通过它访问外网。但如果想让虚拟机直接暴露在局域网里让其他物理机也能访问虚机IP那就得配置桥接网络把虚拟机的网卡桥接到物理网卡上。先看看当前物理网卡的名称ip a我这里物理网卡是ens33和CentOS系列常用的命名一致。桥接网络的配置思路是创建一个bridge类型的连接名称叫br0把物理网卡ens33的地址配置迁移到br0上然后ens33本身加入br0成为桥成员。用nmcli操作比较直观# 创建桥接连接 nmcli connection add type bridge ifname br0 con-name br0 # 修改桥接连接的IP地址为原物理网卡的地址 nmcli connection modify br0 ipv4.addresses 192.168.1.100/24 ipv4.gateway 192.168.1.1 ipv4.dns 223.5.5.5 ipv4.method manual # 将物理网卡ens33接入桥 nmcli connection add type bridge-slave ifname ens33 master br0 # 停用并删除原来的以太网连接配置避免IP冲突 nmcli connection down ens33 nmcli connection delete ens33 # 启动桥接连接 nmcli connection up br0注意这里删除ens33网络连接只是删除了NetworkManager里的配置并不会影响物理网卡设备本身。后续ens33作为桥成员的流量都通过br0转发。配置完成后用ip a确认br0获取了IP地址brctl show查看桥成员列表。如果和物理机网络不互通检查一下交换机端口是否限制了多MAC地址以及防火墙是否放行了相关流量。3.4 创建KVM虚拟机网络准备好之后就可以开始创建虚拟机了。创建虚拟机前需要准备一个系统镜像。我这次用的是一个CentOS 7的ISO镜像做演示放在/data/iso目录下。先创建虚拟机磁盘镜像qemu-img create -f qcow2 /data/kvm/centos7-test.qcow2 50G这里用的qcow2格式是KVM最常用的磁盘格式支持稀疏文件、快照、COW写时复制等特性。50G是虚拟磁盘的最大容量但实际占用空间会根据虚机内部实际写入数据量增长不是一开始就占满50G。然后使用virt-install创建虚拟机virt-install \ --name centos7-test \ --memory 4096 \ --vcpus 4 \ --disk path/data/kvm/centos7-test.qcow2,formatqcow2,size50 \ --cdrom /data/iso/CentOS-7-x86_64-Minimal-2009.iso \ --network bridgebr0,modelvirtio \ --os-variant centos7.0 \ --graphics vnc,listen0.0.0.0,port5901 \ --noautoconsole参数拆解一下--name虚拟机名称后面所有管理操作都用它来标识。--memory和--vcpus分配的内存MB和CPU核数。分配时要考虑宿主机的剩余资源别把内存全部分出去宿主机自身也需要内存。--disk指定磁盘路径和格式这里的size50和前面qemu-img创建的50G对应。--cdrom安装镜像路径。--network指定使用br0桥接网络网卡模型用virtio。virtio是半虚拟化IO模型性能远好于模拟的e1000网卡在Linux虚机里尤其明显。--os-variant指定操作系统类型可以让libvirt自动选择最优的虚拟化参数。可以用osinfo-query os查看可用列表。--graphics vnc因为是服务器环境没有显示器用VNC提供图形安装界面listen0.0.0.0表示允许远程连接port5901指定VNC端口。--noautoconsole创建后不自动打开控制台适合远程操作。执行完上面的命令虚机就创建成功了。通过virsh list --all能看到这台虚机。3.5 通过VNC完成系统安装创建命令执行后虚拟机进入安装等待状态但安装界面在VNC的5901端口。在本地电脑上用VNC客户端连接服务器IP的5901端口就能看到CentOS的图形安装界面。如果不想走图形安装也可以用--location参数指定网络安装源、配合kickstart配置文件做全自动安装这样效率更高适合批量交付虚机。我之前批量交付测试环境时就是先做好一个kickstart文件然后用virt-install调用一条命令一台虚机十几台环境半小时内全部搞定。VNC连上去之后按照正常系统安装流程操作即可。安装完成后虚机内部的操作系统和KVM宿主机的网络是二层打通的直接能拿到局域网IP从外部其他机器访问没有任何问题。3.6 虚拟机日常管理命令虚机创建成功之后日常管理主要靠virsh。这里整理几个高频命令# 查看虚机列表含运行中和已关闭 virsh list --all # 启动虚机 virsh start centos7-test # 正常关机需虚机内装有ACPI驱动virtio/ACPI默认支持 virsh shutdown centos7-test # 强制关机 virsh destroy centos7-test # 重启虚机 virsh reboot centos7-test # 查看虚机基本信息 virsh dominfo centos7-test # 进入虚机控制台需要虚机配置了串口控制台 virsh console centos7-test如果你的管理机不方便敲命令也可以在宿主机上装virt-manager图形工具yum install -y virt-manager通过远程X11转发或者本地桌面环境管理虚机。但说实话用多了还是命令行最顺手尤其是写脚本批量操作的时候。4. 常见问题与排查技巧实录4.1 CPU虚拟化未开启导致创建失败创建虚机时如果报错“KVM hardware virtualization is not available”或者“kvm_intel: no hardware support”百分之九十九是CPU虚拟化没打开。排查顺序先grep -E (vmx|svm) /proc/cpuinfo如果输出为空进BIOS开启硬件虚拟化。如果是物理机重启进BIOS设置如果是虚拟机嵌套虚拟化检查外层虚拟化软件是否开启了嵌套虚拟化选项。另外还有一种情况CPU支持虚拟化但内核模块加载失败。执行dmesg | grep kvm看内核日志如果是“kvm: disabled by BIOS”提示同样回 BIOS 设置如果是模块签名或者内核版本不匹配考虑更新内核或调整模块参数。4.2 桥接网络不通虚机无法访问外网这是KVM配置中被问得最多的问题。桥接配置好了但虚机内部上不了网或者外部访问不了虚机。首先确认宿主机桥接是否生效brctl show ip a如果br0有IP但ens33还是UP状态没有成为桥成员说明配置没生效。检查NetworkManager的连接配置nmcli connection show删掉ens33原来的独立连接只保留br0和br0-slave这两个连接否则可能出现IP冲突。其次检查iptablesfirewalld是否拦截了转发流量。KVM的桥接网络依赖宿主机开启IP转发。检查一下sysctl net.ipv4.ip_forward如果输出为0需要开启echo net.ipv4.ip_forward 1 /etc/sysctl.conf sysctl -p另外firewalld默认会拦截FORWARD链的流量如果开启了firewalld需要放行firewall-cmd --permanent --add-masquerade firewall-cmd --reload和VMware里的NAT模式一样KVM的桥接网络本身是靠二层广播的理论上不需要NAT但如果网关做了隔离策略也可能要检查上游设备的配置。最后别忘了检查虚机内部的网络配置。桥接模式下虚机网卡的IP、网关、DNS都必须和宿主机所在的局域网一致不能沿用NAT模式下的DHCP获取方式除非局域网内有DHCP服务器。如果静态配置错了虚机有网卡也上不了网。4.3 SELinux导致libvirtd启动失败或磁盘无法访问银河麒麟默认的SELinux策略对libvirt有一定限制。如果你改过虚机磁盘镜像的存放目录比如放在/home或者/data下SELinux可能拦截libvirtd对该目录的访问导致虚机无法启动报错信息里有“Permission denied”或者关于svirt_image_t的字样。解决方法有几种第一种给目录打上正确的SELinux标签semanage fcontext -a -t virt_image_t /data/kvm(/.*)? restorecon -R /data/kvm第二种如果不想折腾SELinux标签可以关掉SELinux或者在/etc/selinux/config里把SELINUX设为permissive。但我不建议直接关闭尤其是在生产环境保持SELinux enabled状态只对特定目录打标签是更稳妥的做法。另外如果你用了NFS或其他的网络存储作为虚机镜像目录还要处理NFS的SELinux布尔值setsebool -P virt_use_nfs 1这个比较容易漏。4.4 qemu-img与virt-install磁盘大小不一致有时候你会遇到这种情况用qemu-img手工创建了一个20G的镜像但在virt-install里指定了size50结果虚机里看到的磁盘就是50G。原因是virt-install在指定磁盘路径已存在时会忽略该路径下已存在镜像的大小直接用size参数重新定义磁盘大小。避免这个问题的办法是要么让virt-install自动创建磁盘不预先执行qemu-img create要么在virt-install里不写size参数让它用已有镜像的实际大小。我习惯的做法是让virt-install负责磁盘创建--disk path/data/kvm/xxx.qcow2,size50,formatqcow2它内部会调用qemu-img自动创建并格式化。还有个常见坑虚机磁盘格式用raw还是qcow2。raw格式性能略好但占用空间大qcow2支持快照和压缩省空间。个人建议日常使用qcow2性能差距在绝大多数场景下可以忽略但快照和管理功能明显更实用。4.5 常见问题速查表故障现象可能原因排查命令/方法创建虚机提示KVM不可用CPU虚拟化没开启/模块未加载grep -E (vmx|svm) /proc/cpuinfomodprobe kvm_intellibvirtd启动失败模块未加载、SELinux拦截journalctl -u libvirtd -n 50虚机无法访问外网桥接配置错误、IP转发关闭brctl showsysctl net.ipv4.ip_forward磁盘镜像文件无法访问SELinux标签错误ls -Z /data/kvmsemanage fcontextVNC连不上端口未放行、防火墙拦截ss -tlnp | grep 5901firewall-cmd --list-ports虚机关机总是卡住缺少ACPI支持虚机系统内安装acpid服务5. 实操心得与经验总结整套流程走下来几个体会比较深的地方整理一下。第一银河麒麟和KVM的兼容性真的做得不错。软件包只要从默认源里装基本不会缺依赖内核模块也是内置的不像某些国产Linux发行版需要自己编译模块省了很多事。对做国产化替代的团队来说银河麒麟 V10 KVM 这套组合完全可以作为VMware的替代方案来规划。第二桥接网络是最值得提前做好的部分。虚机的网络通了后面的管理就顺畅了网络这块要是没配好虚机装完了还是白搭还得回来重新折腾。我踩过一次坑是在服务器上配置了NetworkManager和network两个服务同时管理的场景刚开始桥接一直不稳定后来停用了network服务交给NetworkManager统一管理问题就解决了。建议在做桥接之前先把宿主机的网络管理方式梳理清楚。第三virt-install的--os-variant参数不要偷懒省略。指定正确的系统类型libvirt会帮你优化很多东西比如选择合适的驱动模型、CPU模式、时钟源等。省一时手贱后面虚机性能踩坑就得不偿失了。第四快照功能可以大胆用。qcow2格式的磁盘原生支持快照在给虚机打补丁或者做变更前先执行virsh snapshot-create-as centos7-test xxx创建一个快照万一操作出问题可以直接回滚。这个习惯在测试环境和生产环境变更时都很有用能省下不少重装系统的时间。第五性能调优方面如果虚机跑的是高IO业务建议把磁盘驱动从sata换成virtio-blk或者virtio-scsi网络也全用virtio。银河麒麟的虚拟化栈对virtio系列驱动是原生支持的做个简单迁移就能明显降低IO延迟值得一试。最后再分享一个小技巧批量创建虚机的时候别一台台敲命令把virt-install参数写成一个shell脚本循环把虚机名称、IP、配置参数都参数化然后循环创建。我上次批量交付8台测试虚机就是这么干的整个过程不到10分钟全部完成。脚本化思维在运维场景里永远是第一生产力。这套环境搭好之后后面还能继续扩展做高可用、动态迁移、快照备份这些更深入的运维能力每一块都有很多玩法。先把基础环境跑通后面怎么用就看你实际业务需求了。