32 位可执行文件不在 Docker 容器中休眠

Posted

技术标签:

【中文标题】32 位可执行文件不在 Docker 容器中休眠【英文标题】:32-bit Executables Not Sleeping Inside a Docker Container 【发布时间】:2021-07-11 00:55:02 【问题描述】:

Windows 10 是主机系统。 Docker Desktop 3.2.2(WSL2 集成)。 WSL2 Ubuntu 20.04。

#include <unistd.h>
int main()  sleep(1); return 0; 

三种不同方式编译代码:

gcc -o foobar-64 foobar.c
gcc -mx32 -o foobar-3264 foobar.c
gcc -m32 -o foobar-32 foobar.c

一切运行良好。所有可执行文件都休眠一秒钟。

现在在 Docker 中尝试同样的事情:

docker pull ubuntu:20.04
docker run --rm --interactive --tty ubuntu:20.04 bash
# then once inside: apt update && apt install build-essential g++-multilib

做同样的事情。只有前两个可执行文件正常睡眠。 “纯 32 位可执行文件”没有。它立即返回。

root@f24cf548c966:~# time ./foobar-64

real    0m1.002s
user    0m0.001s
sys     0m0.000s
root@f24cf548c966:~# time ./foobar-3264

real    0m1.003s
user    0m0.002s
sys     0m0.000s
root@f24cf548c966:~# time ./foobar-32

real    0m0.001s
user    0m0.001s
sys     0m0.000s

我没有运行 Linux 的 VM 来试用它,看看它是否是 WSL2 的东西。

有什么线索吗?

[编辑]

所以我想在程序上尝试“strace”并揭示了一些有趣的东西......

容器外:

clock_nanosleep_time64(CLOCK_REALTIME, 0, tv_sec=1, tv_nsec=0, 0xffd2f09c) = 0

容器内:

clock_nanosleep_time64(CLOCK_REALTIME, 0, tv_sec=1, tv_nsec=0, 0xffd2339c) = -1 EPERM (Operation not permitted)

容器内外我都验证了可执行文件类型:

foobar-32: ELF 32-bit LSB shared object, Intel 80386, ...

【问题讨论】:

已更新以添加此行为在 AWS 中运行的基于 Ubuntu 20.04 的 EC2 中是一致的,因此它不是 WSL2 的事情。 如果从sleep(1)更改为sleep(10),每个进程运行多长时间? 如果你添加一些 printfs 到 foobar-32 以确保它真正运行呢?检查它的退出代码?试试 nanosleep 并检查它的返回值? @selbie 当我改变时间时,错误的程序没有变化。请参阅我上面的编辑了解原因。 @NateEldredge 代码运行。这只是一个显示错误的精简示例。有关更多信息,请参阅我上面的编辑。 【参考方案1】:

显然这是 Docker 的事情。 EPERM 的事情引发了更多的搜索,我找到了这个

https://unix.stackexchange.com/questions/598471/docker-container-shows-sleep-cannot-read-realtime-clock-operation-not-permit

其中谈到了使用 --privileged 运行,它确实“解决”了问题该帖子中更有趣的链接是

https://github.com/moby/moby/commit/89fabf0f241292e929fbb2fbb794d58d8d697ab5

其中谈到了对默认 seccomp 的更新以添加 64 位 time_t 系统调用(其中之一是 clock_nanosleep_time64

必须弄清楚如何在我的上下文中使用这些信息(AWS EKS 中的 AMI),但至少这不是什么新鲜事。

【讨论】:

以上是关于32 位可执行文件不在 Docker 容器中休眠的主要内容,如果未能解决你的问题,请参考以下文章

32位可执行文件的C#问题

为啥我能够将 x64 程序集加载到 AnyCPU Prefer 32 位可执行文件中?

在 Open Suse Leap 15.1 上对 32 位可执行文件的 iconv_open 支持

C ++ 32位与64位可执行符号[关闭]

为啥 cx_Freeze 在 64 位 Debian Linux 上运行时使 32 位可执行?

在批处理文件中休眠