手把手教:有了 AI 咱玩大点,制作自己的类 Proxmox 虚拟机工具(能跑在实机上哦)

最近9月份我有些玩脱了,又是:teacup_without_handle:又是:scroll:的,真的有些东西能不动就不动,即使它不好用
但是嘛我又管不住自己蠢蠢欲动的心,隔几天不折腾下浑身难受
所以我决定不将折腾记录与我自己生活联系起来,毕竟之前写的 Picokeys 教程还好好的躺在那里嘛 :doge:

最近不是新浪云遭下架,众人抢救中文互联网余光引发热议嘛,我那些天也抢救了些历史广播资料(没用 savetheworld 的工具,我自己去下的)
然后我后面就发现,那个抢救互联网的工具为了简化部署难度,是可以运行在 VM 甚至实体机上面的

其实嘛早在初中时期我就想打造一个属于我自己的系统,跑在实机上的 Helloworld 都行
我还特地买了《30天自制操作系统》跟着学(那时候不懂怎么下国外文件,一个 nask 就把我难倒了 :sweat_smile:)
最近因为这个事情我想起来,我还有个定制系统的梦想

于是我把最近一周的糟心事全放在脑后,突击了几天摸索清楚了定制 Linux 的简易路径
当然如果光是嘴讲怎么进这个界面啊怎么写那个配置啊阿巴阿巴阿巴那估计也不能将精髓淌到别人脑中
不过这对于我来说不是问题,我写的东西一般都是有情景的至少要先把我这个榆木脑袋讲打动
既然不能讲跟工作之类有关的场景,那我可就要往大点的玩了哈,接下来就是我的天马行空实现时间 :doge: 咱们向 Proxmox 发起挑战,做一个属于自己的,跟手舒适的虚拟机工具


Proxmox,我反正相信以小众的定位,大多数人应该玩过,整 AIO All In Boom 那种的

但是嘛,我觉得 Proxmox 界面傻大黑粗的,太专业极客了反而不好,不适合像我这样的新手深入操作
(同理点名 HyperV :face_with_bags_under_eyes:)

而我呢,就喜欢开门见山的应用,像 DeepSeek 那样,点进去就是个大大的聊天框,看着多舒服啊

或者像 Parallels Desktop / UTM / Gnome Boxes 那样,指哪点哪多直观呐

后面我搜了下 Proxmox 的后端是 Qemu,这个简单,Qemu 的接口非常完备,用 AI 解决不在话下

都说到 AI 这个份上了,那我直接让 AI 帮我设计个虚拟机工具,把交互页面做的让自己喜欢,目标就是这个 :victory_hand:
说干就干,如果是经常看我写教程的朋友应该知道我要做什么了哈:


零 - 先和 AI 谈出个前后端来

既然要靠 AI 设计虚拟机工具了,那么首先可以拿捏的是工具的名字
首发小众,嗯咱就叫它 “小众虚拟机” 怎样(:frog: 打钱)

不过考虑到教程要符合大众的需求,不能设计太复杂的概念的话,和 AI 进行谈话式创作或许更适合
这样,先打开你最熟悉的 AI 平台(我用的是 dsh,各位也可选用 WorkBuddy、Trae、Pi Agent、OpenCode、Codex,当然选 ZCode 也 OK :doge:)
正所谓谈话式创作嘛,就是告诉 AI 你是个啥也不懂的小白,先放低自己的身段,让 AI 在涉及新概念时先解释原理,后提问约束,专注于单个概念
毕竟我们开始也不知道自己想要的是什么,用下图的四象限来说就是不清楚未知的未知,需要让 AI 以谈话的形式帮我们挖出来

概念的详情可以看这个文章(虽然是爱范儿写的有些标题党,但是文章内的核心非常棒)

我们也可以用类似的引导开发思维做出适合我们的 “小众虚拟机”,下面给出可参考的 Prompt,很短,但是能让 AI 探索出做出这个虚拟机工具能出来的效果和刨出来的坑

我想自己开发一款虚拟机工具,名为 { 给你的虚拟机起名 },目标是像 ESXi、PVE 这样的在 Web 平台上访问和简单管理虚拟机
不过我是纯小白现在没有头绪,你来从实现目标、前端选型、后端选型、制作四版前端草图、设计后端虚拟机平台来带我一步步设计出这款我心仪的虚拟机平台

和 AI 多轮对话后,就可以捏出个自己喜欢的虚拟机管理界面,比如我这样的 :frog: 虚拟机工具各位觉得怎么样

界面捏好后,就可以让 AI 给出个前后端开发文档,稍后开新对话并创建 /goal 让 AI 跑完全开发流程了,可以参考这个 Prompt 输出开发文档

我即将开新对话完成下一步,你来总结所有对话写进 AGENTS.md,PLAN.md 等文件,你已经完成了前端工作,前端已完成,注入后端开发步骤和前后端对接注意事项,让编码 AI 跑完全开发流程

然后开新对话完成后端开发事宜,同理我把可参考的 Prompt 贴出来,目的是让 AI 写出能完成任务的 goal 并坚持迭代即可

看工作区项目文档,创建 /goal 完成剩余步骤

/goal 现在也做的非常成熟,有什么没做到位的可以插话给 AI 叫它别忘了

最后,经过几轮优化好的 “小众虚拟机” 至此完成 :heart_eyes:
包能套娃的 :doge:

展示下咱做这么个虚拟机工具需要的 Token 量哈,刚买的 Token Plan 搞这个教程望大家多多支持哈 :hugs:

2 个赞

不明觉厉,先点个赞

真正的核心应该是 kvm 吧?不用 kvm、纯靠 QEMU,其实虚拟机的性能是非常低的。

此外有两个功能不知道您有没有做,个人建议可以考虑一下:

  1. virtiofs:它是用来在虚拟机与宿主机之间共享存储空间用的,与 SPICE WebDAV 或使用 Samba 相比,这种方式的文件读写效率几乎可媲美物理存储;
  2. SPICE 的共享剪切板功能:对于虚拟机中运行图形化界面的情况,加个共享剪切板其实很方便的。
1 个赞

qemu是核心,kvm是加速用的,在Windows上也可以换成whpx,打个比方,vbox也可以在没有vt的电脑上跑(有小乌龟)

spice有做的 :victory_hand: 显示ai先给我上的tight,不过有预留,已经叫ai改了哈,带共享剪贴板,不过 virtiofs 可以有,感谢提醒 :+1:

昨晚把教程写完后,我就去睡了,还好今天放假不用担心第二天的班
今天一早醒来就看到大家对我的 “小众虚拟机” 提出的宝贵建议了,在此十分感谢各位提的建议,后面我完成教程后会将 “小众虚拟机” 发出来(含源码和启动镜像),各位如有需要欢迎下载使用哈

[!note]- 但是我想说
不过我想大家可能对我创作的初心有点误会哈,比起这个我更希望大家动手做这个项目,亲自体验将自己的程序通过定制镜像的方式跑在实机上
话说回来,既然制作 “小众虚拟机” 放在第零章,那就说明重头戏在第一章哈,且听我慢慢道来…


壹 - 把咱的虚拟机工具用 Alpine 打包器装起来

有了好用的 “小众虚拟机” 虚拟机管理工具后,咱就想心思将它做成真正的虚拟机工具系统了
先跟刚开发好 “小众虚拟机” 的 AI 协调下将整个程序打包并集成进定制 Linux 系统的路径

阅读此项目,这个项目 “小众虚拟机” 已经开发完成,我即将将其移动到定制 Linux 的 rootfs 中,你来编译前端,打包后端,在 /build 文件夹中交付可用文件,tar.gz 格式,并给出我初次配置和以后启动命令

然后就可以静待 AI 帮忙打包完所有文件并提供交付结果和交付命令了哈

当然等待期间,咱们先选型下适合装 “小众虚拟机” 及以后自行写的小程序的定制系统,在这里我会首选 Alpine

Alpine,虽然各位没怎么听说过它的大名,但是你一定用过 Docker 上的各类镜像
举个例子,你在下镜像的时候,如果没有在镜像指定系统版本(比如 :ubuntu 或者 :debian)一般下的是 Alpine 加持的镜像
Alpine 凭借其 OpenRC 简单精简的服务管理和基于 Busybox 轻量化的工具集,拥有极致小的核心体积,深得 Docker 开发者的喜爱

但是大家可能不知道的是,简单精简的 OpenRC 和 轻量化的 Busybox,在模块化系统也是数一数二的存在,非常适合制作定制系统,Alpine 官方也提供了诸如 alpine-make-vm-image 简易虚拟机打包工具供咱们制作虚拟机定制系统
不过我们的终极目标是在实机上跑咱的 小众虚拟机,那不得不上 Alpine 的另一款简易打包工具 alpine-make-rootfs 了

.1 啥是 rootfs

Linux 可能有些人没怎么真摸过,这样,想理解 rootfs 的可以在手机上下一个 MT管理器 然后一直点 .. 文件夹直到点不动为止

此时你看到的包含启动 Android 所必须的诸如 /bin /dev 等基础目录组合在一起,构成了能运行 Android 的骨架,这就算是一个根文件系统,又叫 rootfs
Linux 的哲学就是 “啥都能成目录” (Android 算是魔改版 Linux),而这些基础目录是能运行 Linux 的核心
所以我们到时候也是用 Alpine 提供的 rootfs 创建工具去创建一个能跑起来 Linux 的根文件系统

.2 怎么用上 alpine-make-rootfs

Alpine 官方建议在 Alpine 中运行 alpine-make-rootfs,我有 WSL2,不过我用的是 Debian,在另装 Alpine 速度很慢的情况下,可不可以直接在 Debian 上跑这个小工具呢?
可以的,首先把这个小工具给下下来:

下好了别忘记加个执行

chmod +x alpine-make-rootfs

完成后咱就可以规划怎么安放刚做成的 “小众虚拟机” 了
正好 AI 帮忙交付好所有文件了,看一下它给的交付目录(参考用,具体看你的 AI 是怎么做的)

build/
├── README.md                  ← 部署说明(含下面全部命令的完整版)
├── appinn-vm-deploy.tar.gz    ← 同内容的压缩包(200 KB,方便拷进 rootfs)
├── backend/                   ← 后端源码(无 .venv / __pycache__ / data 运行时数据)
│   ├── app/…                  35 个 .py + db/schema.sql
│   ├── requirements.txt       宽松约束(fastapi / uvicorn[standard] / pillow)
│   ├── requirements.lock.txt  精确版本(Python 3.14 实测解析出的 19 个)
│   └── run.py
├── frontend/build/            ← vite 产物 50 文件 / 328 KB
└── deploy/
    ├── install.sh             一次性安装(uv 建 venv + 装依赖 + 4 项自检)
    ├── appinn-vm.openrc       OpenRC 单元(Alpine 默认)
    ├── appinn-vm.service      systemd 单元(备用)
    └── appinn-vm.env.example  环境变量样例

交付目录很清晰,然后我们把这个 tar.gz 以及 alpine-make-rootfs 拷到 WSL2 主目录中作为定制 Alpine 的核心文件
顺便建立其他文件留作备用,具体目录如下:

appinn-vm-os/
├── appinn-vm-deploy.tar.gz    ← 拷过来的虚拟机工具项目
├── make-rootfs.sh             ← 给 alpine-make-rootfs 调用的脚本,实现些自动化操作
└── alpine-make-rootfs         ← 主角,用于打包出 rootfs

然后编辑 make-rootfs.sh 做下自动化操作,把咱们的工具打包进 rootfs

#!/bin/sh -e

# 可选,这里需要创建可调用虚拟机的用户
adduser -D -H -s /sbin/nologin appinn
adduser appinn libvirt
adduser appinn kvm

# 第一步部署项目
mkdir -p /opt/appinn-vm
tar -xzf /mnt/appinn-vm-deploy.tar.gz -C /opt/appinn-vm
cd /opt/appinn-vm
sh deploy/install.sh
chown -R appinn:appinn /opt/appinn-vm

# 第二步装 OpenRC 服务使其开机自启动
install -m 0755 deploy/appinn-vm.openrc /etc/init.d/appinn-vm
cat > /etc/conf.d/appinn-vm << 'CONFEOF'
APPINN_HOME=/opt/appinn-vm
APPINN_USER=appinn
CONFEOF
rc-update add libvirtd default
rc-update add appinn-vm default
rc-update add local default

# 可选,设置 libvirt 网络
cat > /etc/local.d/appinn-firstboot.start << 'FBEOF'
#!/bin/sh
i=0
while [ $i -lt 30 ]; do
  virsh -c qemu:///system list --all >/dev/null 2>&1 && break
  sleep 1
  i=$((i+1))
done
virsh -c qemu:///system net-start default 2>/dev/null || true
virsh -c qemu:///system net-autostart default 2>/dev/null || true
rm -f /etc/local.d/appinn-firstboot.start
FBEOF
chmod +x /etc/local.d/appinn-firstboot.start

然后就可以让 alpine-make-rootfs 开始打包了哈
打包这茬事是真的慢(即使换源了)得留半个小时,这段时间可以做点别的事

sudo ./alpine-make-rootfs \
  --mirror-uri 'https://mirrors.aliyun.com/alpine' \
  --packages 'python3 py3-libvirt uv libvirt-daemon libvirt-client qemu-system-x86_64 qemu-img ovmf openrc mkinitfs linux-lts' \
  --timezone 'Asia/Shanghai' \
  --script-chroot \
  ./rootfs.tar.gz \
  ./build-rootfs.sh

[!note]- 一直卡在 apk not found, downloading static apk-tools
:alarm_clock:老问题了,下载国外文件慢,不过这次咱们可以不用魔法,直接自定义 alpine-make-rootfs 小工具即可
其实吧 alpine-make-rootfs 是个 shell 文件,直接拿编辑器就能打开


我们需要找到这一行,把对应的 apk.static 想方设法下载下来(用 IDM 下速度不错)

然后把 apk.static 放在 appinn-vm-os/ 目录下,并用 chmod 加执行权限
最后在编辑器找到这一行,把 : ${APK:="apk"} 改为 : ${APK:="./apk.static"} 就行了

.3 能做成 ISO 吗

当然能,接下来是本章教程比较难的部分了,闭起小嘴巴竖起小耳朵别分心
尽管咱们得到了定制系统的 rootfs,但是它只是个文件,别说实机了,放进虚拟机也是没法将其引导的

而一个真正能被启动起来的 Linux 机器,需要最起码三样东西:

    1. rootfs 咱们有
    1. Linux 内核咱们也有
    1. initramfs 搭配 Linux 内核完成启动步骤,这个真没有 :wl:

[!note]- 为啥 alpine-make-rootfs 小工具不在 rootfs 提供 initramfs
initramfs 的创建需要结合 rootfs 内部系统来生成,里面包含内核以及配置等,必须要咱们的定制系统亲自生成
而进入咱们的定制系统就需要解压现有的 rootfs,并以 chroot 方式进入
然后咱们就能跑一遍 initramfs 生成器也就是 mkinitfs 补全这最后一步了

所以接下来我们要改造这堆文件,将其打包成一个可以引导的 ISO 文件

先把咱刚刚生成的 rootfs 给提取出来

mkdir -p ./rootfs
sudo tar -xzf ./rootfs.tar.gz -C ./rootfs

然后我们再生成启动时必要的 initramfs,补全这最后一块定制 Alpine 的拼图
先通过 chroot 进入咱们的定制系统

sudo chroot ./rootfs

然后看一下装在咱定制系统的 Linux 内核版本号

ls /lib/modules
# 比如我的版本号是 6.6.30-0-lts

之后用 mkinitfs 将咱的 initramfs 弄出来

mkinitfs -b / -o /boot/initramfs-lts {内核版本号}
# 比如 mkinitfs -b / -o /boot/initramfs-lts 6.6.30-0-lts

生成好后检查生成的 initramfs 是否存在

ls -lh /boot/initramfs-lts
ls -lh /boot/vmlinuz-lts

如果存在那就太好了,计划完成了一大半,剩下的就是制作可引导 ISO 的流程了


中秋节出门玩了哈,未完待续…