我如何从 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
....
从 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
....