收起左侧

链式克隆虚拟机,实现一秒开十台,每台虚拟机占用不到100MB!

2
回复
53
查看
[ 复制链接 ]

概述

本教程记录在飞牛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. 创建模板存储目录

在你想要的存储空间上创建一个文件夹并右键详细信息复制原始路径,替换后续路径操作命令


操作步骤

第一步:创建源虚拟机

  1. 在飞牛 Web 管理界面中,正常创建一台虚拟机并安装好操作系统。如果是Windows务必要执行通用化 运行菜单输入 %WINDIR%\system32\sysprep\sysprep.exe
  2. 完成所有系统配置和软件安装
  3. 关闭虚拟机(模板必须从关机状态的虚拟机制作)

本教程以飞牛创建的 Ubuntu 24.04 虚拟机 za66xazz 为例。

第二步:确认源虚拟机信息

sudo virsh dominfo za66xazz

image.png

查看磁盘信息:

sudo virsh domblklist za66xazz

image.png
查看磁盘镜像详情:

sudo qemu-img info /vol1/vm/pool/c2656788-aa6b-4b5f-9e96-a220aac9ae65-m2iq.qcow2

image.png

第三步:复制源磁盘为模板基础镜像

将源虚拟机的磁盘复制到模板目录:

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

image.png
输出:

关键对比:模板镜像 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

image.png

VNC恢复正常

image.png

第九步:补全元数据(可选)

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

QQ20260314-204129_1.png

QQ20260314-204356_1.png

飞牛图形化创建的虚拟机 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 块。

image.png

常用 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 密钥。

收藏
送赞 1
分享

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
https://www.xiaozhuhouses.asia/欢迎访问我的博客

38

主题

1464

回帖

0

牛值

系统先锋体验团🛩️

飞牛百度网盘玩家fnOS1.0上线纪念勋章

你这完全脱离了飞牛的操作,确定不会跟飞牛自身虚拟管理机产生冲突吗

13 小时前 楼主 显示全部楼层
ZYan 发表于 2026-3-14 23:47
你这完全脱离了飞牛的操作,确定不会跟飞牛自身虚拟管理机产生冲突吗

不会 看似脱离了 但是飞牛仍然能管理 因为飞牛识别虚拟机走的又不是数据库记录 底层都是对接系统接口相关识别的 所以两者数据是同步的 另外这是进阶教程 极客玩家可以试试🤣🤣 链式克隆出来的虚拟机飞牛是完全可以管理的,并且支持修改任意配置,这个克隆你完全可以理解为一**立的虚拟机,本质上没有太大区别。文章修改了下,忘记放效果图了
https://www.xiaozhuhouses.asia/欢迎访问我的博客
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则