我如何从 Docker 容器中检测 QEMU 仿真?

How do I detect QEMU emulation from within a Docker container?

从 docker 容器中(在我的例子中 运行ning 基于 Debian Busty 的图像)我如何检测它是否在 QEMU 仿真下 运行ning(就像在 ARM 上发生的那样)适用于 AMD64 图像的 Mac)?

从非 docker 的角度来看,我看到 cpuinfo 可能会浮出水面的建议,但是当 运行 从我的容器内部时,它不会产生任何与 QEMU 直接相关的东西:

$ docker run -it --entrypoint /bin/bash debian-buster-based-amd64-image

WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested

root@c93f6a8ec754:/app# cat /proc/cpuinfo
processor   : 0
BogoMIPS    : 48.00
Features    : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 asimddp sha512 asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp flagm2 frint
CPU implementer : 0x00
CPU architecture: 8
CPU variant : 0x0
CPU part    : 0x000
CPU revision    : 0

processor   : 1
BogoMIPS    : 48.00
Features    : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 asimddp sha512 asimdfhm dit uscat ilrcpc flagm ssbs sb paca pacg dcpodp flagm2 frint
CPU implementer : 0x00
CPU architecture: 8
CPU variant : 0x0
CPU part    : 0x000
CPU revision    : 0

# ...etc

Docker QEMU 不支持我的容器中的某些功能所依赖的功能(inotify 文件系统事件)- 我希望在容器内切换行为以避免发生崩溃图书馆试图使用它。

检测容器是否运行仿真的方法有很多,但最可靠的方法是使用识别入口点是否被仿真。

创建容器时,入口点将变为 PID 1。Docker 用于 qemu 仿真的机制将检测到入口点用于不同的体系结构,并将让模拟器来模拟架构。您可以阅读有关 .

中使用的机制的更多信息

由于将模拟入口点,因此进程名称将替换为 qemu-xxxx,其中 xxxx 是将被模拟的体系结构。如果我们调用 ps -uax,我们可以确定我们的入口 pint 过程是否被替换为 qemu,如下例所示:

docker run -it --entrypoint /bin/bash amd64/ubuntu                                                                                                                                  
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
root@043bd4f57ca8:/# ps -uax
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.7  0.1 149280 13804 pts/0    Ssl  07:08   0:00 /usr/bin/qemu-x86_64 /bin/bash /bin/bash
root        22  0.0  0.1 150404  9564 ?        Rl+  07:04   0:00 ps -uax

利用此知识检测我们是否被模仿的一种简单方法是从 PID 1 获取 pmap 并检查响应中是否存在 qemu(计数qemu 的大于 0)

root@043bd4f57ca8:/# pmap 1 | grep qemu | wc -l
5

pmap 将报告进程的内存映射,binary/library 从中创建内存段,在这种情况下的结果如下:

root@043bd4f57ca8:/# pmap 1
1:   /usr/bin/qemu-x86_64 /bin/bash /bin/bash
0000000000200000    724K r---- qemu-x86_64
00000000002c4000   1652K r-x-- qemu-x86_64
0000000000470000    236K rw--- qemu-x86_64
00000000004ba000     84K rw--- qemu-x86_64
00000000004cf000    128K rw---   [ anon ]
0000000017053000      4K -----   [ anon ]
0000000017054000     16K rw---   [ anon ]
0000004000000000    180K r---- bash
000000400002d000    708K r---- bash
00000040000de000    220K r---- bash
0000004000115000     16K r---- bash
0000004000119000     36K rw--- bash
0000004000122000    460K rw---   [ anon ]
000000400112c000      4K -----   [ anon ]
000000400112d000   8192K rw---   [ anon ]
000000400192d000      4K r---- ld-2.31.so
000000400192e000    140K r---- ld-2.31.so
0000004001951000     32K r---- ld-2.31.so
0000004001959000      4K -----   [ anon ]
000000400195a000      4K r---- ld-2.31.so
000000400195b000      4K rw--- ld-2.31.so
000000400195c000     12K rw---   [ anon ]
0000004001961000     56K r---- libtinfo.so.6.2
000000400196f000     60K r---- libtinfo.so.6.2
000000400197e000     56K r---- libtinfo.so.6.2
000000400198c000     16K r---- libtinfo.so.6.2
0000004001990000      4K rw--- libtinfo.so.6.2
0000004001991000      8K rw---   [ anon ]
0000004001993000      4K r---- libdl-2.31.so
0000004001994000      8K r---- libdl-2.31.so
0000004001996000      4K r---- libdl-2.31.so
0000004001997000      4K r---- libdl-2.31.so
0000004001998000      4K rw--- libdl-2.31.so
0000004001999000    136K r---- libc-2.31.so
00000040019bb000   1504K r---- libc-2.31.so
0000004001b33000    312K r---- libc-2.31.so
0000004001b81000     16K r---- libc-2.31.so
0000004001b85000      8K rw--- libc-2.31.so
0000004001b87000     28K rw---   [ anon ]
0000004001b90000     12K r---- libnss_files-2.31.so
0000004001b93000     28K r---- libnss_files-2.31.so
0000004001b9a000      8K r---- libnss_files-2.31.so
0000004001b9c000      4K r---- libnss_files-2.31.so
0000004001b9d000      4K rw--- libnss_files-2.31.so
0000004001b9e000     24K rw---   [ anon ]
0000ffff78916000   1808K rw---   [ anon ]
0000ffff78ada000 131068K rwx--   [ anon ]
0000ffff80ad9000      4K -----   [ anon ]
0000ffff80ada000   1196K rw---   [ anon ]
0000ffff80c05000      8K -----   [ anon ]
0000ffff80c07000    140K rw---   [ anon ]
0000ffff80c2a000      8K r----   [ anon ]
0000ffff80c2c000      4K r-x--   [ anon ]
0000ffffd61bc000    132K rw---   [ stack ]
 total           149536K

请注意,这与我们想要在 Intel 下模拟 ARM 的情况一样有效,如本例所示:

root@9bd90133ebee:/# ps -uax
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.6  0.1 151208 13560 pts/0    Ssl  06:57   0:00 /usr/bin/qemu-aarch64 /usr/bin/bash

root@9bd90133ebee:/# pmap 1
1:   /usr/bin/qemu-aarch64 /usr/bin/bash
0000000000200000   1408K r---- qemu-aarch64
0000000000360000   3304K r-x-- qemu-aarch64
000000000069a000    408K rw--- qemu-aarch64
0000000000700000     48K rw--- qemu-aarch64
000000000070c000    136K rw---   [ anon ]
0000000001d5a000      4K -----   [ anon ]
0000000001d5b000     12K rw---   [ anon ]
0000005500000000   1132K r---- bash
....