Сам ответ, как я нашел решение, которое работает для нас:
TL; др: использовать .ebextensions скриптов для запуска сценария, прежде чем 01flip, ваш скрипт будет убедиться, что изящная отключение whatevers внутри докер имеет место
первый, ваше приложение (или любой другой your'e работает в докер) должен быть в состоянии поймать сигнал, SIGINT, например, и завершение работы грациозно на ней.
Это абсолютно не связано с Docker, вы можете протестировать его, работая где угодно (локально, например) Существует много информации о том, как добиться такого поведения для разных приложений в сети (будь то ruby, node.js и т.д ...)
Второй, ваш проект на основе EB/Docker может иметь папку .ebextensions, которая содержит все своего рода скриптов для выполнения во время развертывания. мы ставим 2 пользовательские сценарии в него, gracefulshutdown_01.config и gracefulshutdown_02.config файл, который выглядит примерно так:
# gracefulshutdown_01.config
commands:
backup-original-flip-hook:
command: cp -f /opt/elasticbeanstalk/hooks/appdeploy/enact/01flip.sh /opt/elasticbeanstalk/hooks/appdeploy/01flip.sh.bak
test: '[ ! -f /opt/elasticbeanstalk/hooks/appdeploy/01flip.sh.bak ]'
cleanup-custom-hooks:
command: rm -f 05gracefulshutdown.sh
cwd: /opt/elasticbeanstalk/hooks/appdeploy/enact
ignoreErrors: true
и:
# gracefulshutdown_02.config
commands:
reorder-original-flip-hook:
command: mv /opt/elasticbeanstalk/hooks/appdeploy/enact/01flip.sh /opt/elasticbeanstalk/hooks/appdeploy/enact/10flip.sh
test: '[ -f /opt/elasticbeanstalk/hooks/appdeploy/enact/01flip.sh ]'
files:
"/opt/elasticbeanstalk/hooks/appdeploy/enact/05gracefulshutdown.sh":
mode: "000755"
owner: root
group: root
content: |
#!/bin/sh
# find currently running docker
EB_CONFIG_DOCKER_CURRENT_APP_FILE=$(/opt/elasticbeanstalk/bin/get-config container -k app_deploy_file)
EB_CONFIG_DOCKER_CURRENT_APP=""
if [ -f $EB_CONFIG_DOCKER_CURRENT_APP_FILE ]; then
EB_CONFIG_DOCKER_CURRENT_APP=`cat $EB_CONFIG_DOCKER_CURRENT_APP_FILE | cut -c 1-12`
echo "Graceful shutdown on app container: $EB_CONFIG_DOCKER_CURRENT_APP"
else
echo "NO CURRENT APP TO GRACEFUL SHUTDOWN FOUND"
exit 0
fi
# give graceful kill command to all running .js files (not stats!!)
docker exec $EB_CONFIG_DOCKER_CURRENT_APP sh -c "ps x -o pid,command | grep -E 'workers' | grep -v -E 'forever|grep' " | awk '{print $1}' | xargs docker exec $EB_CONFIG_DOCKER_CURRENT_APP kill -s SIGINT
echo "sent kill signals"
# wait (max 5 mins) until processes are done and terminate themselves
TRIES=100
until [ $TRIES -eq 0 ]; do
PIDS=`docker exec $EB_CONFIG_DOCKER_CURRENT_APP sh -c "ps x -o pid,command | grep -E 'workers' | grep -v -E 'forever|grep' " | awk '{print $1}' | cat`
echo TRIES $TRIES PIDS $PIDS
if [ -z "$PIDS" ]; then
echo "finished graceful shutdown of docker $EB_CONFIG_DOCKER_CURRENT_APP"
exit 0
else
let TRIES-=1
sleep 3
fi
done
echo "failed to graceful shutdown, please investigate manually"
exit 1
gracefulshutdown_01.config небольшой Util, что резервное копирование оригинальный flip01 и удаляет (если существует) наш собственный скрипт.
gracefulshutdown_02.config где происходит волшебство. создает скрипт с разрешением 05gracefulshutdown и гарантирует, что после этого переименуйте его в 10flip.
05gracefulshutdown, пользовательский скрипт, делает это в основном:
- найти ток, протекающий Docker
- найти все процессы, которые должны быть отправлены в SIGINT (для нас свои процессы с «рабочим» в его названии
- отправить SIGINT к вышеуказанным процессам
- петля:
- проверить, если были убиты процессы от до того
- продолжить цикл для количества попыток
- если попытки завершены, выход со статусом «1» и не продолжайте 10flip, необходимы ручные вмешательства.
Это предполагает, что на машине работает только 1 докер, и вы можете вручную перескочить, чтобы проверить, что случилось, в случае его неудачи (для нас еще не произошло).
Я предполагаю, что его также можно улучшить во многих отношениях, так что получайте удовольствие.