Назад | Перейти на главную страницу

Правильный способ сохранить запуск контейнера докеров, когда он используется для периодических задач

У меня есть докер-контейнер с установленным и настроенным ПО.

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

Что хочу - возможность запускать какую-то команду в зависимости от внешних событий. лайк:

docker exec mysupercont /path/to/mycommand -bla -for

и

docker exec mysupercont /path/to/myothercommand 

Но "exec" невозможно, когда контейнер остановлен, а также у этого контейнера есть некоторые "рабочие" данные внутри, которые используются для этих команд, поэтому я не могу использовать

docker run ...

каждый раз, потому что он воссоздает контейнер из изображения и уничтожает мои данные.

Каков «правильный» и «лучший» способ поддерживать работу такого контейнера? Какую команду я могу запустить внутри?

Не нужно выполнять каждый раз docker run.

docker run фактически представляет собой последовательность из двух команд: «создать» и «запустить».

При запуске контейнера необходимо указать "-it":

-i, --interactive = false Оставить STDIN открытым, даже если он не подключен
-t, --tty = false Назначить псевдо-TTY

Пример:

docker run -it debian:stable bash

После завершения работы команда указывается при запуске (в моем примере bash). Например, вы выполняете «выход». Контейнерные остановки:

CONTAINER ID        IMAGE                      COMMAND                CREATED             STATUS                     PORTS               NAMES
1329c99a831b        debian:stable              "bash"                 51 seconds ago      Exited (0) 1 seconds ago                       goofy_bardeen

Теперь ты можешь начать снова

docker start 1329c99a831b

Контейнер запускается и снова выполняет команду «bash».
Подключитесь к этому сеансу "bash" с помощью команды

docker attach 1329c99a831b

Подводить итоги: вы должны понимать разницу между run и start контейнер.
Кроме того, посмотрите на документация на роль параметров "-i t" и "-d"для" Бега "

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

Но последний комментарий Таранаки, использование '-itd', похоже, является тем, что заказал докер.

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

Поскольку вы упомянули периодические задачи и, вероятно, используете что-то вроде cron из-за того, как вы хотите использовать docker exec, У меня есть только лекарство для тебя. По крайней мере, я сделал что-то подобное.

  1. Dockerfile

    FROM <some base>
    CMD tail -f /dev/null
    
  2. Беги как обычно docker run -d .... (Я использовал docker-compose)

  3. Настройте crontab на хост-машинах, например:

    * * * * * docker exec mysupercont foo >> /var/log/foo.log 2>&1
    * * * * * docker exec mysupercont bar >> /var/log/bar.log 2>&1
    

Я считаю это решение хорошим, поскольку мы можем полагаться на древний и проверенный crontab в довольно стандартной среде Linux, в то время как Docker обрабатывает более экзотические зависимости и переменные среды вашей бизнес-логики. Вы также можете установить некоторые ограничения, если ваши периодические задачи застревают и имеют утечки памяти или что-то еще.

Tail будет время от времени вызывать некоторые файловые операции.

Вот мое решение уснуть вечно без каких-либо побочных эффектов.

# Ah, ha, ha, ha, stayin' alive...
while true; do :; done & kill -STOP $! && wait $!

Как это устроено

while true; do :; done & # do nothing(:) in background, in an endless loop
kill -STOP $!            # stop the background process of doing nothing
wait $!                  # wait forever, because doing nothing process is stopped