Остановить контейнер Docker после выполнения кода

Чтобы получить более глубокое представление о Docker, я создал файл dockerfile, который выполняет скрипт Python. Работает нормально, но после выполнения скрипта контейнер вылетает. Как я могу изменить свой файл докеров, чтобы уничтожить контейнер после выполнения, вместо того, чтобы позволить контейнеру постоянно падать и перезапускаться?

Докерфайл:

FROM python:3

ADD aa.py /

CMD [ "python", "./aa.py" ]

Питон:

print('Hello!')

Сообщение об ошибке:

2017-06-14 11:37:09 [CELL/0] OUT Starting health monitoring of container
2017-06-14 11:37:09 [APP/PROC/WEB/0] OUT Hello!
2017-06-14 11:37:09 [APP/PROC/WEB/0] OUT Exit status 0
2017-06-14 11:37:09 [CELL/0] OUT Exit status 143
2017-06-14 11:37:09 [CELL/0] OUT Destroying container
2017-06-14 11:37:09 [API/0] OUT Process has crashed with type: "web"
2017-06-14 11:37:09 [API/0] OUT App instance exited with guid 6fdede46-6751-4725-ad78-b76262dbe701 payload: {"instance"=>"", "index"=>0, "reason"=>"CRASHED", "exit_description"=>"2 error(s) occurred:\n\n* 2 error(s) occurred:\n\n* Codependent step exited\n* cancelled\n* cancelled", "crash_count"=>4, "crash_timestamp"=>1497433029411246770, "version"=>"98e2a035-e38f-4169-95fb-2701c8486e9c"}
2017-06-14 11:37:09 [CELL/0] OUT Successfully destroyed container
2017-06-14 11:38:31 [CELL/0] OUT Creating container

person jz22    schedule 14.06.2017    source источник
comment
Как вы начали свой контейнер? Вы можете использовать docker run --rm mypython, который удалит ваш контейнер после выполнения скрипта.   -  person lvthillo    schedule 14.06.2017
comment
Я использую Docker на CloudFoundry. Через пользовательский интерфейс я набрал репозиторий Docker Hub и запустил его.   -  person jz22    schedule 14.06.2017
comment
Я никогда не использовал cloudfundry, поэтому не могу вам с этим помочь. Я подозреваю, что он пытается перезапуститься из-за cf, потому что просто в докере этот контейнер запустится, покажет сообщение и остановится. Опция --rm удалит контейнер после запуска. Я не могу помочь вам воспроизвести это в ср.   -  person lvthillo    schedule 14.06.2017


Ответы (1)


Примечание. Значение по умолчанию CMD для python:3 равно python3.

код выхода 143 означает SIGTERM как здесь. Это что отправляет docker.
Итак, вам нужно чтобы ваше приложение python3 корректно обрабатывало сигнал SIGTERM

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

OP добавляет в комментариях:

Тем временем я обнаружил, что обработка SIGTERM в среде Docker работает отлично.

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

Я преобразовал свой скрипт в REST-сервер, используя фреймворк flask. Теперь он всегда работает, но выполняет свою задачу только при вызове через свой URL-адрес.

person VonC    schedule 14.06.2017
comment
Спасибо. Когда посылается сигнал? После того, как скрипт выполнен? - person jz22; 15.06.2017
comment
Я пробовал решения, но после обработки SIGTERM он снова падает. - person jz22; 15.06.2017
comment
@user3080315 user3080315 сигнал отправляется, когда основной процесс завершается и контейнер останавливается. Если ваше приложение не обрабатывает это правильно, вы можете остаться с зомби-процессами (stackoverflow.com/a/33119321/6309). Вот почему с докером 1.13 или более поздней версии у вас есть docker run --init: stackoverflow.com/a/39593409/6309 - person VonC; 15.06.2017
comment
@user3080315 user3080315 Если он все еще падает, когда докер регистрируется, чтобы увидеть, есть ли какие-либо дополнительные подсказки. - person VonC; 15.06.2017
comment
@user3080315 user3080315 Я проверю это (и я проголосовал за это), но я надеюсь, что эксперт по Python тоже посмотрит;) - person VonC; 15.06.2017
comment
Я только что заметил, что после реализации обработчика SIGNIT он больше не говорит код выхода 143. Теперь он говорит, что произошел сбой с кодом выхода 0 и с типом web. - person jz22; 15.06.2017
comment
@ user3080315 Это кажется ожидаемым: 143 — это специальный код сигнала, связанный с SIGTERM (128 + 15). SIGINT (прерывается с клавиатуры) — 130 (128+2): support. ersa.edu.au/hpc/pbs-exit-codes.html - person VonC; 15.06.2017
comment
Но он падает, хотя я обработал сигтерм и впоследствии создал новый контейнер. - person jz22; 15.06.2017
comment
@user3080315 user3080315 Точно, поэтому я следую вашему другому вопросу, который касается этого: заголовок stackoverflow.com/questions/44567981/ - person VonC; 15.06.2017
comment
@ user3080315 вы решили свой другой вопрос, который вы только что удалили? - person VonC; 06.07.2017
comment
Тем временем я обнаружил, что обработка SIGTERM в среде Docker работает отлично. Однако использование того же кода в Docker на CloudFoundry не предотвращает сбой контейнера. В CloudFoundry вам нужно приложение, которое всегда работает, а не просто выполняет задачу, а затем останавливается, как это делает скрипт. Даже остановка без ошибок определяется как сбой в CloudFoundry. Я преобразовал свой скрипт в REST-сервер, используя фреймворк flask. Теперь он всегда работает, но выполняет свою задачу только при вызове через свой URL-адрес. - person jz22; 06.07.2017
comment
@ user3080315 хороший улов! Я включил ваш комментарий в ответ для большей наглядности. - person VonC; 06.07.2017