Systemd — запустить служебный контейнер Docker во время `ExecStop=`

Я тестирую CoreOS, чтобы увидеть, соответствует ли он нашим потребностям, и пока все идет немного медленно, но все в порядке. Мне нравится systemd, но он не работает должным образом, особенно при завершении работы.

Моя цель

Моя цель - запустить скрипт при запуске и остановке службы, который добавляет и удаляет записи с нашего DNS-сервера соответственно для службы. Он работает, когда служба запускается системой при загрузке или когда она запускается или выключается вручную, но не при перезагрузке или остановке системы (shutdown -r now, shutdown -h now).

Вот немного упрощенная версия службы реестра докеров, которую я использую для примера:

[Unit]
Description=Docker Registry
After=docker.service
Before=registry-ui.service
Wants=registry-ui.service

[Service]
Conflicts=halt.target poweroff.target reboot.target shutdown.target sleep.target
TimeoutStartSec=0
Restart=on-failure
ExecStartPre=-/usr/bin/docker kill Registry
ExecStartPre=-/usr/bin/docker rm Registry
ExecStartPre=-/usr/bin/docker run --rm myrepo:5000/tool runtool arg1 arg2
ExecStart=/usr/bin/docker run various args registry:latest
ExecStop=-/usr/bin/docker run --rm myrepo:5000/tool runtool arg1 arg2
ExecStop=-/usr/bin/docker stop Registry

[X-Fleet]
MachineID=coreos1

[Install]
WantedBy=multi-user.target
RequiredBy=registry-ui.service
Also=registry-ui.service

(Этот модуль работает вместе с другим модулем - registry-ui.service. Когда один запускается, другой также работает.)

Обратите внимание на строку Conflicts=.... Я добавил его, потратив время на то, чтобы понять, почему служба не закрывалась должным образом. Это ничего не сделало. Однако, согласно документам, службы имеют строку Conflicts=shutdown.target на По умолчанию. Когда сервисы конфликтуют и один запускается, другой отключается — по крайней мере, так говорится в документах.

Что я упустил? Почему мои ExecStop= строки не запускаются?


Обновлять

Я определил, что выполняется ExecStop= строк. Использование journalctl -u registry.service -n 200 дало мне это сообщение:

Error response from daemon: Cannot start container 7b9083a3f81710febc24256b715fcff1e8146c867500c6e8ce4d170ad1cfd11a: dbus: connection closed by user

Это указывает на то, что проблема (как я предположил в комментариях) заключается в том, что мой док-контейнер не запускается во время выключения. Я добавил следующие строки в свой раздел [Unit]:

[Unit]
After=docker.service docker.socket
Requires=docker.service docker.socket
...

Новые строки не влияют на ошибку journalctl, поэтому теперь у меня возникает вопрос: есть ли способ запустить служебный контейнер докера перед выключением?


person JoBu1324    schedule 31.10.2014    source источник
comment
Хм. Я добавил строку ExecStop=touch /home/me/shutdown и нашел файл после перезагрузки. Может ли проблема быть связана с сетью или с тем, что система отказывается запускать контейнер после начала выключения?   -  person JoBu1324    schedule 31.10.2014
comment
Добавление сетевых зависимостей не помогло, все еще ищу причину.   -  person JoBu1324    schedule 31.10.2014


Ответы (2)


Если я понял вашу цель, вы хотели бы запустить некоторую очистку DNS, когда сервер отключается, и вы пытаетесь сделать это внутри файла службы systemd docker. Почему бы вам не использовать флот для этой задачи? попробуйте создать файл модуля флота, который отслеживает ваш DNS-сервер, и когда он обнаруживает, что сервер недоступен, вы можете запускать свои задачи очистки.

На флоте, когда вы уничтожаете службу с помощью fleetctl destroy, строки остановки выполнения не запускаются (аналогично отключению питания). Если вы хотите провести сеанс очистки, вы обычно достигаете этого, используя спутниковый сервис с этими директивами.

serviceFile.service

[Unit]
[email protected]

[email protected]

[Unit]
PartOf=%i.service
person inverminx    schedule 29.04.2015

Вместо того, чтобы запускать все в одном юнит-файле, вы можете запустить 2 разные службы и связать их с помощью bindsTo, чтобы они запускались и останавливались вместе: http://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo=

Это сделало бы два простых и меньших по размеру юнит-файла, каждый из которых заботился бы об одном контейнере. Это также облегчит вам отладку.

person Popinou    schedule 30.04.2015