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


41

У мене є контейнер docker з встановленим і налаштованим програмним забезпеченням.

Немає жодної програми, яку слід запускати / запускати постійно.

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

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

і

docker exec mysupercont /path/to/myothercommand 

Але "exec" неможливий при зупинці контейнера, а також у цьому контейнері є деякі "робочі" дані, які використовуються для цих команд, тому я не можу використовувати

docker run ...

щоразу, тому що він відтворює контейнер із зображення та знищує мої дані.

Який "правильний" та "найкращий" спосіб зберегти такий контейнер? Яку команду можна запустити всередину?


Це дуже добре пояснене питання. Дивіться ще один подібний пост тут .
Грант Лі

1
docker run -d --name=name container tail -f /dev/null
парі

Відповіді:


46

Вам не потрібно виконувати кожен раз docker run.

docker run насправді є послідовністю двох команд: "створити" та "запустити".

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

-i, --інтерактивний = хибний Тримайте 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" для "Виконання"


1
ага, я це розумію. Питання було: мені нічого не потрібно запускати всередині контейнера, але мені потрібно тримати його в стані "run". Отже, ваша відповідь - використовувати bash для збереження контейнера в робочому стані?
Корявін Іван

Так. Процес, який ви вказали під час виконання, повинен тривати до контейнера, щоб він продовжував працювати. Найпростіший приклад - баш. Можливо, вам буде найпростішим способом запустити контейнер з "-d" та підключитись до нього за потребою за допомогою docker attach ID. Вийти з цього сеансу, не закінчуючи bash, ви можете скористатисяCTRL-p CTRL-q
MSemochkin

Процес, який ви вказуєте під час запуску контейнера, отримує PID 1. Відповідно, контейнер просто не може працювати без нього ☺
MSemochkin

Мій досвід запуску і вкладення (або починати з -ai) полягає в тому, що швидке та інтерактивне редагування вашого командного рядка не відображається. EG tty не відображає і не повторюється.
dlamblin

1
Це витончено. Зауважте, що якщо ви хочете запустити контейнер у фоновому режимі, не запускаючи його вручну заново (скажімо, якщо ви запускаєте веб-службу), використовуйте параметри '-itd' та CTRL-p CTRL-q для від'єднання, не зупиняючи контейнер.
taranaki

6

Весь бізнес про те, чи можна запустити зупинений контейнер чи ні, залежить від того, як контейнер був створений спочатку, тобто запускається. Якщо ви запустили команду, яка закінчилася, або ви виходите з інтерактивної команди, наприклад, bash, ви не можете запустити, перезапустити або виконати зупинений контейнер. Все, що ви можете зробити - це видалити його. Це мотлох.

Але останній коментар таранакі, використовуючи "-itd", здається, те, що докер наказав.

Контейнер продовжує працювати, і ви можете виконувати все, що завгодно, і ви можете зупинити, запустити або перезапустити контейнер. Звичайно, це лише попередня знахідка, заснована на іміджі альпійців. Зауважте, якщо ви приєднаєте до контейнера, він зупиниться, коли ви вийдете, але ви можете його запустити заново.


3
+1 "здається, те, що замовив докер" :-)
Метт Олександр

5

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

  1. Докерфайл

    FROM <some base>
    CMD tail -f /dev/null
    
  2. Запустити зі звичайним docker run -d ....(я використовував docker-compose)

  3. Налаштуйте хост-машини, наприклад:

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

Мені здається, що це рішення приємно, оскільки ми покладаємось на стародавній та перевірений crontab у досить Linux-середовищі за замовчуванням, в той час як Docker обробляє більш екзотичні деп-файли та змінні середовища. Ви також можете встановити деякі обмеження, якщо ваші періодичні завдання застрягають і є витоки пам’яті чи що завгодно.


0

Хвіст все ще час від часу спричиняє деякі файлові операції.

Ось моє рішення спати вічно, без побічних ефектів.

# 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

1
важко зрозуміти, що це робить. чому б просто не спати 3650d
Пітер

1
Ви маєте рацію, сон, певно, спрацює так само добре, як і моє рішення, однак сон у підсумку закінчиться :-D PS: Я додам кілька коментарів, щоб зробити своє рішення легко зрозуміти.
qoomon
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.