I want to make sure the process gets killed after 10 seconds of CPU time. Docker run command accepts the flag --ulimit cpu=10
that is supposed to do that.
However when I run java command using this, the ulimit setting is ignored. The java process with infinite loop continues even after 10s (actually for minutes until I kill it) Here is the command I used to test.
docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
java -cp /classes/ InfiniteLoop
Instead of invoking java directly, if I start bash and then run java c, it works as expected.
docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
bash -c 'date; java -cp /classes/ InfiniteLoop'
Why does invoking java program directly does not respect ulimit option?
Edit 1:
$ docker --version
Docker version 1.9.1, build a34a1d5
The java program is, 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);
}
}
}
}
Edit 2: The following doesn't work either. That is, with only java executed in the bash.
docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
bash -c 'java -cp /classes/ InfiniteLoop'
But, adding any noop or ':' command works. Or even an arbitrary word that prints "command not found" also works.
docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
bash -c ':; java -cp /classes/ InfiniteLoop'
and this works too.
docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
bash -c 'ArbirtraryCommandNotFound; java -cp /classes/ InfiniteLoop'
Edit 3: Similar to using the no-op (:), invoking the process with time also makes the process to be killed exactly after the CPU time is exceeded.
docker run --rm -i -v /usr/local/src:/classes --ulimit cpu=10 java:8 \
bash -c 'time java -cp /classes/ InfiniteLoop'