docker 运行 --ulimit cpu=10 超时后不杀死 java 进程

docker run --ulimit cpu=10 does not kill java process after timeout

我想确保进程在 CPU 时间 10 秒后被终止。 Docker 运行 命令接受应该执行此操作的标志 --ulimit cpu=10

然而,当我使用这个 运行 java 命令时,ulimit 设置将被忽略。具有无限循环的 java 过程甚至在 10 秒后仍在继续(实际上是几分钟,直到我杀死它) 这是我用来测试的命令。

docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
java -cp /classes/ InfiniteLoop

而不是直接调用 java,如果我启动 bash 然后 运行 java c,它会按预期工作。

docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
bash -c 'date; java -cp /classes/ InfiniteLoop'

为什么直接调用 java 程序不考虑 ulimit 选项?

编辑 1:

$ docker --version
Docker version 1.9.1, build a34a1d5

java 程序是,InfiniteLoop.java

import java.util.*;

class InfiniteLoop {
  public static void main(String[] args) throws Exception {
    for (long i = 0; i < 1000_000_000_000L; i++) {
      if (i % 1_000_000_000 == 0) {
        System.out.println(new Date() + ", i = " + i);
      }
    }
  }
}

编辑 2: 以下也不起作用。也就是说,只有 java 在 bash.

中执行
docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
bash -c 'java -cp /classes/ InfiniteLoop'

但是,添加任何 noop 或“:”命令都有效。甚至打印 "command not found" 的任意单词也可以。

docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
bash -c ':; java -cp /classes/ InfiniteLoop'

这也行。

docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
bash -c 'ArbirtraryCommandNotFound; java -cp /classes/ InfiniteLoop'

编辑 3: 与使用空操作 (:) 类似,使用时间调用进程也会使进程恰好在超过 CPU 时间后被杀死。

docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
bash -c 'time java -cp /classes/ InfiniteLoop'

经过一些 experimenting I re-read the original question and also took into account the fact that it is independent of the type of program being launched, that is, Java, C++, etc.: the reason why it works in the one case (when invoked with bash -c) and not when you directly invoke it is that ulimit is a bash built in command and the docs for docker run are not entirely transparent about it.