howto:弹性beanstalk +部署docker +优雅关机

你好伟大的人的计算器,

在EB上托pipe一个docker容器,并在其上运行一个基于nodejs的代码。 当重新部署我们的docker集装箱时,我们希望旧的容器能够正常closures。

我已经find了关于我们的代码如何接收由'docker stop'命令产生的sigterm信号的帮助和指南。

然而,进一步调查EB机器运行/opt/elasticbeanstalk/hooks/appdeploy/enact/01flip.sh在: /opt/elasticbeanstalk/hooks/appdeploy/enact/01flip.sh显示,当从目前的“翻转”到新的上一级容器时,旧的“docker kill”

有没有办法改变这种行为,docker停止?
或者一般来说推荐的方法来处理旧容器的正常closures?

谢谢!

自我回答,因为我find了一个适合我们的解决scheme:

tl; dr:在01flip之前使用.ebextensions脚本来运行你的脚本,你的脚本将确保docker内的whatevers正常closures

首先 ,你的应用程序(或者你在Docker中运行的任何东西)必须能够捕获一个信号,例如SIGINT,然后优雅地closures它。
这是完全不相关的Docker,你可以testing它运行在任何地方(例如本地)有很多信息关于获得这种types的行为在networking上的不同types的应用程序(无论是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是魔术发生的地方。 它创build一个05年可靠的closures制定脚本,并确保翻转后将其重命名为10flip。

05年closures,自定义脚本,基本上这样做:

  • find当前运行的docker
  • find所有需要发送SIGINT的进程(对于我们来说,它的名字中包含“worker”的进程
  • 发送sigint到上述过程
  • 循环:
  • 检查之前的进程是否被杀死
  • 继续循环一次尝试
  • 如果尝试结束,退出状态“1”,不要继续10flip,手动干扰是必要的。

这假设你只有1个docker在机器上运行,并且你可以手动跳上来检查错误的情况下(我们从来没有发生过)。
我想它也可以在许多方面得到改善,所以玩得开心。