银河麒麟v10鲲鹏920上手工创建虚拟机:KVM与virt-install完整实操指南

发布时间:2026/9/16 21:12:42
银河麒麟v10鲲鹏920上手工创建虚拟机:KVM与virt-install完整实操指南 银河麒麟 server v10 上手工创建虚拟机鲲鹏920平台的一次完整实操最近帮一台装好银河麒麟 kylin server v10 的鲲鹏920机器做虚拟化折腾下来发现网上很多教程写得含糊要么直接跳过了ARM平台和x86平台的差异要么把virt-install的参数一笔带过照着敲完还是一堆报错。这篇文章把我在鲲鹏920 银河麒麟server v10上的完整创建虚拟机过程记录下来包括组件选型、命令参数、以及几个卡了我很久的坑。先说结论在银河麒麟v10上创建虚拟机本质就是用KVM QEMU libvirt这一套标准虚拟化栈但因为CPU是ARM架构镜像格式、固件选择、系统类型的写法都和x86不完全一样照着x86的教程抄作业大概率会翻车。整个过程我自己跑通后又从零开始重建了一遍虚拟机确认了每一步的依赖关系和注意事项下面按实操顺序来写。适合刚接触银河麒麟系统虚拟化、或者准备在信创环境里用鲲鹏机器跑虚拟机的朋友参考。1. 为什么在鲲鹏920上还要再套一层虚拟化场景与技术方案选型1.1 鲲鹏920和银河麒麟v10这个组合的现状鲲鹏920是华为基于ARMv8架构设计的服务器CPU和常见的x86_64服务器CPU相比指令集不同、固件规范走的是UEFI很多底层行为都不一样。银河麒麟server v10有针对这个平台的专门版本一般镜像名会带aarch64或arm64标识用的时候要注意和x86_64的镜像区分开。在系统层面银河麒麟v10的ARM版本已经默认编译好了KVM内核模块至少我用的这个版本内核基于4.19具体小版本号记不清了打开系统后直接检查/dev/kvm就能看到设备节点。这是好消息省去了重新编译内核的麻烦。既然底层已经具备KVM支持那么在上面再创建虚拟机就是顺理成章的事。常见使用场景包括把一套业务环境拆成多个隔离虚拟机、在测试机上快速创建临时环境、或者在一台高性能鲲鹏服务器上做资源整合。我这次的需求就更典型了——一台机器上需要同时跑多个不同配置的实例直接物理隔离成本太高虚拟化是最合适的选择。1.2 可选虚拟化方案对比KVM、容器、还有那些桌面工具在动手之前有必要把方案选型说清楚。当前在麒麟系统上做虚拟化主流有三条路方案底层技术优点缺点适合场景全虚拟化KVM QEMULinux内核KVM模块 QEMU模拟设备生态成熟、性能接近物理机、隔离性强配置相对复杂需要理解虚拟化组件服务器环境、正式业务、多租户隔离容器Docker等内核Namespace Cgroup轻量、启动快、资源占用小共享内核隔离性弱不能跑不同操作系统的内核应用打包、微服务、开发测试桌面虚拟化工具VirtualBox等QEMU或自有虚拟化引擎操作简单、有图形界面性能一般、在纯服务器环境安装困难桌面开发、个人实验这里要说一个误区有人觉得既然用了麒麟系统就直接用系统自带的“虚拟系统管理器”virt-manager图形工具就行。实际上在纯命令行服务器上图形环境往往没装而且远程管理virt-manager还需要额外的网络配置并不省事。真正稳定可靠的做法是直接用命令行工具virt-install和virsh管理虚拟机。1.3 为什么最终选择KVM libvirt这套标准组合我的选择理由很简单银河麒麟v10的ARM内核已经带上了KVM模块QEMU和libvirt的麒麟软件源里也有预编译的aarch64版本整体是“原汁原味”的Linux虚拟化方案不需要额外折腾第三方闭源组件出了问题也能靠Linux社区的经验排查。另一个重要原因是鲲鹏920对KVM虚拟化的支持比较完善硬件虚拟化扩展类似x86的VT-x默认开启。内核KVM模块加载后虚拟机里的Guest OS能直接利用CPU的硬件虚拟化能力性能损耗很小。我实际测试下来虚拟机里跑编译任务和物理机性能差距基本在5%以内这个表现完全可以接受。对libvirt这一层我用的是virt-install命令行工具来创建虚拟机用virsh做日常管理和查看状态。这套组合在自动化脚本里也很好使以后可以写脚本批量创建虚拟机不用一台台手动操作。2. 创建虚拟机前必须确认的三件事硬件支持、组件安装、网络规划2.1 先检查CPU虚拟化扩展和KVM内核模块创建虚拟机的第一步不是急着眼镜像而是确认硬件虚拟化能力。ARM架构下检查方式和x86不太一样x86要看/proc/cpuinfo里有没有vmx或svm标志ARM则要看内核有没有加载KVM模块。登录服务器后依次执行# 检查KVM模块是否加载 ls /dev/kvm # 查看KVM相关模块状态 lsmod | grep kvm # 查看CPU支持的虚拟化特性ARM架构下主要看是否支持KVM cat /proc/cpuinfo | grep -i virtualization\|vfp\|asimd正常情况下列出的结果中应该能看到/dev/kvm设备节点以及kvm_module这些内核模块。如果/dev/kvm不存在大概率是内核模块没加载可以尝试手动加载modprobe kvm如果modprobe报错说明当前内核可能没有编译KVM支持或者BIOS/固件里虚拟化功能被关闭了。鲲鹏服务器的BIOS一般默认开启但如果是二手设备或者被别人调过需要进固件设置确认一下。这一步如果没搞定后面所有操作都是白搭。2.2 安装qemu-kvm、libvirt和桥接工具组件安装是常规操作但在ARM平台要特别注意软件包名字与版本。我这边用的是麒麟官方源直接dnf安装# 更新软件源缓存 dnf makecache # 安装QEMU KVM和libvirt相关组件 dnf install -y qemu-kvm libvirt virt-install bridge-utils这里要解释几个包的具体作用qemu-kvmQEMU配合KVM的版本负责设备模拟。ARM架构下的QEMU支持模拟多种ARM开发板但我们这里主要是利用它对virtio设备的支持。libvirt虚拟化管理库提供了统一的管理接口virsh和virt-install都依赖它。virt-install用来从命令行创建虚拟机的工具会自动调用QEMU/KVM。bridge-utils用来创建和管理网桥的工具做虚拟机网络时要用到。另外一个容易忽略的包是edk2-uefi固件。ARM平台的虚拟机不像x86有BIOS需要UEFI固件来启动虚拟机。建议一并安装dnf install -y edk2-uefi如果这个包不装创建虚拟机时指定加载固件步骤后续启动大概率会报找不到可引导设备。2.3 启动libvirtd服务并规划虚拟机网桥装完组件后需要把libvirtd服务启动起来并设置开机自启systemctl start libvirtd systemctl enable libvirtd systemctl status libvirtd服务正常启动后用virsh命令可以查看当前虚拟化环境virsh version virsh nodeinfonodeinfo输出中如果能看到CPU型号、内存大小、虚拟化CPU核数等信息说明libvirt已经能正确识别底层硬件可以继续往下走了。网络规划是很多新手容易忽略的点。创建虚拟机前要想好虚拟机怎么联网。麒麟系统安装libvirt后会默认创建一个NAT网络一般是192.168.122.0/24网段虚拟机通过这个网络可以访问外网但外部网络要访问虚拟机里的服务会比较麻烦。如果虚拟机上要跑对外提供访问的服务建议创建桥接网络# 查看当前网络列表 virsh net-list --all由于我这里的宿主机网卡是物理网卡要把虚拟机直接暴露到物理网络采用桥接模式最直接。创建桥接网桥的命令如下假设物理网卡名字叫enp3s0不同机器可能不一样用ip a确认一下nmcli connection add type bridge ifname br0 con-name br0 nmcli connection modify br0 ipv4.method auto nmcli connection add type ethernet slave-type bridge con-name bridge-slave-enp3s0 ifname enp3s0 master br0对网桥操作不熟悉的同学我建议第一次实验时先用默认的NAT网络跑通虚拟机创建流程之后再研究桥接。NAT网络在virt-install中通过参数--network networkdefault指定即可桥接网络则用--network bridgebr0。3. 一步一个命令virt-install 创建鲲鹏架构的虚拟机3.1 准备安装镜像创建虚拟机前先想好要给虚拟机装什么系统。在鲲鹏920上一般有几种选择装一个银河麒麟v10的ARM版、装openEuler的ARM版、或者装一个纯命令行的Ubuntu Server ARM版。我用的是麒麟v10的ARM64安装镜像通常是.iso文件可以从官网下载或者用之前已经下载好的镜像。把镜像上传到宿主机后放在比如/opt/kylin_iso目录下记住完整路径后面virt-install命令要引用。3.2 virt-install命令的核心参数与解释先给出完整命令再逐步解释每个参数的含义。这里有个关键点ARM架构和x86的virt-install用法最核心的区别在于指定架构、机器类型、以及是否使用UEFI固件我第一次就是漏了这几个参数创建的虚拟机死活启动不了。virt-install \ --name kylin-vm-01 \ --memory 4096 \ --vcpus 4 \ --cpu host \ --arch aarch64 \ --machine virt \ --os-variant kylin-v10 \ --disk path/var/lib/libvirt/images/kylin-vm-01.qcow2,size50,formatqcow2 \ --cdrom /opt/kylin_iso/Kylin-Server-10-aarch64.iso \ --network networkdefault \ --graphics vnc,listen0.0.0.0 \ --boot uefi参数逐个说明--name虚拟机名称自定义即可。--memory分配给虚拟机的内存MB这里分配4GB。--vcpusCPU核数分配4核。--cpu host让虚拟机直接使用宿主机的CPU型号特性性能最好。创建后不要轻易改不然虚拟机里的系统可能不识别CPU变化。--arch aarch64显式指定架构为aarch64这是ARM64服务器必须的参数。--machine virt机器类型ARM平台通常用virt类型。--os-variant优化虚拟机OS的设置。这个参数可以先用osinfo-query os查看支持哪些系统如果不知道具体名称可以用--os-variant detecton,namelinux让安装程序自动探测。--disk磁盘路径、大小、格式。--cdrom安装镜像路径。--network networkdefault使用NAT网络。--graphics vnc,listen0.0.0.0用VNC做图形安装界面监听所有地址方便远程连接安装。--boot uefi指定用UEFI引导ARM虚拟机必须要加这个参数。3.3 安装过程中的注意事项命令执行后virt-install会调用QEMU启动虚拟机、加载UEFI固件然后从ISO镜像引导。此时可以通过VNC连接到虚拟机的安装界面用VNC客户端比如TigerVNC连接宿主机的IP加端口默认5900。如果没有图形环境也可以把--graphics换成文本模式--graphics none --location /opt/kylin_iso/Kylin-Server-10-aarch64.iso不过ARM版的麒麟安装镜像对纯文本安装支持一般我更推荐VNC模式装系统时能看到完整界面。安装过程跟在物理机上装系统差不多选择语言、配置磁盘、设置root密码、创建普通用户。这里提醒一个点在ARM平台上安装时系统可能默认分区格式是GPT而非MBR这是正常的不要干预。安装完成后系统会自动重启并进入新系统。这时候可以用virsh工具查看虚拟机状态和连接方式virsh list --all virsh vncdisplay kylin-vm-01vncdisplay命令会返回VNC显示号结合宿主机IP就能用VNC客户端连接到虚拟机了。我实测下来从命令执行完到VNC界面出现d大约等了30秒到1分钟和物理机装系统的等待时间类似。4. 创建后的日常管理和运维克隆、快照、CPU内存调整4.1 用virsh对虚拟机做基础管理安装完成后日常管理基本都靠virsh完成。最常用的几个命令# 启动虚拟机 virsh start kylin-vm-01 # 正常关机发送ACPI关机信号 virsh shutdown kylin-vm-01 # 强制关机 virsh destroy kylin-vm-01 # 设置虚拟机开机自启 virsh autostart kylin-vm-01 # 进入虚拟机的命令行控制台需要虚拟机里开启串口控制台 virsh console kylin-vm-01virsh console这个命令很好用不需要VNC就能直接进虚拟机命令行前提是虚拟机里要有serial console配置。在装系统时如果选了开启串口终端一般都能直接使用。4.2 克隆虚拟机复制一个同样的环境如果需要多个相同的虚拟机不一定要重新安装克隆要快得多。先把要克隆的虚拟机关机然后使用virt-clone命令# 关闭源虚拟机 virsh shutdown kylin-vm-01 # 克隆 virt-clone \ --original kylin-vm-01 \ --name kylin-vm-02 \ --file /var/lib/libvirt/images/kylin-vm-02.qcow2克隆完成后启动新虚拟机时可能会遇到两个问题一个是新虚拟机继承了源虚拟机的hostname、IP地址需要进去改另一个是网卡的MAC地址虽然virt-clone会自动生成新的但如果系统里配置了固定IP比如/etc/sysconfig/network-scripts/ifcfg-eth0里写死了IP依然要手动改。所以我克隆后一般建议进入虚拟机执行以下操作# 查看当前主机名 hostnamectl set-hostname kylin-vm-02 # 查看网卡配置 ip a # 根据实际情况修改IP配置然后重启网络 # 如果有SSH host key可以清空重新生成 rm -f /etc/ssh/ssh_host_* systemctl restart sshd4.3 快照给虚拟机拍个“后悔药”在系统配置出问题或者要测试新软件时快照能救命。创建和恢复快照的命令很简单# 创建快照 virsh snapshot-create-as kylin-vm-01 snapshot-initial 初始安装完成状态 # 查看快照列表 virsh snapshot-list kylin-vm-01 # 恢复快照会回滚到快照创建时的状态 virsh snapshot-revert kylin-vm-01 snapshot-initial # 删除快照 virsh snapshot-delete kylin-vm-01 snapshot-initial这里说下我的经验快照建议装完系统、拷贝完基础配置后就建一个以后无论怎么折腾一条命令就能回到干净状态。但要注意快照占磁盘空间别建太多保持两三个就够用。另外快照恢复是整体回滚会丢失快照创建之后的所有数据变更操作前要想清楚。4.4 调整虚拟机配置CPU和内存的在线扩展KVM支持在线调整CPU和内存不用关机# 调整CPU核数最大不能超过宿主机的物理CPU核数 virsh setvcpus kylin-vm-01 8 --live # 调整内存需要虚拟机支持内存热插拔一般默认可以 virsh setmem kylin-vm-01 8192 --live不过在线调整只是临时生效重启虚拟机就会恢复为XML配置里的原始值。如果想永久生效需要编辑虚拟机配置virsh edit kylin-vm-01在XML配置里找到memory和vcpu标签修改保存后重启虚拟机生效。我习惯先在线调整测试效果确认无误后再改XML配置做持久化。5. 实操中踩过的坑和排查链路建议先看完再动手5.1 创建后无法启动UEFI固件缺失问题这是我第一次创建虚拟机时遇到的第一个大坑。命令执行完虚拟机状态一直是shut off查看日志发现报错内容大意是“找不到可引导的设备”。排查链路是这样的# 查看虚拟机的当前状态 virsh list --all # 查看虚拟机的详细日志 virsh list --all --detail # 查看libvirtd的日志 journalctl -u libvirtd -n 50 # 查看QEMU进程启动日志 journalctl -xe | grep qemu最后发现是创建命令里漏了--boot uefi参数。ARM平台默认情况下没有传统BIOS引导如果不指定UEFIQEMU就不知道该从哪里引导系统。这里有个判断经验如果虚拟机创建时报错和boot/uefi相关先用find /usr/share -name *.fd看看edk2固件文件是否存在确认装了edk2-uefi包再在命令里指定--boot uefi。5.2 虚拟机没网络检查网桥和NAT配置第二次遇到的坑是虚拟机起来了VNC也连上了但虚拟机里面ping不通外网。先按这个顺序排查# 在宿主机上查看虚拟机的网卡状态 virsh domiflist kylin-vm-01 # 查看libvirt的虚拟网络状态 virsh net-list --all virsh net-info default # 检查本机的iptables规则查看NAT规则是否正常 iptables -t nat -L n POSTROUTING最后发现是firewalld把NAT规则给挡了。libvirt创建default网络时自动生成的iptables规则和firewalld的规则冲突流量到宿主机后没法正确转发。解决方法是把firewalld对libvirt网络的区域设置改一下firewall-cmd --permanent --zonelibvirt --change-interfacevirbr0 firewall-cmd --reload或者更加简单粗暴但有效把firewalld停掉如果你的服务器对安全要求没那么严格的话systemctl stop firewalld systemctl disable firewalld我生产环境一般不停firewalld而是按第一种方式调整区域设置。改完之后虚拟机里重新启动网卡或者重启虚拟机网络就通了。5.3 ARM架构特有的坑镜像架构不匹配第三个坑很有代表性。我一开始图省事下载了一个x86_64的麒麟镜像想在鲲鹏的虚拟机里直接装。结果virt-install执行后虚拟机启动到UEFI阶段就卡住了ISO根本没法引导。这个问题的原因在于ARM平台上的虚拟机只能引导ARM架构的系统镜像x86_64镜像的引导扇区格式、内核镜像格式都不一样UEFI无法识别。解决方式也很简单下载对架构的镜像。选择ISO时一定要看清楚文件名里带不带aarch64/arm64标识。在鲲鹏920上创建虚拟机宿主机的CPU是ARM架构虚拟机的CPU也是ARM架构那Guest OS必须也是ARM架构这叫“同构虚拟化”。未来如果有特殊需求要做跨架构模拟比如在ARM上跑x86虚拟机那是另一套玩法用QEMU的TCG模式性能非常差一般只用于测试不建议用于日常使用。5.4 VNC连接不上监听地址和防火墙安装系统时如果用了VNC图形界面经常遇到VNC客户端连不上的问题。可能原因有两个第一是virt-install里没指定listen0.0.0.0默认只监听127.0.0.1远程当然连不上。创建命令里要写成--graphics vnc,listen0.0.0.0。第二是宿主机防火墙可能挡了5900端口。可以用防火墙命令放行firewall-cmd --permanent --add-port5900/tcp firewall-cmd --reload如果同时运行多个虚拟机VNC端口会往后顺延比如第一台是5900第二台可能就是5901。用virsh vncdisplay kylin-vm-01可以查到每个虚拟机的VNC显示号和对应端口。5.5 性能比预期低CPU型号和numa节点的影响有一台虚拟机创建后跑多线程任务性能明显不如物理机。排查后发现是我创建时CPU参数写了--cpu cortex-a72强制指定了一个较老的ARM CPU型号导致虚拟机的CPU特性比如某些向量指令被限制了。解决办法是把CPU参数改成--cpu host让虚拟机直接继承宿主机的CPU全部特性。但如果虚拟机要跨宿主机迁移比如以后要从这台鲲鹏920迁移到另一台配置不同的服务器用--cpu host就会出现CPU不兼容问题那种场景下要根据实际的迁移需求做CPU型号屏蔽配置这里先不展开。另外如果宿主机是多路CPU或者大内存机器建议用numactl --hardware查看NUMA节点拓扑。在创建虚拟机时用--numatune参数把虚拟机内存绑定到指定NUMA节点避免跨节点访问内存导致的性能下降。我实际测试中这个优化在内存密集型任务上能带来10%以上的性能提升。6. 把创建流程脚本化适合批量交付环境的实操模板6.1 我的自动化脚本思路如果只是创建一个虚拟机手工敲命令没问题。但遇到批量交付场景——比如一次要交付5台虚拟机给不同班组使用——再手工敲就太低效了。这种情况下应该把创建过程做成脚本。我整理了一份脚本的核心逻辑实际应用时按需修改参数即可#!/bin/bash # 批量创建虚拟机脚本示例 # 用法: ./create_kvm.sh vm_name vm_count BASE_NAME$1 VM_COUNT${2:-1} ISO_PATH/opt/kylin_iso/Kylin-Server-10-aarch64.iso DISK_DIR/var/lib/libvirt/images for i in $(seq 1 $VM_COUNT); do VM_NAME${BASE_NAME}-${i} echo Creating VM: ${VM_NAME} virt-install \ --name ${VM_NAME} \ --memory 4096 \ --vcpus 4 \ --cpu host \ --arch aarch64 \ --machine virt \ --os-variant linux \ --disk path${DISK_DIR}/${VM_NAME}.qcow2,size50,formatqcow2 \ --cdrom ${ISO_PATH} \ --network networkdefault \ --graphics vnc,listen0.0.0.0 \ --boot uefi \ --noautoconsole done echo All VMs created successfully.--noautoconsole参数的意思是创建后不自动连接控制台免得批量创建时interactive的安装界面卡住脚步。装系统还是需要VNC或者之后用其他方式自动化处理。6.2 自动化安装用Kickstart文件实现全自动部署如果需要更彻底的自动化可以在virt-install里指定kickstart文件实现无人值守安装。麒麟系统支持这个方式。大体思路是准备好kickstart文件比如/opt/kylin_iso/ks.cfg内容包含分区、软件包选择、root密码等参数然后在virt-install命令的最后加上--extra-args ksfile:/ks.cfg inst.kshd:fd0:/ks.cfg不过这里涉及到一个ISO文件的挂载和kickstart文件的路径映射问题命令行里直接引用会比较绕。更常见的做法是把ISO文件解压出来自定义其中的GRUB引导菜单加入ks参数然后重新打包成ISO。这个操作比较折腾有批量的自动化安装需求时再研究这里先提个思路。6.3 日常备份和数据保护建议最后虚拟机创建好了、跑上业务了备份就是头等大事。我的建议是按节奏做三件事一是虚拟机的配置文件本身就是重要的元数据定期备份/etc/libvirt/qemu/目录tar -czf /backup/libvirt-qemu-configs.tar.gz /etc/libvirt/qemu/二是磁盘镜像文件可以用qcow2格式自带的快照功能也可以直接用rsync做整盘同步rsync -avP /var/lib/libvirt/images/kylin-vm-01.qcow2 /backup/三是如果虚拟机上跑的是数据库之类的高价值应用建议在应用层面做逻辑备份虚拟层备份只是兜底不能完全替代应用备份。我个人实际操作中的体会是虚拟机创建本身不难真正花时间的是前期规划——想好网络模式、想好磁盘布局、想好初始化方式。把这些想清楚创建就是一条命令的事想不清楚后面运维会处处被动。希望这篇实操记录能帮你少走点弯路尤其在ARM平台上每一个“参数差异”都可能是一次深夜排障。