我怎样才能得到一个upstart脚本来正确地管理运行docker镜像



我有一个本地的docker注册表,我想用upstart管理。

我有以下脚本(在/etc/init/docker-registry.conf):

description "docker registry" 
author "me" 
start on filesystem and started docker 
stop on runlevel [!2345] 
respawn 
script
    /usr/bin/docker.io run -a stdout --rm --name=docker-registry 
    -v /var/local/docker-registry:/var/local/docker-registry 
    -p 5000:5000 mysite:5000/docker-registry
end script

我可以启动我的docker注册表:
sudo start docker-registry

响应:docker-registry start/running, process 8620

检查确认其运行?

sudo status docker-registry

响应:docker-registry start/running, process 8620

尝试使用:

sudo stop docker-registry

响应:docker-registry stop/waiting

然而,它实际上并没有停止。


它确实完美地停止了:

docker stop docker-registry

我试着把这个添加到upstart脚本:

post-stop script
    docker stop docker-registry
end script

但是它只是返回:stop: Job failed while stop

这对我有用:

description "container foo"
author "me"
start on filesystem and started docker
stop on runlevel [!2345]
respawn
script
  /usr/bin/docker start -a foo
end script
pre-stop script
  /usr/bin/docker stop foo
end script

我假设官方Docker文档只关心自动启动部分。upstart的实际PID输出与实际的docker进程PID不同,我怀疑这会在停止时导致一些不匹配:

sudo service foo-docker start
foo-docker start/running, process 30313

这个过程是什么?看起来这就是Docker启动容器的方式:

ps -p 30386 -f
UID        PID  PPID  C STIME TTY          TIME CMD
root     30386     1  0 14:48 ?        00:00:00 /bin/sh -e -c /usr/bin/docker start -a foo  /bin/sh

在容器内运行的实际命令的PID是不同的:

pidof foo
30400

和杀死docker PID,我猜service foo-docker stop做的,不会杀死容器(或在其中运行的命令):

sudo kill 30386 # or sudo service foo-docker stop
#30400 is still running

尝试在docker run行前加上exec。这将导致docker容器在shell脚本上下文中运行,而不是在shell派生脚本的上下文中运行。结果,docker run二进制将接收信号并自我清理。

例如:

description "Docker container for OpenVPN server"
start on filesystem and started docker
stop on runlevel [!2345]
respawn
script
  exec docker run --volumes-from ovpn-data --rm -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn
end script

和运行start docker-openvpnstop docker-openvpn工作如预期(——rm也被尊重)。

在Ubuntu 14.04的Docker version 1.4.0, build 4595d4f上测试。

如果它不工作,考虑更新到使用上游docker apt repo:

   curl https://get.docker.io/gpg | sudo apt-key add -
   echo deb http://get.docker.io/ubuntu docker main | sudo tee /etc/apt/sources.list.d/docker.list
sudo apt-get update && sudo apt-get install -y lxc-docker

这里不需要调用docker stopUpstart的stop命令会向容器发送SIGTERM信号,这是一样的。

让——rm在这里工作可能会有问题。在Github上有一个关于它的公开问题

要使预停止脚本工作,只需添加"rm"来清理指定的容器,因此:

<>之前......pre-stop脚本/usr/bin/docker stop[容器名称]/usr/bin/docker rm[容器名称]端脚本之前

在这种情况下,你也可以避免启动(如"docker start"vs"docker run")容器(只有在你已经运行并停止时才会启动)。所以你的开始脚本看起来像:

<>之前...脚本/usr/bin/docker rm[容器名]| true/usr/bin/docker run [-v vol:vol] [-p port:port]——name=[容器名][docker标签]端脚本之前

要使其工作,您需要使用——name运行,否则stop找不到您的容器。如果您真的想启动-a,您可以在启动脚本中运行、停止、启动。

完整的示例:<>之前描述"storm supervisor docker container"作者"youremailprovider.domain"启动文件系统并启动docker停止运行级别[!]2345]重生脚本/usr/bin/docker rm storm-supervisor | true/usr/bin/docker run——name="storm-supervisor" -v/var/log/docker-storm-supervisor:/var/log -p 6700:6700 -p 6701:6701 -p 6702:6702 -p 6703:6703 -p 6704: 6705 -p 6706:6706 tycoon/storm-supervisor端脚本pre-stop脚本/usr/bin/docker/usr/bin/docker rm storm-supervisor端脚本

您可以在启动docker-registry时使用--restart=always,即

docker run -d --restart=always docker-registry

这样映像将自动重新启动与机器重新启动,就像upstart。

更多关于重启策略的信息在这里

最新更新