Следующий сценарий довольно прост: он порождает count
задач, а затем ожидает их. Если count
больше 545, он работает нормально, когда выполняется вне контейнера docker, но терпит неудачу при выполнении внутри. wait
внезапно сообщает, что самый старый PID задачи неизвестен. Увеличение count
на единицу приведет к тому, что wait
сообщит об этой же ошибке для еще одной задачи и так далее. Обратите внимание, что все порожденные задачи действительно выполняются и завершаются правильно.
test.sh
count=546
pids=()
for (( index=0; index < count; ++index ))
do
sleep 2 &
pid=${!}
pids+=(${pid})
#echo "spawned task #${index} PID ${pid}" 1>&2
done
echo "done spawning" 1>&2
sleep 5
for (( index=0; index < count; ++index ))
do
pid=${pids[${index}]}
wait ${pid}
code=${?}
if [[ 0 -eq ${code} ]]
then
: #echo "reaped task #${index} PID ${pid}" 1>&2
else
echo "task #${index} PID ${pid} exited with code ${code}" 1>&2
#exit ${code}
fi
done
echo "done reaping" 1>&2
exit 0
Dockerfile
FROM ubuntu:18.04
COPY test.sh /
RUN bash /test.sh
docker build --no-cache "${PWD}"
завершено создание
тест. sh: строка 15: ожидание: pid 8 не является дочерним по отношению к этой оболочке
PID 8 задачи # 0 завершен с кодом 127
завершено получение
онлайн-компилятор
И хост, и контейнер используют ubuntu: 18.04, bash 4.4, docker 18.09.2 или 19.03.6 (пробовал в разных системах).
Поскольку проблема возникает только после того, как это странно указано c количество порожденных задач, я подозреваю, что он должен достигать какого-то неявного ограничения на что-то. Bash manual даже перечисляет переменную среды CHILD_MAX
как такое ограничение, однако установка большого значения путем запуска скрипта, такого как CHILD_MAX=8190 bash ./test.sh
, ничего не меняет. Более того, добавление jobs -l 2>&1
до / после sleep 5
показывает, что все порожденные задачи правильно подтверждены, у них указаны правильные PID и статусы (хотя wait
сообщит, что даже больше задач не принадлежат текущей оболочке). Я также пробовал проверить некоторые потенциально связанные ограничения, но все они, похоже, даже не близки (getconf -a | grep CHILD_MAX
дает 128275, cat "/proc/sys/kernel/pid_max" 1>&2
дает 32768). Есть идеи, что здесь происходит и как это исправить?