我已经从docker镜像创建了gcloud
个计算实例,并将其配置为启动shutdown script,该实例应调用docker stop
以便正常关闭容器中的应用程序。
gcloud beta compute instances create-with-container mycontainername \
--container-image ypapax/trap_exit \
--metadata-from-file shutdown-script=./on_shutdown.sh
这是我的初始on_shutdown.sh:
#!/usr/bin/env bash
docker stop $(docker ps -a -q)
尽管,我在其中添加了更多调试行,现在on_shutdown.sh
看起来像:
#!/usr/bin/env bash
# https://cloud.google.com/compute/docs/shutdownscript
curl -X POST -d "$(date) running containers on $(hostname): $(docker ps)" http://trap_exit.requestcatcher.com/test
docker stop $(docker ps -a -q)
result=$?
curl -X POST -d "$(date) $(hostname) stop status code: $result" http://trap_exit.requestcatcher.com/test
当我重新启动Google计算实例时:
sudo reboot
脚本on_shutdown.sh
已启动(我看到它正在检查requrest listener)。但是,当它尝试停止docker容器时,没有什么可停止的,docker ps
显示为空行。
所以这行:
curl -X POST -d "$(date) running containers on $(hostname): $(docker ps)" http://trap_exit.requestcatcher.com/test
给我
Thu Jul 12 04:29:48 UTC 2018 running containers on myinstance:
在调用sudo reboot
之前,我检查了docker ps
并看到我的容器正在运行:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bbaba30e65ff ypapax/trap_exit "/entrypoint.sh" 7 seconds ago Up 7 seconds myinstance
因此,看起来docker容器在调用reboot
和启动on_shutdown.sh
之间被杀死。问题在于,在我的entrypoint中,杀死并不会调用trap cleanup EXIT
。需要停止它才能调用清理。
这是我的切入点:
#!/usr/bin/env bash
set -ex
cleanup(){
echo cleanup is called
curl -X POST -d "cleanup is called on $(hostname) $(date)" http://trap_exit.requestcatcher.com/test
}
trap cleanup EXIT
curl -X POST -d "container is started on $(hostname) $(date)" http://trap_exit.requestcatcher.com/test
sleep 10000
因此,我想在gcloud计算实例重新启动或关闭时运行容器的清理,但是标志--metadata-from-file shutdown-script=./on_shutdown.sh
并没有帮助。我还尝试了其他方法来在重启时调用脚本,例如this。但是我的脚本根本没有启动。
如果可以的话,这里是我的Dockerfile。
答案 0 :(得分:2)
首先,有limitations coming with this approach:
- 创建并运行关闭脚本,这些脚本会尽最大努力在实例终止或重新启动之前立即执行命令。
- 关机脚本对于带有managed instance group的autoscaler中的实例特别有用。
- 脚本在实例停止之前的limited shutdown period期间运行
如您所见,在关闭脚本运行时,泊坞窗可能已经停止:用docker ps -a
(而不是docker ps)检查以查看所有退出容器的状态。
尝试adding a supervisor(作为in this example)一个docker镜像本身,以查看是否是管理者,或者至少是use the docker run --init
option:目标是检查容器本身是否确实使用了其管理者脚本