得之我幸 失之我命

when someone abandons you,it is him that gets loss because he lost someone who truly loves him but you just lost one who doesn’t love you.

qemu 中部署 fnOS

有好长时间不更新博客了,其实折腾还是在折腾的,就是每次折腾都不深入,于是就没有什么特别的内容值得被记录,这篇也是犹犹豫豫,迟疑之中写的。一方面是因为涉及到了一个新的工具 qemu,在命令行里开虚拟机这还是第一次,另一方面也是希望把最初在 debian 上用 docker 部署 qemu 容器,容器里部署 fnOS 这部分内容做一个备份。这两个方面的折腾都花了不少时间,只是硬件限制,所以两层套壳的部署方案最终被直接在 debian 上运行 qemu 部署 fnOS 替代了

docker 部署 qemu 容器,容器里部署 fnOS

下面 4 个步骤是我在飞牛论坛上找到的,原文链接在这里,我做了一些修改和补充

  1. 创建 compose.yml,内容如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    services:
    fnos:
    image: qemux/qemu
    container_name: fnos
    environment:
    BOOT: "https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.12-965.iso" # fnOS 镜像链接
    RAM_SIZE: "2G" # qemu 设定的内存大小
    CPU_CORES: "4"
    DISK_SIZE: "16G" # 飞牛系统盘大小,对应容器里的 /storiage,系统里的目录 /dir1
    DISK2_SIZE: "200G"
    devices:
    - /dev/kvm
    - /dev/net/tun
    cap_add:
    - NET_ADMIN
    ports:
    - 8006:8006
    volumes:
    - /dir1:/storage
    - /dir2:/storage2
    restart: unless-stopped
    stop_grace_period: 2m
    networks:
    vlan:
    ipv4_address: 192.168.0.10
    networks:
    vlan:
    external: true

    关于这个镜像,还有更多的参数可用,可以看这里

  2. 创建 macvlan 网络

    在缺省网络模式下,qemu 里运行的 fnOS 无法通过 IP 从外部访问,可以运行以下命令创建:

    1
    2
    3
    4
    5
    6
    # 假设内网是 192.168.0.*
    $ docker network create -d macvlan \
    --subnet=192.168.0.0/24 \
    --gateway=192.168.0.1 \
    --ip-range=192.168.0.0/28 \
    -o parent=ens133 vlan # 其中 ens133 是本机的有线网卡
  3. 启动容器

  4. 安装 fnOS

    浏览器访问 192.168.0.10:8006,按提示完成 fnOS 安装

    安装完成后,打开 192.168.0.10:5666 体验 fnOS

这个方案存在的问题

  1. 飞牛数据盘的内容,是无法直接在 debian 上读取的,数据盘在 debian 上的显示是一个 data2.img

  2. 如果本机没有使用有线网卡,说是 macvlan 网络并不是那么合适 —— 关于这个问题,我用 gemini 做了一次 deepsearch,结果可以看这里

插曲,那我能不能直接根据 iso 做一个 docker 镜像呢?

可行,但困难重重

可行的地方是,fnOS 的 iso 镜像里已经包含了所有的依赖和工具,可以直接解压获取相应的 rootfs,直接用来构建

困难重重的地方是,我确实构建出来了一个 docker 镜像

  1. 但由于没有排除不必要的文件和目录,导致镜像体积有 5GB 之多

  2. 通过这个镜像,我找不到 fnOS 的 webUI 服务

  3. 虽然发现了 webUI 的蛛丝马迹,但由于 fnOS 的服务是由 systemd 管理的,而要给 docker 容器加入对 systemd 的支持,这不是我能最快解决的方式了

插曲二,那我能不能用现成的 docker 镜像呢?

确实也找到了一个现成的 docker 镜像以及对应的 compose.yaml,从这个 compose.yaml 里可以看到,这个镜像是启用了 systemd 的,但不好用

  1. 这个 compose.yaml 存在下面这个问题需要修改,否则启动会直接出错
1
2
3
4
# 修改前
/sys/fs/cgroup:/sys/fs/cgroup:ro
# 修改后
/sys/fs/cgroup:/sys/fs/cgroup:rw
  1. 登陆 webUI 的时候也有一些 bug

  2. debian 不能访问数据盘

在 qemu 中部署 fnOS

最后尝试直接在 qemu 中部署 fnOS,以下面这个 qemu 命令,成功启动了 fnOS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
$ qemu-system-x86_64 \
-name "fnOS-VM" \
-enable-kvm \
-cpu host \
-m 2G \
-smp 4,sockets=1,cores=4,threads=1 \
-machine type=q35,accel=kvm \
-daemonize \
-pidfile "$VM_DIR/qemu.pid" \
-monitor telnet:127.0.0.1:11000,server,nowait,nodelay \
-serial file:"$VM_DIR/serial.log" \
-drive if=pflash,format=raw,readonly=on,file="$UEFI_CODE" \
-drive if=pflash,format=raw,file="$UEFI_VARS" \
-device virtio-scsi-pci,id=scsi0 \
-drive file="$DISK1",if=none,id=drive-disk1,format=raw,cache=none,aio=native \
-device scsi-hd,bus=scsi0.0,scsi-id=0,drive=drive-disk1 \
-drive file="$DISK2",if=none,id=drive-disk2,format=raw,cache=none,aio=native \
-device scsi-hd,bus=scsi0.0,scsi-id=2,drive=drive-disk2 \
-drive file="$BOOT_ISO",if=none,id=drive-iso,media=cdrom,readonly=on \
-device scsi-cd,bus=scsi0.0,scsi-id=1,drive=drive-iso \
-netdev user,id=net0,hostfwd=tcp::7666-:5666 \
-device virtio-net-pci,netdev=net0 \
-virtfs local,path="$SHARED_DIR",mount_tag=host_share,security_model=passthrough,id=fsdev0 \
-vga virtio \
-display vnc=0.0.0.0:5101,password=on \
-device qemu-xhci \
-device usb-tablet \
-device virtio-rng-pci \
-device virtio-balloon-pci

使用 qemu 部署过程中还是遇到了很多问题:

  1. 这应该是个 shell 的语法问题,\ 之后有空格或者注释,导致换行作用实效,命令解析失败

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $ qemu-system-x86_64 \
    # ... 其他参数保持不变 ...
    -drive file="$DISK1",if=none,id=drive-disk1,format=raw,cache=none,aio=native \
    -device scsi-hd,bus=scsi0.0,drive=drive-disk1 \
    \
    # (安装时启用) 挂载启动ISO
    -drive file="$BOOT_ISO",if=none,id=drive-iso,media=cdrom,readonly=on \
    -device scsi-cd,bus=scsi0.0,scsi-id=2,drive=drive-iso \
    \
    # ... 其他参数保持不变 ...
  2. fnOS 中通过挂载共享目录的方式,无法在 webUI 中看到路径,需要先创建存储空间,通过在存储空间的位置进行挂载共享目录,才可以在网盘下载文件时看到共享目录

其他问题

以下 qemu 问题由于我还没有展开研究,所以先仅做记录

  1. 网卡目前显示半双工,应该如何修改配置

  2. vnc 设置了无密码,但是在 macOS 上进行访问时依然提及需要密码

  3. 网卡 tap 和 user 模式的区别

be slow to promise and quick to perform.