[systemd-devel] Shutting down service using systemd-nspawn

Lennart Poettering lennart at poettering.net
Wed Feb 25 11:35:12 PST 2015


On Tue, 24.02.15 09:39, Peter Paule (systemd-devel at fedux.org) wrote:

> Hi, any suggestions to cleanly shutdown containers?
> 
> If using defaults in a service file for stopping a container started with
> nspawn it will be killed by SIGTERM/SIGKILL. This makes "systemd-nspawn" to
> exit with
> "1" and the unit is marked as failed.

Hmm, nspawn actually passes the exit code it got from the container's
PID 1 on to its caller.

When nspawn itself gets SIGTERM it will send SIGRTMIN+3 to the
container's PID 1. In systemd that triggers an orderly shutdown, other
init systems have no nice way to trigger an orderly shutdown in a
similar way. When systemd runs nspawn as a service it will eventually
send SIGKILL to the service if SIGTERM does not shutdown the thing.

>   nginx at example_org.service - Webservice for example_org
>      Loaded: loaded (/etc/systemd/system/nginx at .service; enabled; vendor
> preset: disabled)
>      Active: failed (Result: exit-code) since Tue 2015-02-24 08:11:54 UTC;
> 25ms ago
>     Process: 17351 ExecStart=/usr/bin/systemd-nspawn --register=no
> --ephemeral --bind-ro ${SSL_DIR}:/etc/ssl/nginx --bind-ro
> ${WWW_DIR}:/srv/www --bind ${LOG_DIR}:/var/log/nginx/ --bind-ro
> ${SITES_DIR}:/etc/nginx/sites-enabled/ --bind-ro
> ${CONFIG_DIR}:/etc/nginx/other-config/ -M docker-centos-nginx
> /usr/sbin/nginx (code=exited, status=1/FAILURE)
>    Main PID: 17351 (code=exited, status=1/FAILURE)

In general: nspawn is primarily designed to run init-like processes as
PID 1 inside the container. If you run other code as PID 1 then you
will run into problems, since PID 1 is magic on UNIX, and your process
might not be able to deal with that fact. For example, it needs to
reap arbitrary children it doesn't expect, or it needs to handle
SIGWINCH, SIGINT, SIGPWR the right way. Or, so that that nspawn can
nicely shut down the container it ideally needs to handle SIGRTMIN+3.

Docker ignores the fact that PID 1 is special, and thus runs into
problems with daemons that do not reap unknown children. You can run
things the same way with nspawn, but if you do this you really need to
know what you are doing and the problems you run into with that.

I'd be willing to take a patch that adds --kill-signal= that allows
changing the kill signal from SIGRTMIN+3 to anything else. With that
you could use --kill-signal=SIGTERM to get the behaviour you want...

Lennart

-- 
Lennart Poettering, Red Hat


More information about the systemd-devel mailing list