通过入口点启动时,用于Docker容器的100%CPU

时间:2019-08-01 07:19:02

标签: c++ docker docker-stack

我们编写了一个小型C ++应用程序,主要通过ZeroMQ对其他进程进行一些监督。因此,大多数情况下,应用程序处于空闲状态,并定期发送和接收一些请求。

我们基于ubuntu构建了一个docker映像,该映像仅包含此应用程序,一些依赖项和一个entrypoint.sh。入口点基本上以/bin/bash运行,根据环境变量处理一些配置文件,然后通过exec启动应用程序。

现在这是奇怪的部分。当我们在没有docker的情况下手动启动应用程序时,CPU使用率接近0%。当我们启动与docker image相同的应用程序时,CPU使用率将达到100%,并恰好阻塞了一个CPU内核。

要了解正在发生的情况,我们将图像的入口点设置为/bin/yes(只是为了确保容器继续运行),然后在正在运行的容器内启动bash。从那里开始,我们手动启动entrypoint.sh,CPU再次变为0%。

所以我们想知道什么会导致这种情况。我们需要添加到Dockerfile中以防止这种情况吗?


这是strace生成的一些输出。我用strace -p <pid> -f -c并等待了五分钟来收集一些见解。

1。在docker run(100%CPU)下运行

strace: Process 12621 attached with 9 threads
strace: [ Process PID=12621 runs in x32 mode. ]
[...]

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 71.26   17.866443         144    124127           nanosleep
 14.40    3.610578       55547        65        31 futex
 14.07    3.528224        1209      2918           epoll_wait
  0.10    0.024760        4127         6         1 restart_syscall
  0.10    0.024700           0     66479           poll
  0.05    0.011339           4      2902         3 recvfrom
  0.02    0.005517           2      2919           write
  0.01    0.001685           1      2909           read
  0.00    0.000070          70         1         1 connect
  0.00    0.000020          20         1           socket
  0.00    0.000010           1        18           epoll_ctl
  0.00    0.000004           1         6           sendto
  0.00    0.000004           1         4           fcntl
  0.00    0.000000           0         1           close
  0.00    0.000000           0         1           getpeername
  0.00    0.000000           0         1           setsockopt
  0.00    0.000000           0         1           getsockopt
------ ----------- ----------- --------- --------- ----------------
100.00   25.073354                202359        36 total

2。使用虚拟入口点和docker exec(0%CPU)运行

strace: Process 31394 attached with 9 threads
[...]
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 67.32   12.544007         102    123355           nanosleep
 14.94    2.784310       39216        71        33 futex
 14.01    2.611210         869      3005           epoll_wait
  2.01    0.373797           6     66234           poll
  1.15    0.213487          71      2999           recvfrom
  0.41    0.076113       15223         5         1 restart_syscall
  0.09    0.016295           5      3004           write
  0.08    0.014458           5      3004           read
------ ----------- ----------- --------- --------- ----------------
100.00   18.633677                201677        34 total

请注意,在第一种情况下,我早一点开始strace,所以有一些不同的调用都可以追溯到初始化代码。

我唯一能找到的是使用Process PID=12621 runs in x32 mode.时的行docker run。这可能是个问题吗?

还请注意,在两次测量中,过程运行5分钟时,总运行时间约为20秒。


有关100%CPU情况的一些进一步调查。我用top -H -p <pid>检查了该进程,只有父进程使用100%CPU,而子线程大部分都处于空闲状态。但是当在父进程上调用strace -p <pid>时,我可以验证该进程没有执行任何操作(不生成任何输出)。

所以我确实有一个进程正在使用我的CPU的整个核心,而完全不执行任何操作。

1 个答案:

答案 0 :(得分:1)

事实证明,该软件的某些遗留部分正在等待while循环中的控制台输入:

while (!finished) {
  std::cin >> command;
  processCommand(command)
}

因此,在本地运行docker exec时,此方法工作正常。但是由于可执行文件是作为docker服务启动的,因此没有控制台。因此std::cin是非阻塞的,并立即返回。这样,我们创建了一个无休止的无休止循环,这自然会导致100%的CPU使用率。

感谢@Botje指导我们完成调试过程。