Intereting Posts
Настройте галочку для автоматического переключения между LAN и WLAN Примените цвета к выходу терминала, чтобы выделить URL и другие Как реплицировать основные задачи настройки? Программный центр Ubuntu: не удалось устранить проблемы, у вас были сломанные пакеты Восстановление файловой системы ext4 с поврежденным журналом Удалить символы строки строки из stdout? Несколько строк в одну строку Резервное копирование на уровне байта и файлового уровня Сжатие файлов с помощью p7zip из командной строки Подавить предупреждение версий rbenv, если рубины не установлены Сценарий или команда для перечисления всех каталогов верхнего уровня, содержащих подкаталоги с измененными файлами менее 30 дней Установка свежей арки – текст терминала полностью нечитабелен сразу после загрузки Как разместить / сохранить файл в памяти на linux? Субдомен для Nagios Различные разделы загрузки для двойной загрузки Удалить n минут старый файл в solaris

Тестирование бесконечного цикла в фоновом режиме в Docker?

Я хочу запустить фоновую очередь, работающую в моем образе dockerа:

php artisan queue:work --daemon --sleep=1 --tries=3 & 

Сразу после этого он запускает Apache httpd с приложением PHP laravel . Приложение laravel отправляет push-уведомления в Redis. Работник фоновой очереди собирает сообщения от Redis и отправляет их через службу push-уведомлений.

Это работает и выходит из системы каждую секунду. В случае сбоя фоновой команды я бы хотел ее перезагрузить. Согласно этому ответу https://unix.stackexchange.com/a/223780/72040 я могу бесконечно запускать команду в фоновом режиме, например:

 while true; do php $QUEUE_WORK; done & 

Чтобы проверить это, я запустил свой контейнер с помощью docker run затем выполнил docker exec -it для входа в систему и увидел:

 UID PID PPID C STIME TTY TIME CMD 100000 1 0 0 19:55 ? 00:00:00 httpd -D FOREGROUND 100000 21 1 0 19:55 ? 00:00:00 /bin/sh -e /tmp/scripts/run 100000 22 21 1 19:55 ? 00:00:01 php artisan queue:work --sleep=1 --tries=3 100000 43 1 0 19:55 ? 00:00:00 /usr/bin/cat 100000 50 1 0 19:55 ? 00:00:00 /usr/bin/cat 100000 51 1 0 19:55 ? 00:00:00 /usr/bin/cat 100000 52 1 0 19:55 ? 00:00:00 /usr/bin/cat 100000 53 1 0 19:55 ? 00:00:00 httpd -D FOREGROUND ... 100000 130 0 1 19:57 pts/0 00:00:00 /bin/bash 100000 144 130 0 19:57 pts/0 00:00:00 ps -efww 

Затем я запускаю kill 22 вижу вывод в docker run :

 /tmp/scripts/run: line 10: 22 Killed php $QUEUE_WORK 

Цикл не поддерживает процесс. Я дважды проверил, что цикл – это код, запускаемый в образе. Если у меня есть цикл запустить «эхо х: сон 1», он работает нормально.

Почему цикл не заменяет команду, когда я ее убиваю?

ПРИМЕЧАНИЕ . Приложение развернуто в Kubernetes в виде нескольких модhive с возможностью мониторинга и автоматического перезапуска, если URL-адрес проверки работоспособности httpd возвращает ошибку или время ожидания.

Я не хочу развертывать работников очереди в виде отдельного модуля или контейнера-коляски. Я хочу запускать его как фоновый процесс в контейнере httpd чтобы он делил код приложения с httpd с нулевой конфигурацией.

Я не заинтересован в использовании мониторов процессов или других инструментов или технологий, чтобы «поддерживать жизнь».

Мой вопрос: почему цикл Bash завершает работу при завершении процесса, который он запускает?

Настроить

Я установил следующий Dockerfile :

 $ more Dockerfile From centos ADD run.sh /tmp/run.sh RUN chmod +x /tmp/run.sh ENTRYPOINT ["/tmp/run.sh"] 

Настройте скрипт, run.sh :

 $ cat run.sh while true; do sleep 15 ; echo "background"; done & while true; do sleep 12 ; echo "foreground"; done 

Построил это:

 $ docker build -t sleeper . Sending build context to Docker daemon 7.791 MB Step 1/4 : FROM centos ---> 49f7960eb7e4 Step 2/4 : ADD run.sh /tmp/run.sh ---> b4099de53780 Removing intermediate container 1ce8e3a1dac5 Step 3/4 : RUN chmod +x /tmp/run.sh ---> Running in e410429a6cba ---> 06789467e636 Removing intermediate container e410429a6cba Step 4/4 : ENTRYPOINT /tmp/run.sh ---> Running in ad8b847b505f ---> a2415df63f99 Removing intermediate container ad8b847b505f Successfully built a2415df63f99 

пример

Затем начал это:

 $ docker run -dit sleeper 28c19c338e6e6177529cf989f42c7f14b17f1c705a61f5244d5350f0ab8f8364 

Затем он запускается неоднократно, показывая:

 foreground background foreground background 

Теперь, когда я смотрю его, я вижу, что он не sleep , несмотря на то, что команды sleep со временем «умирают»:

 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 28c19c338e6e sleeper "/tmp/run.sh" About a minute ago Up About a minute focused_lumiere 

Сверху видно, что этот контейнер был загружен более 1 минуты. Вот как выглядит ps auxf внутри контейнера:

 $ ps auxf ... USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 24 0.0 0.1 11828 2964 pts/1 Ss 16:00 0:00 /bin/bash root 58 0.0 0.1 51712 3432 pts/1 R+ 16:01 0:00 \_ ps auxf root 1 0.0 0.1 11692 2572 pts/0 Ss+ 15:58 0:00 /bin/bash /tmp/ root 5 0.0 0.1 11696 2272 pts/0 S+ 15:58 0:00 /bin/bash /tmp/ root 56 0.0 0.0 4368 636 pts/0 S+ 16:01 0:00 \_ sleep 15 root 57 0.0 0.0 4368 664 pts/0 S+ 16:01 0:00 sleep 12 

Теперь, если мы убьём фоновый sleep 15 вот так:

 $ kill 56 

И запустить другой docker ps :

 $ docker ps ... USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 24 0.0 0.1 11828 2964 pts/1 Ss 16:00 0:00 /bin/bash root 60 0.0 0.1 51712 3344 pts/1 R+ 16:01 0:00 \_ ps auxf root 1 0.0 0.1 11692 2572 pts/0 Ss+ 15:58 0:00 /bin/bash /tmp/ root 5 0.0 0.1 11696 2272 pts/0 S+ 15:58 0:00 /bin/bash /tmp/ root 59 0.0 0.0 4368 636 pts/0 S+ 16:01 0:00 \_ sleep 15 root 57 0.0 0.0 4368 664 pts/0 S+ 16:01 0:00 sleep 12 

Мы видим, что цикл while, который защищает наш фоновый sleep 15 , выполнил свою работу и перезапустил еще один sleep 15 .