JoBu1324
JoBu1324

Reputation: 7769

Systemd - Run Utility Docker Container During `ExecStop=`

I am testing CoreOS to see if it meets our needs, and so far things are going a little slow, but OK. I like systemd, but it doesn't seem to be working properly - specifically, on shutdown.

My Goal

My goal is to have a script run on service start and stop that adds and removes records from our DNS server respectively for a service. It works when the service is started by the system on boot, or when it is manually started or shut down - but not when the system is rebooted or halted (shutdown -r now, shutdown -h now).

Here is a slightly simplified version of a docker registry service I am using for an example:

[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

(This unit works together with another unit - registry-ui.service. When one is started the other does as well.)

Note the Conflicts=... line. I added it after spending time trying to figure out why the service wasn't shutting down properly. It did nothing. According to the docs, however, services have a Conflicts=shutdown.target line by default. When services conflict and one starts up, the other shuts down - or so the docs say.

What did I miss? Why won't my ExecStop= lines run?


Update

I've determined that ExecStop= lines do run. Using journalctl -u registry.service -n 200 gave me this message:

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

Which indicates that the problem is (as I speculated in the comments) that my docker container won't start during shutdown. I've added the following lines to my [Unit] section:

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

The new lines have no effect on the journalctl error, so my question now becomes, is there a way to run a utility docker container prior to shutdown?

Upvotes: 3

Views: 1276

Answers (2)

Popinou
Popinou

Reputation: 384

Instead of starting everything in one unit file, you can start 2 different services and bind them using bindsTo so that they start and stop together : http://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo=

That would make two easy and smaller unit files, each taking care of one container. It would also make debugging easier for you.

Upvotes: 0

inverminx
inverminx

Reputation: 65

If I understood your goal, you would like to run some DNS cleanup when a server is being powered off, and you are attempting to do this inside the systemd docker service file. Why don't you use fleet for that task ? try to create a fleet unit-file that monitors your DNS server, and when it detect the server is not reachable you can launch your cleanup tasks.

On fleet, when you destroy a service using fleetctl destroy, the exec stop lines don't run (similar to power-off). If you want to have a cleanup session, you usually achieve this using a satellite service with this directives

serviceFile.service

[Unit]
[email protected]

[email protected]

[Unit]
PartOf=%i.service

Upvotes: 1

Related Questions