LINUX.ORG.RU

Как грамотно запустить контейнер, чтобы работал Ctrl+C

 , , ,


2

3

Нужно указать в докерфайле какую-нибудь команду, которая ничего не делает. Но чтобы работало завершение по сигналам.

Первое, что пробовал это ENTRYPOINT ["sleep", "infinity"]. Не сработало. sleep игнорирует сигналы. Всякие вариации вроде bash -c "sleep infinity" или bash -c "exec sleep infinity" тоже не работают.

Лучшее, что придумал - ENTRYPOINT ["sh", "-c", "while sleep 1; do true; done"]. Но немного некрасиво - секунду всё равно ждать и крутится там туда-сюда, запускает sleep всё время. И кажись для SIGSTOP не работает, только для SIGINT.

Какой самый классный и короткой способ сделать так, чтобы и по сигналу (SIGINT и SIGSTOP) завершало выполнение, и чтобы в рамках sh работало, и выглядело не монструозно. Через всякие trap-ы и kill-ы и я смогу, но там строк на 10 будет в лучшем случае.

★★★★

Последнее исправление: vbr (всего исправлений: 1)

Я вообще последнее время перестал понимать, что спрашивают регистранты. Может, конечно дело и во мне.

С разных сторон, смотря что надо, можно посоветовать:

  • или docker kill
  • или -it
  • или вообще что-то третье

Но использовать докер-контейнер для "while sleep 1; do true; done - точно неправильно.

vvn_black ★★★★★
()
Ответ на: комментарий от vvn_black

Ну если не понимаешь - спроси. Я отвечу.

Для чего мне использовать докер-контейнер - это уж мне решать. Вроде задачу описал - запустить контейнер, который ничего не делает (но и не завершается, как, наверное, очевидно из сообщения).

docker kill посылает SIGSTOP и через 10 секунд SIGKILL. Мне не нравится ждать 10 секунд.

-it + ctrl+C посылает SIGINT (и больше ничего не посылает).

Основы докера я знаю. Вопрос в данном случае вообще не про докер, а про линукс. Как запустить программу, которая будет «спать» но в то же время завершится при получении сигнала. Используя стандартные юниксовые команды (желательно те, что идут в docker.io/library/alpine:3) в самом минимальном исполнении.

vbr ★★★★
() автор топика
Последнее исправление: vbr (всего исправлений: 2)
Ответ на: комментарий от vvn_black

Обидеть меня может не только лишь каждый. Мало кому удаётся это сделать. Просто не очень люблю классику форумов, когда начинают объяснять, что я не хочу того, что я хочу. А я хочу.

vbr ★★★★
() автор топика
Ответ на: комментарий от vbr

Основы докера я знаю. Вопрос в данном случае вообще не про докер, а про линукс. Как запустить программу, которая будет «спать» но в то же время завершится при получении сигнала. Используя стандартные юниксовые команды (желательно те, что идут в docker.io/library/alpine:3) в самом минимальном исполнении.

Сигнал или передается в процесс и он сам решает как на него реагировать, или ядру, который сам решает что делать с процессом. kill -9 до процесса не доходит, соотв. процесс просто не знает что его пристрелят, это может создавать кучу проблем. Соотв. тебе нужно копать сам докер и смотреть можно ли где-то изменить скорость его завершения…

ИМХО, 10 сек это ни о чем.

soomrack ★★★★★
()
Ответ на: комментарий от soomrack

Докер запускает указанный в ENTRYPOINT процесс с pid 1 и всё. При команде docker stop этому процессу посылается SIGTERM. Ожидается, что при этом процесс завершится. Если он упрямится - то через 10 секунд его прибивает. Вот вопрос в том, как через стандартные тулзы сделать так, чтобы процесс завершался, а не игнорировал получаемые сигналы. Пока все наивные попытки не работают, стандартные тулзы игнорируют сигналы. Работает только та белиберда на шелле.

vbr ★★★★
() автор топика
Ответ на: комментарий от George

Спасибо, может оно и правильней всего будет. Пока хочется попробовать обойтись без установки доп программ, т.к. это больше для отладки нужно, чем для полноценных образов.

vbr ★★★★
() автор топика

Если кто-то будет экспериментировать, то вот конкретные команды:

FROM alpine:3
ENTRYPOINT ["sh", "-c", "trap true TERM; sleep 1 & while wait $!; do sleep 1 & done"]
docker run --rm -it $(docker build -q .)

Нажать Ctrl+C. Должно завершиться сразу.

docker run --rm $(docker build -q .)

в другом терминале

docker container ls
docker container stop inspiring_driscoll

должно завершиться сразу.

vbr ★★★★
() автор топика
Последнее исправление: vbr (всего исправлений: 1)

Про tini тут уже упомянули несколько раз, но никто не упомянул, что оно уже встроено в docker-ce.

Запускай контейнеры с флагом --init, и проблема решена.

MaZy ★★★★★
()
Последнее исправление: MaZy (всего исправлений: 1)