概述
本教程记录在飞牛NAS(FnOS)上实现 KVM 虚拟机链式克隆的完整过程。链式克隆基于 qcow2 的 backing file 技术,克隆虚拟机仅存储与模板的差异数据,极大节省磁盘空间。
优势
- 创建速度极快 — 秒级完成
- 磁盘空间极省 — 克隆初始仅占约 256KB ~ 数百KB
- 批量部署方便 — 一个模板可派生出多个克隆
环境信息
| 项目 |
详情 |
| 系统 |
FnOS(基于 Debian 12) |
| 内核 |
Linux 6.12.18-trim |
| CPU |
Intel Xeon E5-2680 v4 @ 2.40GHz (16核) |
| 内存 |
7.8GB |
| QEMU |
qemu-img 7.2.22 |
| libvirt |
virsh 9.0.0 |
| 网络 |
OVS 桥接(ens3-ovs) |
前置准备
1. 安装 virt-install
FnOS 默认已安装 KVM/QEMU/libvirt,但缺少 virt-install,需要手动安装:
sudo apt update
sudo apt install -y virtinst
安装输出:
Reading package lists...
Building dependency tree...
Setting up virt-viewer (11.0-2) ...
Setting up virtinst (1:4.1.0-2) ...
验证安装:
which virt-install
# /usr/bin/virt-install
2. 创建模板存储目录
在你想要的存储空间上创建一个文件夹并右键详细信息复制原始路径,替换后续路径操作命令
操作步骤
第一步:创建源虚拟机
- 在飞牛 Web 管理界面中,正常创建一台虚拟机并安装好操作系统。如果是Windows务必要执行通用化 运行菜单输入
%WINDIR%\system32\sysprep\sysprep.exe
- 完成所有系统配置和软件安装
- 关闭虚拟机(模板必须从关机状态的虚拟机制作)
本教程以飞牛创建的 Ubuntu 24.04 虚拟机 za66xazz 为例。
第二步:确认源虚拟机信息
sudo virsh dominfo za66xazz

查看磁盘信息:
sudo virsh domblklist za66xazz

查看磁盘镜像详情:
sudo qemu-img info /vol1/vm/pool/c2656788-aa6b-4b5f-9e96-a220aac9ae65-m2iq.qcow2

第三步:复制源磁盘为模板基础镜像
将源虚拟机的磁盘复制到模板目录:
sudo cp /vol1/vm/pool/c2656788-aa6b-4b5f-9e96-a220aac9ae65-m2iq.qcow2 \
/vol1/1000/templates/ubuntu24.04-base.qcow2
💡 提示:这里使用 cp 而非移动,源虚拟机保持不变,便于确认无误后再决定是否删除。
第四步:将模板镜像设为只读
这一步非常重要! 所有克隆都依赖此模板镜像,一旦被修改会影响所有克隆虚拟机:
sudo chmod 444 /vol1/1000/templates/ubuntu24.04-base.qcow2
验证:
ls -lh /vol1/1000/templates/ubuntu24.04-base.qcow2
输出:
-r--r--r--+ 1 root root 4.5G Mar 14 20:37 /vol1/1000/templates/ubuntu24.04-base.qcow2
第五步:创建链式克隆磁盘
使用 qemu-img create 基于模板创建链式克隆磁盘:
sudo qemu-img create -f qcow2 -F qcow2 \
-b /vol1/1000/templates/ubuntu24.04-base.qcow2 \
/vol1/1000/templates/ubuntu24-clone-01.qcow2
输出:
Formatting '/vol1/1000/templates/ubuntu24-clone-01.qcow2', fmt=qcow2
cluster_size=65536 extended_l2=off compression_type=zlib size=21474836480
backing_file=/vol1/1000/templates/ubuntu24.04-base.qcow2 backing_fmt=qcow2
lazy_refcounts=off refcount_bits=16
参数说明:
| 参数 |
说明 |
-f qcow2 |
克隆磁盘格式为 qcow2 |
-F qcow2 |
backing file(模板)的格式为 qcow2 |
-b <路径> |
指定 backing file(模板基础镜像) |
| 最后的路径 |
克隆磁盘的输出路径 |
验证链式克隆磁盘:
sudo qemu-img info /vol1/1000/templates/ubuntu24-clone-01.qcow2

输出:
✅ 关键对比:模板镜像 4.5 GB,克隆磁盘仅 256 KB!
第六步:修复目录权限
libvirt 运行虚拟机使用 libvirt-qemu 用户,需要确保存储目录有访问权限:
sudo chmod o+x /vol1 /vol1/1000 /vol1/1000/templates
第七步:创建链式克隆虚拟机
使用 virt-install 基于克隆磁盘创建虚拟机。
⚠️ 关键注意事项:飞牛 FnOS 的网络使用 OVS 桥接,创建虚拟机时必须指定 virtualport_type=openvswitch,否则网络会失败。
sudo virt-install \
--name ubuntu24-clone-01 \
--ram 2048 \
--vcpus 2 \
--machine q35 \
--disk /vol1/1000/templates/ubuntu24-clone-01.qcow2,format=qcow2,bus=virtio,discard=unmap \
--osinfo detect=on,require=off \
--network bridge=ens3-ovs,model=virtio,virtualport_type=openvswitch \
--graphics vnc,listen=0.0.0.0 \
--video virtio \
--import \
--noautoconsole \
--cpu host-passthrough
输出:
WARNING Using --osinfo generic, VM performance may suffer. Specify an accurate OS for optimal results.
Starting install...
Creating domain... | 0 B 00:00
Domain creation completed.
参数说明:
| 参数 |
说明 |
--name |
虚拟机名称 |
--ram |
内存大小(MB) |
--vcpus |
CPU 核心数 |
--machine q35 |
使用 Q35 芯片组 |
--disk |
指定克隆磁盘,格式 qcow2,总线 virtio |
--osinfo detect=on,require=off |
自动检测 OS,不强制要求 |
--network |
OVS 桥接网络,必须加 virtualport_type=openvswitch |
--graphics |
VNC 图形输出 |
--video virtio |
VirtIO 显卡 |
--import |
导入已有磁盘(不从 ISO 安装) |
--noautoconsole |
不自动打开控制台 |
--cpu host-passthrough |
CPU 直通,性能最佳 |
第八步:修改 VNC 为 Socket 方式(适配飞牛 Web 界面)
飞牛 FnOS 的 Web VNC 控制台通过 Unix Socket 连接,而非 TCP 端口。virt-install 默认创建的是 TCP 方式,需要修改为 Socket 方式才能在飞牛界面中使用 VNC。
1. 关闭虚拟机:
sudo virsh destroy ubuntu24-clone-01
2. 导出 XML 配置:
sudo virsh dumpxml ubuntu24-clone-01 > /tmp/clone01.xml
3. 修改 VNC 配置:
将 XML 中的 graphics 部分:
<!-- 修改前(TCP 方式,飞牛界面无法使用) -->
<graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>
<listen type='address' address='0.0.0.0'/>
</graphics>
替换为:
<!-- 修改后(Socket 方式,飞牛界面可用) -->
<graphics type='vnc' socket='/var/run/vms/ubuntu24-clone-01.vnc.sock' powerControl='yes'>
<listen type='socket' socket='/var/run/vms/ubuntu24-clone-01.vnc.sock'/>
</graphics>
可以使用 sed 命令批量替换:
sed -i "s|<graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>|<graphics type='vnc' socket='/var/run/vms/ubuntu24-clone-01.vnc.sock' powerControl='yes'>|" /tmp/clone01.xml
sed -i "s|<listen type='address' address='0.0.0.0'/>|<listen type='socket' socket='/var/run/vms/ubuntu24-clone-01.vnc.sock'/>|" /tmp/clone01.xml
4. 重新定义并启动虚拟机:
删除旧的虚拟机定义
sudo virsh undefine ubuntu24-clone-01
使用修改后的 XML 重新定义:
sudo virsh define /tmp/clone01.xml
启动虚拟机:
sudo virsh start ubuntu24-clone-01
删除临时文件
rm -f /tmp/clone01.xml

VNC恢复正常

第九步:补全元数据(可选)
比较明显的是克隆出来的虚拟机飞牛是不显示类型这导致后续无法通过飞牛修改这个虚拟机配置,其实飞牛这些信息都是定义到了XML文件中,同样我们进行修改


飞牛图形化创建的虚拟机 XML 中包含以下元数据:
<title>ubuntu24</title>
<metadata>
<customMeta xmlns="customMeta">
<osType xmlns="osType">linux</osType>
<osVersion xmlns="osVersion">6.x - 2.6 Kernel</osVersion>
<autostart xmlns="autostart">false</autostart>
<createdTime xmlns="createdTime">1773490742</createdTime>
</customMeta>
</metadata>
需要将这些元数据注入到克隆虚拟机中:
1. 关闭虚拟机并导出 XML:
sudo virsh destroy ubuntu24-clone-01
sudo virsh dumpxml --inactive ubuntu24-clone-01 > /tmp/clone01.xml
2. 注入元数据:
使用 sed 在 </uuid> 行后插入 <title> 和 <metadata> 块:
CREATED_TIME=$(date +%s)
sed -i "/<\/uuid>/a\\
<title>ubuntu24-clone-01</title>\\\\
<metadata>\\\\
<customMeta xmlns=\\\"customMeta\\\">\\\\
<osType xmlns=\\\"osType\\\">linux</osType>\\\\
<osVersion xmlns=\\\"osVersion\\\">6.x - 2.6 Kernel</osVersion>\\\\
<autostart xmlns=\\\"autostart\\\">false</autostart>\\\\
<createdTime xmls=\\\"createdTime\\\">${CREATED_TIME}</createdTime>\\\\
</customMeta>\\\\
</metadata>" /tmp/clone01.xml
💡 sed 转义较复杂,也可以直接用文本编辑器(如 nano /tmp/clone01.xml)手动在 </uuid> 行下方添加上述 XML 块。

常用 osType 和 osVersion 值:
| osType |
osVersion |
说明 |
linux |
6.x - 2.6 Kernel |
Linux 通用 |
windows |
win11 |
Windows 11 |
windows |
win2k22 |
Windows Server 2022 |
other |
- |
其他系统 |
3. 重新定义并启动:
sudo virsh undefine ubuntu24-clone-01
sudo virsh define /tmp/clone01.xml
sudo virsh start ubuntu24-clone-01
rm -f /tmp/clone01.xml
输出:
Domain 'ubuntu24-clone-01' has been undefined
Domain 'ubuntu24-clone-01' defined from /tmp/clone01.xml
Domain 'ubuntu24-clone-01' started
现在飞牛 Web 界面上克隆虚拟机会显示 Linux 图标、系统类型和版本信息。
虚拟机列表
验证结果
sudo virsh list --all
Id Name State
------------------------------------
7 ubuntu24-clone-01 running
- za66xazz shut off
磁盘空间对比
模板镜像: 4.5G /vol1/1000/templates/ubuntu24.04-base.qcow2
克隆磁盘: 448K /vol1/1000/templates/ubuntu24-clone-01.qcow2
💡 克隆磁盘运行一段时间后会增长,因为写入的新数据都会记录到克隆磁盘中,但远小于完整复制一份磁盘。
架构说明
模板基础镜像(只读 444)
**── ubuntu24.04-base.qcow2 (4.5GB)
**── ubuntu24-clone-01.qcow2 → VM: ubuntu24-clone-01 (448KB)
**── ubuntu24-clone-02.qcow2 → VM: ubuntu24-clone-02 (可继续创建)
**── ...
每个克隆虚拟机的磁盘文件都以模板镜像作为 backing file,只存储运行过程中产生的差异数据。
快速创建更多克隆
基于同一模板快速创建更多克隆虚拟机,只需重复步骤 5~8:
# 1. 创建克隆磁盘
sudo qemu-img create -f qcow2 -F qcow2 \
-b /vol1/1000/templates/ubuntu24.04-base.qcow2 \
/vol1/1000/templates/ubuntu24-clone-02.qcow2
# 2. 创建虚拟机
sudo virt-install \
--name ubuntu24-clone-02 \
--ram 2048 \
--vcpus 2 \
--machine q35 \
--disk /vol1/1000/templates/ubuntu24-clone-02.qcow2,format=qcow2,bus=virtio,discard=unmap \
--osinfo detect=on,require=off \
--network bridge=ens3-ovs,model=virtio,virtualport_type=openvswitch \
--graphics vnc,listen=0.0.0.0 \
--video virtio \
--import \
--noautoconsole \
--cpu host-passthrough
# 3. 修改 VNC 为 Socket 方式
sudo virsh destroy ubuntu24-clone-02
sudo virsh dumpxml ubuntu24-clone-02 > /tmp/clone02.xml
sed -i "s|<graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0'>|<graphics type='vnc' socket='/var/run/vms/ubuntu24-clone-02.vnc.sock' powerControl='yes'>|" /tmp/clone02.xml
sed -i "s|<listen type='address' address='0.0.0.0'/>|<listen type='socket' socket='/var/run/vms/ubuntu24-clone-02.vnc.sock'/>|" /tmp/clone02.xml
sudo virsh undefine ubuntu24-clone-02
sudo virsh define /tmp/clone02.xml
sudo virsh start ubuntu24-clone-02
rm -f /tmp/clone02.xml
删除克隆虚拟机
# 关闭虚拟机
sudo virsh destroy <虚拟机名称>
# 删除虚拟机定义及磁盘
sudo virsh undefine <虚拟机名称> --remove-all-storage
注意事项
⚠️ 模板镜像不可修改 — 模板镜像已设为只读(444),所有克隆都依赖此镜像,修改或删除会导致所有克隆虚拟机无法启动。
⚠️ OVS 网络 — FnOS 使用 Open vSwitch 桥接网络,创建虚拟机时必须指定 virtualport_type=openvswitch,否则会报错 Unable to add bridge ens3-ovs port: Operation not supported。
⚠️ VNC Socket — 飞牛 Web 界面的 VNC 控制台通过 Unix Socket(/var/run/vms/<vm-name>.vnc.sock)连接,通过命令行创建的虚拟机需要手动修改 VNC 配置为 Socket 方式才能在飞牛界面中使用。
⚠️ 目录权限 — 虚拟机磁盘所在目录需要确保 libvirt-qemu 用户有访问权限(目录链上每级都需要 o+x)。
⚠️ 内存限制 — 此服务器总内存 7.8GB,需合理分配,建议每台虚拟机 1-2GB,最多同时运行 3-4 台。
⚠️ 克隆的虚拟机与模板共用相同的系统配置(hostname、MAC 地址、SSH 密钥等),多台克隆可能产生冲突。建议首次启动后手动修改 hostname 和重新生成 SSH 密钥。