vagrant@ubuntu:~$ sudo docker pull ubuntu > /dev/null
vagrant@ubuntu:~$ sudo docker run -d ubuntu sleep 60
0bd80651c6f97167b27f4e8df675780a14bd9e0a5c3f8e5e8340a98fc351bc64
vagrant@ubuntu:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
0bd80651c6f9 ubuntu "sleep 60" 15 seconds ago Up 12 seconds distracted_kalam
vagrant@ubuntu:~$ sleep 60
vagrant@ubuntu:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
vagrant@ubuntu:~$ sudo docker ps -a | grep ubuntu
0bd80651c6f9 ubuntu "sleep 60" 4 minutes ago Exited (0) 3 minutes ago distracted_kalam
В случае с бэкапам – это норма, а в случае с приложениями, которые не должны завершаться – нет. Типичный прием – веб-сервер. Самое простое в таком случае заново рестартовать его:
vagrant@ubuntu:~$ sudo docker run -d –restart=always ubuntu sleep 10
c3bc2d2e37a68636080898417f5b7468adc73a022588ae073bdb3a5bba270165
vagrant@ubuntu:~$ sleep 30
vagrant@ubuntu:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
c3bc2d2e37a6 ubuntu sleep 10" 46 seconds ago Up 1 second
Мы видим, что, когда контейнер падает – он рестартует. Как результат – у нас всегда приложение в двух состояниях – поднимается или поднято. Если веб-сервер падает от какой-то редкой ошибки – это норма, но, скорее всего, ошибка в обработке запросов, и он будет падать на каждом таком запросе, а в мониторинге мы увидим поднятый контейнер. Такой веб-сервер лучше мёртвый, чем наполовину живой. Но, при этом нормальный веб-сервер может не стартануть из-за редких ошибок, например, из-за отсутствия подключения к базе данных из-за нестабильности сети. В таком случает, приложение должно уметь обрабатывать ошибки и завершаться. А в случае падения из-за ошибок кода – не перезапускать, чтобы увидеть неработоспособность и отправить на починку разработчикам. В случает же плавающей ошибки можно попробовать несколько раз:
vagrant@ubuntu:~$ sudo docker run -d –restart=on-failure:3 ubuntu sleep 10
056c4fc6986a13936e5270585e0dc1782a9246f01d6243dd247cb03b7789de1c
vagrant@ubuntu:~$ sleep 10
vagrant@ubuntu:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3bc2d2e37a6 ubuntu "sleep 10" 9 minutes ago Up 2 seconds keen_sinoussi
vagrant@ubuntu:~$ sleep 10
vagrant@ubuntu:~$ sleep 10
vagrant@ubuntu:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3bc2d2e37a6 ubuntu "sleep 10" 10 minutes ago Up 9 seconds keen_sinoussi
vagrant@ubuntu:~$ sleep 10
vagrant@ubuntu:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3bc2d2e37a6 ubuntu "sleep 10" 10 minutes ago Up 2 seconds keen_sinoussi
Другим аспектом является то, когда считать контейнер умершим. По умолчанию – это падание процесса. Но, далеко, не всегда приложение само падает в случае ошибки, чтобы дать контейнеру его перезапустить. Например, сервер может быть разработан неправильно и пытаться во время своего запуска скачать необходимые библиотеки, при этом этой возможности у него нет, например, из-за блокировки запросов файрволлом. В таком сценарии сервер может долго ожидать, если не прописан адекватный таймаут. В таком случае, нам нужно проверить работоспособность. Для веб-сервера это ответ на определённый url, например:
docker run –rm -d \
–-name=elasticsearch \
–-health-cmd="curl –silent –fail localhost:9200/_cluster/health || exit 1" \
–-health-interval=5s \
–-health-retries=12 \
–-health-timeout=20s \
{image}
Для демонстрации мы возьмём команду создания файла. Если приложение не достигло в отведённый лимит времени (поставим пок 0) рабочего состояния (к примеру, создания файла), то помечается как на рабочее, но до этого делается заданное кол-во проверок:
vagrant@ubuntu:~$ sudo docker run \
–d –name healt \
–-health-timeout=0s \
–-health-interval=5s \
–-health-retries=3 \
–-health-cmd="ls /halth" \
ubuntu bash -c 'sleep 1000'
c0041a8d973e74fe8c96a81b6f48f96756002485c74e51a1bd4b3bc9be0d9ec5
vagrant@ubuntu:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c0041a8d973e ubuntu "bash -c 'sleep 1000'" 4 seconds ago Up 3 seconds (health: starting) healt
vagrant@ubuntu:~$ sleep 20
vagrant@ubuntu:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c0041a8d973e ubuntu "bash -c 'sleep 1000'" 38 seconds ago Up 37 seconds (unhealthy) healt
vagrant@ubuntu:~$ sudo docker rm -f healt
healt
Если же хотя бы одна из проверок сработала – то контейнер помечается как работоспособный (healthy) сразу:
vagrant@ubuntu:~$ sudo docker run \
–d –name healt \
–-health-timeout=0s \
–-health-interval=5s \
–-health-retries=3 \
–-health-cmd="ls /halth" \
ubuntu bash -c 'touch /halth && sleep 1000'
vagrant@ubuntu:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
160820d11933 ubuntu "bash -c 'touch /hal…" 4 seconds ago Up 2 seconds (health: starting) healt
vagrant@ubuntu:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
160820d11933 ubuntu "bash -c 'touch /hal…" 6 seconds ago Up 5 seconds (healthy) healt
vagrant@ubuntu:~$ sudo docker rm -f healt
healt
При этом проверки повторяются всё время с заданным интервалом:
vagrant@ubuntu:~$ sudo docker run \
–d –name healt \
–-health-timeout=0s \
–-health-interval=5s \
–-health-retries=3 \
–-health-cmd="ls /halth" \
ubuntu bash -c 'touch /halth && sleep 60 && rm -f /halth && sleep 60'
vagrant@ubuntu:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8ec3a4abf74b ubuntu "bash -c 'touch /hal…" 7 seconds ago Up 5 seconds (health: starting) healt
vagrant@ubuntu:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8ec3a4abf74b ubuntu "bash -c 'touch /hal…" 24 seconds ago Up 22 seconds (healthy) healt
vagrant@ubuntu:~$ sleep 60
vagrant@ubuntu:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Читать дальше