Как я могу получить upstart script для правильного управления запуском образа докеров?

У меня есть локальный док-реестр, с которым мне бы хотелось справиться с upstart.

У меня есть следующий script (в /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

Я могу запустить мой реестр докеров с помощью:

sudo start docker-registry

Ответ: запуск/запуск docker-реестра, процесс 8620

Проверьте, чтобы убедиться в его функционировании?

sudo status docker-registry

Ответ: запуск/запуск docker-реестра, процесс 8620

Попытка остановить его с помощью

sudo stop docker-registry

Ответ: остановка/ожидание докере-реестра

Однако это фактически не останавливается. Процесс все еще жив, контейнер работает, и он все еще отлично работает


Он отлично справляется с:

docker stop docker-registry

Я попытался добавить это к выскочке script:

post-stop script
    docker stop docker-registry
end script

Но он просто возвращает: stop: сбой задания при остановке

Ответ 1

Это сработало для меня:

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 заботиться только об автоматической стартовой части. Фактический вывод PID с помощью выскочки отличается от фактического 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

И убивая PID докера, как я думаю, service foo-docker stop делает, не убивает контейнер (или команду, запущенную внутри него):

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

Ответ 2

Попробуйте префикс строки docker run с помощью exec. Это приведет к тому, что контейнер докера будет запущен в контексте оболочки script, а не в оболочке, которая его разветкит. В результате двоичный код 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-openvpn и stop docker-openvpn работают так, как ожидалось (--rm также соблюдается).

Протестировано на Docker version 1.4.0, build 4595d4f на Ubuntu 14.04.

Если это не сработает, подумайте об обновлении, чтобы использовать возвращаемый доклер 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

Ответ 3

Нет необходимости звонить на докерную остановку здесь Команда stopstart stop отправит сигнал SIGTERM в контейнер, который является тем же самым.

Может возникнуть проблема с получением --rm для работы здесь. В Github есть открытый вопрос о нем

Ответ 4

Чтобы сделать ваш пре-стоп script, просто добавьте "rm" для очистки именованного контейнера, поэтому:

...
...
pre-stop script
  /usr/bin/docker stop [container name]
  /usr/bin/docker rm   [container name]
end script

Вы также можете не запускать (как в режиме "докер-старт" и "докер-запуск" ) контейнер в этом случае (запуск запускается только в том случае, если вы уже выполнили прогон и остановку). Итак, ваш старт script выглядит следующим образом:

...
script
   /usr/bin/docker rm [container name] | true
   /usr/bin/docker run [-v vol:vol] [-p port:port] --name=[container name] [docker tag]
end script

Чтобы это сработало, вам нужно запустить с --name или остановить не можете найти свой контейнер. Если вы действительно хотите запустить -a, вы можете запустить, остановить, запустить в своем старте script.

Полный пример:

description "storm supervisor docker container"
author "[email protected]"

start on filesystem and started docker
stop on runlevel [!2345]
respawn
script
        /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:6704 -p 6705:6705 -p 6706:6706 tycoon/storm-supervisor
end script

pre-stop script
        /usr/bin/docker stop storm-supervisor
        /usr/bin/docker rm storm-supervisor
end script

Ответ 5

Вы можете использовать --restart=always при запуске docker-registry, т.е.

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

Таким образом, изображение автоматически перезапустится вместе с перезагрузкой компьютера, как и выскочка.

Подробнее о политиках перезагрузки здесь