докер запустить-ограничение процессора=10 не убить процесс Java по истечении времени неактивности.


Я хочу убедиться,что процесс будет убит через 10 секунд процессорного времени. Команда docker run принимает флаг --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 или ': 'работает. Или даже произвольное слово, которое печатает "команда не найдена", также работает.

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: Аналогично использованию no-op (:), вызов процесса со временем также приводит к тому, что процесс будет убит точно после превышения времени процессора.

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

1 ответ:

После некоторогоэкспериментирования я перечитал исходный вопрос и также принял во внимание тот факт, что он не зависит от типа запускаемой программы, то есть Java, C++ и т. д.: причина, по которой он работает в одном случае (при вызове с помощью bash -c), а не при прямом вызове, заключается в том, что ulimit является bash, построенной в команде, и документы для docker run являются не совсем прозрачными об этом.