84 Star 681 Fork 63

Moe/TMOE

可否将tmoe-qemu移入到tmoe-manager?

已完成
创建于  
2022-04-20 11:20

架构与系统版本

container value
os ubuntu 20.04 LTS
arch arm64
type proot

host value
os android 11
arch arm64
terminal Termux
tmoe latest

硬件设备为小米平板5 Pro 5G

该问题是怎么引起的

我这个需求应该算是有点特殊,我需要GUI和Docker并存,也就是说Docker所在系统必须有图形界面,因为我要让Docker利用容器外的GUI进行绘图。现在的问题是,我通过各种尝试使用proot和chroot都无法正常安装docker,那看来就只有qemu这一条路了。可是tmoe-qemu现在被放置在tmoe-tools里,这就没办法像proot那样直接在Termux中直接创建,必须要在套一层容器里再装虚拟机。
我通过tmoe-qemu安装UOS,整个过程极其漫长难熬,光是安装就花了4个多小时,我想骁龙870的性能也不至于这么拉胯吧,虽然本身在arm64的架构里装x64的虚拟机性能肯定会有影响,但是如果去掉外层的proot容器呢?性能会不会有所提升?
我看过#I361KZ这个Issue,Moe大佬说当初不下放给Termux是因为termux和容器内的写法不一致。这确实是个问题,维护两套代码实属心累,但是容器里真的还需要qemu吗?

建议

就我目前来看,既然可以使用proot或者是chroot容器了,我干嘛还要在容器内建qemu虚拟机呢?使用qemu恰好就是proof容器无法满足需求的下策不是吗?(或者有什么我没有考虑周全的情况,Moe大佬可以指出
所以既然是这样,不如把tmoe-tools里的qemu去掉,直接维护tmoe-manager里的qemu是不是更好?

评论 (8)

Bean 创建了任务 3年前
Bean 修改了描述 3年前
Bean 修改了描述 3年前
Bean 修改了描述 3年前
Bean 修改了描述 3年前
展开全部操作日志
5617340 mo2 1648809770 Moe 拥有者 3年前

conslusion

先来说一下结论:
就算是极限精简的 alpine + virt 内核,在 tcg 加速下跑 docker 的速度也快不到哪去。
你的目的是跑 docker,qemu 只是手段。
更合理的做法是:手动编译linux内核,加入 docker 所需的特性,让它原生支持 docker。
折衷的做法是:远程连接服务器。

qemu 慢的主要原因在于你的cpu或系统不支持 kvm 或其他特殊的加速方案。
我不能说没有 kvm 就一定慢,因为 xen 也挺快的。

影响一个事物的因素,往往是多方面的。
有些时候,我们不能从一个角度去分析。
比如 qemu 速度慢,可能是qemu自身配置方面的问题,宿主硬件配置的问题,也有可能是某些外部因素的影响。
我们不能说容器就一定会更慢。
容器内部就一定不能让 qemu 加速。
实际上,我之前曾听别人说过,他在 docker 里的 kvm(qemu) 里跑 macos 虚拟机。

如果你的系统(内核)和 cpu 都支持 kvm 的话,并且你的 qemu 加上了 accel=kvm ,那么对于qemu的其他东西,就算你随便配置都不会太慢。
注: 对于kvm,x86_64 架构加速适用于x86 和 x64, 但是不适用于 arm64 。

倒不如说,如果可以加速的话,请务必告诉我。
我之前饱受交叉编译不同架构之苦。

同理,反过来也是一样的。
不同的一点在于 arm64v9 貌似还有个特殊版本(without aarch32 support)。
普通的 arm64v8a 和 arm64v9(with aarch32 support) 是可以直接向下兼容 arm32v7l 的。

简单来说,就算你有 kvm, 但是cpu 是 arm64 架构的,这时候也不能用 kvm 来加速 x64 架构的系统。


frontend

我在那个 issue 中,提到了 "libnewt" 和 "libncursesw6",这个是与 TUI 相关的东西,你可以把它简单理解为与前端相关的东西。准确来说,这是与前端相关的后端库。
实际上,在好几个月前,由于 termux 引入了一些新包,因此我不需要手动维护(提供)相关库/二进制,就能使用相同的语法了。
其实我想要用 rust 来重写一些东西,如果我真的要重写,那么就算没有那些库也无所谓了!

很好,此处假设前端相关的问题已经解决了。

backend

然而,还有个问题,我在那个 issue 中没有提到,就是后端方面的差异。
从以前到现在,一直都是这样。
termux 源里 qemu-system 没有 debian/ubuntu 的完整,前者相比后者少了一些包,还有一些特性。
这可能会造成一些问题,比如说在非完整版上使用部分功能/特性可能会出问题。

我这里并没有想要喷 termux 的 qemu-system 的相关维护者,实际上他们能维护相关软件包已经是相当难得的一件事情了。

维护软件包,在很多情况下是一件很辛苦的事,他们的付出应该得到尊重。

手动编译,可以给它加上一些特性。但是对于 android,手动编译前的准备工作可能会比标准 linux 发行版更繁琐,出现各种小问题的可能性会更大。

container

对于 android/linux,tmoe 的 chroot 功能除非手动切换,否则默认是 unshare。
对于使用systemd init 的 gnu/linux,它默认是 systemd-nspawn。

对于在 proot/chroot 中尝试运行 docker 的行为,其实我应该在文档中加个说明,因为有太多人踩坑了。
详见此issue
首先,linux docker 必须要有 linux 内核的支持。
像 macos 上的 docker 其实是虚拟机方案。
windows 上的 windows container 不清楚,但是 wsl2+docker 也是虚拟机方案。
有些电脑的 cpu 支持虚拟化(比如Intel Vt-x, Vt-d, Vt-c),系统也支持调用一些加速方案。
我们在这里不用关心是什么加速方案。
它们速度可能并不慢,但是并不是原生运行的。

你可能因为它们的速度很快,就误以为 android 跑虚拟机再跑 docker 的速度也不慢。
从某种程度来说也没错啦!之前不是有新闻说,pixel6 (android 13)支持 kvm, 然后有大佬在上面跑虚拟机。
但是那是人家有 kvm 啊!
如果只有 tcg 的话,那么就算是 arm64 跑 arm64 虚拟机(非容器),那也快不起来呀!

回到容器内部跑 docker 的问题吧。
假设你的内核支持 docker,那么如果需要在容器内部跑 docker 的话,应该要用 docker in docker 的思路去解决。
就是在宿主环境里开 docker 后台进程,让容器绑定宿主的 docker 的 unix socket。
这样子就可以在容器内调用宿主的 docker 了。
我之前在 docker 里调用过 docker,但还没在 chroot/unshare 里这么干过。
注: docker in docker 对于 CI(持续集成) 来说还挺常见的,比如 drone ci

container+qemu

如果你在 debian sid 的 unshare 容器内使用 qemu-system,那么它的速度不一定会比 termux版 的 qemu 慢,倒不如说,它还有可能更快一些。

你是不是觉得有违常理,觉得我在胡说八道?

你可能不知道的冷知识: 在一两年前,我曾“潜入”到某个交流虚拟机和容器的群里,不过后来退群啦!他们说在 proot 里面的 qemu 会比 termux 里的更快。

是不是觉得更离谱了。
我起初也觉得有点不可置信,但是我却无法拿出强有力的证据来推倒这个结论。

你说 unshare 的话,我有 99.9% 的可能性会选择相信。
proot 的话,我是有点不太信的啦!
proot 与 chroot/unshare 对比,最大的区别不在于前者有更多的小问题,而在于磁盘 IO 性能。
我个人觉得前者的磁盘 IO 性能弱了很多(读写速度比较慢),而后者基本上与宿主差不多了。(这是主观感受,因为没有测试,所以可能是错误的结论)

其实我不应该这么贬低 proot,因为我自己并没有能力去写一个这么强的 container-runtime。
你可能会觉得我目中无人,盲目自大。
确实!这是我的不对,前面的内容已经加了删除线了。

话说回来,debian 那边维护 qemu 的态度确实是非常非常积极。
假如今天出 qemu 最新版, 明天我就在 debian experimental 源里看到相关包。
我完全相信这件事,完全相信 Debian QEMU Team。
输入图片说明
输入图片说明
注:实际上,最新的 qemu7.0 不到两天就进 sid 源了,比我预想的还要快。
我记得之前,好像是6.0版的时候,它会在 experimental 源里多待几天,然后才进 sid 的。

qemu

最后,我谈一谈 qemu 本身吧!
简单的 qemu 相当简单,几分钟就能入门,复杂的 qemu 可谓是难到了极致。

有些东西难的不是它不是它本身,而是它延伸出来的东西。
一个简单的知识点可能并不难,但是这个“点”可能会与其他“点”一起连成一个“面”,这个“面”可能会与其他“面”连成一个“体”。而这个“体”有又可能和其他“体”相连,组成一个更大的“体”。

你如果对这个“点”关联到的“面”没有全面而清晰的认识,那么可能会觉得好难好难啊!
我以前就觉得 qemu 好难好难啊,现在还是这么想的。(可谓一点都没有长进。)
而且我现在越来越焦躁了,大概率是没有时间,并且也静不下心来去深入研究其他的“点”了。

题外话:你别看我说要用 rust 去重写 tmoe 本体,然后以为我马上就能写出来。因为我立下了 2023 年之前写出来的 flag, 所以大概率是会在 2022-12-31 23:59:59 的时候发啊!(不是

我们随便摘出一段 tmoe-qemu 的配置(对,就是别人经常喷的那个小脚本。
其实在一般情况下,我们是不需要做如此精细化的控制的。
但是太简单又不行,这样子就拉不开与别人的差距了。
当年我在写它的时候,“卷”这个词应该还没有流行。放现在看,这个东西就是无意义的“卷”的产物。
输入图片说明
你以为 qemu 只跟软件有关,实际上跟硬件方面有千丝万缕的联系。
初看可能难以理解。
其实把抽象的东西具体化就好了。
比如说 “-device” 参数,你把它想象成一台电脑,在特定 pci/pcie 接口插入设备就可以了。

再谈谈其他配置,比如半虚拟化相关的 virtio。
在配置 qemu 方面,virtio 相关的硬件可能会比其他完全虚拟化的硬件更快。
virtio 有部分内容还跟内核有关。
比如 virtio 相关的文件系统。
举个例子: 当初 debian buster 的 cloud 内核,裁剪掉了 virtio-9p 相关的东西。
注:virtio-9p 和 virtio-fs 都能让虚拟机与宿主共享特定文件,后者效率更高一点,但是要求也更高。为了兼容性, tmoe 里面的qemu 工具,用的是 virtio-9p。

等等,说下去就变成讲解 qemu 了。(大雾

你用 tmoe 的 qemu 相当于走了弯路。
虽然网络配置(转发tcp, udp 端口)以及共享文件夹方面,可能会比 virt-manager 更简单一点。

其实你要研究 qemu 的话,应该去研究 libvirt api 。
要方便一点的话,可以去研究 virsh 和 virt-manager,这两者应该都是通过 libvirt 来管理的。

时间应该花在有意义的事情上。
就算是折腾工具,也要折腾有意思的工具。

我不希望你把时间浪费在折腾 tmoe tools内置的 qemu 配置工具上。

虽然这个工具当初花了我很多时间和心血,但是转念一想,把它归为浪费时间更为合适。

我是写给自己用的,debian sid + intel cpu 可以用 kvm 加速,默认配置是 MACHINE_ACCEL='kvm:tcg',也就是默认支持 kvm ,当不支持 kvm 时,将回退为 tcg。

我还以为没有人在用呢!而且我也很久没有维护这个 qemu 工具了。
emmm, 其实我之前就想要砍掉它了。

你可能不知道的冷知识。
之前我在写文档的时候,会加上更新日志。
每次我说我砍掉了一些功能, fork 数就会增加。
太神奇了!
直到后来,我删掉了更新日志。

Bean-Xabean Bean
回复 Moe 拥有者
3年前

感谢大佬的超精细回答,我悟了啊

我现在知道为什么你做的proof-Docker用的是debian sid了
自己搞内核我看我还是算了吧,我也不想太折腾(其实我就是喜欢Surface,只是我没钱 ,所以想用arm的平板代替)。。。
虽然virt-manager好,但是有TUI才香啊,因为宿主机就是不装GUI咋办?
直接研究qemu确实难度好大,话说我这两天就卡在了QEMU Monitor上了,有个奇怪的问题,我想通过QEMU Monitor把光驱弹出来,我首先查一下光驱名称:info block,看到光驱设备是:virtio-3-format(好奇怪的名字),然后我再输入:eject virtio-3-format,这么写应该没错吧,我看网上也是这样的流程,但是奇怪的是,qemu给我反馈找不到virtio-3-format这个设备是怎么回事呢?

Moe 添加了
 
good-first-issue
标签
3年前
5617340 mo2 1648809770 Moe 拥有者 3年前
5617340 mo2 1648809770 Moe 拥有者 3年前

输入图片说明

你如果想要在 arm64 android设备(不支持docker的内核)上跑 docker,可以试试这个。
安装完成后,打开 vnc 客户端,输入 localhost:5905
进入系统后,输入 root , 再输入 passwd 修改密码。

然后回到 termux,新建一个 session(会话窗口),并输入 ssh -p 2888 root@localhost

进入 ssh 后,输入 docker ps -a 看看。

在虚拟机里面,你可以用 systemctl 命令。

输入 docker start portainer
然后打开浏览器,输入 localhost:39081
注:默认的 tcp 转发规则是:2888:22,39081:39080
你可以手动修改。


这个qemu虚拟机镜像有将近一年没更新了,我在考虑要不要砍掉它。
你可以在我砍掉之前,体验一下。

Bean-Xabean Bean
回复 Moe 拥有者
3年前

Lc0rM4.jpg

大概就是上图的情况,砍掉,感觉有点可惜

最近事情太多,但这几天还是用零碎的时间(基本上都是睡觉的时候让它安装系统)把qemu在安卓(骁龙870)平台上的使用情况测试完了,我简单概括一下吧。

按照Moe大佬的说明,如果确实要试用一下带图形桌面的qemu,建议在proot-Docker那个容器里新建qemu虚拟机,因为proot-Docker中的宿主系统是Debian sid,这个版本对于qemu支持最好。

我习惯使用Ubuntu,所以测试的都是Ubuntu系列的桌面,版本均为22.04 LTS。Xubuntu和Ubuntu-MATE性能差不多,但是Ubuntu-MATE针对触摸屏的体验要好一些,Lubuntu性能最好,比另外两个的响应速度快一倍,但是Lubuntu对于虚拟机的支持可能还不完善,安装在最后会报无法弹出光驱的错误。

成功安装Xubuntu和Ubuntu-MATE差不多都得需要至少8个小时左右的时间,进入系统后,启动浏览器的平均响应时间为3.5分钟,总结就是一句话:没法用!我估计没人能忍受这个龟速系统。。。

综上,在安卓上面最好还是放弃带图形桌面的qemu,另外就目前的情况来看,想要在安卓上运行Docker,最简单有效的方式,还是直接使用tmoe-proof的Docker容器,tmoe都已经把环境调试好了,免得自己折腾。

5617340 mo2 1648809770 Moe 拥有者
回复 Bean
3年前

proot 的 磁盘 IO 性能会弱一些, chroot/unshare 不会。
其实我更推荐后者。
我推荐 debian sid 的 qemu-system 的主要原因是它的qemu版本比较新,特性比较全。
理论上,你给 android 手动编译最新版 qemu, 并加上一些特性,它不一定会比 unshare + debian 版 qemu-system 弱啊!
注:在某些情况下,新版的 qemu 的性能可能会比旧版更好。
你可能会从其他地方学到一些配置和加速技巧,但在没有 kvm 或其他特殊加速方案的前提下,这些技巧是有限的。

5617340 mo2 1648809770 Moe 拥有者
回复 Bean
3年前

可以看出来你是在用心回复的。
时间是很宝贵的。
如果你能从中收获到快乐的话,那就是值得的。
如果只是单纯浪费时间的话,那就不值得了。

Moe 置顶等级设置为 3年前
Moe 任务状态待办的 修改为已完成 3年前
Moe 置顶等级 修改为不置顶 3年前

登录 后才可以发表评论

状态
负责人
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
参与者(2)
Bean-Xabean 5617340 mo2 1648809770
1
https://gitee.com/mo2/linux.git
git@gitee.com:mo2/linux.git
mo2
linux
TMOE

搜索帮助