user59634
user59634

Reputation:

Restarting host from docker container

As the title indicates, is it possible to restart the host from a container? I have a docker container running with systemd as described here and started as:

$ docker run -privileged --net host -ti -d -v /sys/fs/cgroup:/sys/fs/cgroup:ro <image_name>

Once I issue the systemctl reboot command, I see:

# systemctl reboot
[root@dhcp-40-115 /]# 
[3]+  Stopped   

The host doesn't reboot. However, I see [1915595.016950] systemd-journald[17]: Received SIGTERM from PID 1 (systemd-shutdow). on host's kernel buffer.

Use case:

I am experimenting with running the restraint test harness in a container and some of the tests reboot the host and hence if this is possible to do from a container, the tests can run unchanged.

Update

As I mention in my answer:

There is a detail I missed in my question above which is once I have systemd running in the container itself, the systemctl reboot is (roughly saying) connecting to systemd on the container itself which is not what I want.

The accepted answer has the advantage that it is not dependent on the host and the container distro be have compatible systemd. However, on a setup where they are, my answer is what I think is a more acceptable one, since you can just use the usual reboot command.

Other init systems such as upstart is untested.

Upvotes: 16

Views: 20852

Answers (4)

Mr.Wang from Next Door
Mr.Wang from Next Door

Reputation: 14790

docker run -d --name network_monitor --net host --restart always --privileged --security-opt apparmor=unconfined  --cap-add=SYS_ADMIN \
-v /proc:/proc \
$IMAGE_URI

docker container must be granted enough permission to mount /proc

Upvotes: 0

Andy
Andy

Reputation: 3215

Adding to user59634's answer:

-v /run/systemd:/run/systemd works on fedora 27 and ubuntu 16

But the only socket you need is

docker run -it --rm -v /run/systemd/private:/run/systemd/private fedora reboot

You can also use /run/dbus, but I like this systemd method more. I do not fully understand how much power you are giving the container, I suspect it is a enough to take over your host. So I would only suggest using this in a container that you wrote, and then communicate with any another container see here.

Unrelated similar information

Sleeping/suspending/hibernating can be done with only the -v /sys/power/state:/sys/power/state, and using /lib/systemd/systemd-sleep suspend for example. If you know how to, you can echo a string directly to /sys/power/state, for example echo mem > /sys/power/state here for more explanation of the different options you get from cat /sys/power/state

Upvotes: 0

xeor
xeor

Reputation: 5455

I was able to send sysrq commands to the host mounting /proc/sysrq-trigger as a volume.

This booted the host.

docker-server# docker run -i -t -v /proc/sysrq-trigger:/sysrq centos bash
docker-container# echo b > /sysrq

You can set a bit-mask permission on /proc/sys/kernel/sysrq on the host to only allow eg, sync the disks and boot. More information about this at http://en.wikipedia.org/wiki/Magic_SysRq_key but something like this (untested) should set those permissions:

echo 144 > /proc/sys/kernel/sysrq

Also remember to add kernel.sysrq = 144 to /etc/sysctl.conf to have it saved over reboots.

Upvotes: 16

user59634
user59634

Reputation:

There is a detail I missed in my question above which is once I have systemd running in the container itself, the systemctl reboot is (roughly saying) connecting to systemd on the container itself which is not what I want.

On the hint of a colleague, here is what I did on a "stock" fedora image (nothing special in it):

$ docker run -ti -v /run/systemd:/run/systemd fedora /bin/bash

Then in the container:

bash-4.2# systemctl status docker
docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled)
   Active: active (running) since Tue 2014-07-01 04:57:22 UTC; 2 weeks 0 days ago
     Docs: http://docs.docker.io
 Main PID: 2589
   CGroup: /system.slice/docker.service

Here, the container is able to access systemd on the host. Then, issuing a reboot command actually reboots the host:

bash-4.2# reboot 

Thus, it is possible to reboot the host from the container.

The point to note here is that the host is running Fedora 20 and so is the container. If the host was a different distro not running systemd, this would not be possible. Generally speaking, if the host and the container are running distros which are not running systemd or incompatible versions of systemd, this will not work.

Upvotes: 8

Related Questions