Is there any concrete and acceptable solution for running systemd inside the docker container?
Solution 1
You didn't mention what distribution you're using inside your container (which would have implications w/r/t which version of systemd you're using), but the following will successfully boot a CentOS container running systemd:
docker run -it --rm \
-e container=docker \
--tmpfs /run \
--tmpfs /tmp \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
--cap-add SYS_ADMIN \
centos /sbin/init
This is with Docker 17.05.0-ce; older versions may require additional flags. Using a stock centos:7
image, your initial environment inside the container looks like this:
# systemctl status
State: running
Jobs: 0 queued
Failed: 0 units
Since: Mon 2017-12-04 17:47:15 UTC; 45s ago
[...]
And:
# ps -fe
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 17:47 ? 00:00:00 /sbin/init
root 16 1 0 17:47 ? 00:00:00 /usr/lib/systemd/systemd-journald
dbus 26 1 0 17:47 ? 00:00:00 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
root 28 1 0 17:47 ? 00:00:00 /usr/lib/systemd/systemd-logind
root 30 1 0 17:47 console 00:00:00 /sbin/agetty --noclear --keep-baud console 115200 38400 9600 vt220
root 32 0 0 17:47 ? 00:00:00 bash
root 58 32 0 17:48 ? 00:00:00 ps -fe
Note that I'm using --rm
here not because it's necessary but because I'm terrible at cleaning things up after the fact. It's not necessary to get the container to run.
but looks like most of them compromise the security of the container and the host
Well, running systemd does require privileges beyond those granted to a typical Docker container (hence the --cap-add
). Whether this has security implications for your environment or not depends on what you're doing.
Solution 2
For example, if you want to run systemd in a Arch Linux container,
run this command: docker run -it --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro --name=ArchLinux archlinux /bin/sh -c "if [ -x /etc/docker-start ]; then exec /etc/docker-start; else exec /bin/sh; fi"
Then run these commands in the container:
echo 'Server = https://THE_FASTEST_MIRROR_FOR_YOU/archlinux/$repo/os/$arch' >/etc/pacman.d/mirrorlist
pacman -Sy --noconfirm systemd systemd-sysvcompat
passwd -d root
echo -en '#!/bin/sh\numount /etc/hostname; umount /etc/hosts; umount /etc/resolv.conf; exec /usr/lib/systemd/systemd' >/etc/docker-start
chmod 700 /etc/docker-start
echo -e 'nameserver 8.8.8.8' >/etc/resolv.conf
exit
Then start the container and attach to it: docker start -ia ArchLinux
You need to run with --privileged
, and this may cause some security problems. Please try to avoid it if possible.
Comments
-
lakshayk over 1 year
I have seen many workarounds for this to run systemd inside docker containers but looks like most of them compromise the security of the container and the host. How are most people here dealing with running systemd specific stuff inside the container.
-
Admin over 6 yearsCould you explain why you need systemd?
-
Admin over 6 yearsMy application is setup in production using some bash scripts which use systemd extensively. I cannot change them but i would want to dockerize the solution.
-
Admin over 6 yearsCould you add the information you have found and add the pros and cons for every approach?
-
Admin over 6 yearsWhy do you want to dockerize this application if it doesn't fit well into the docker way (and you can't change it)?
-
Admin over 6 yearsClients time and again want docker images to test out in their CI/CD pipelines
-
Admin over 6 yearsDid you consider to provide VMs to the customers?
-
Admin over 6 yearsBusiness decision does not change on small technical limitations :)
-
-
larsks over 6 yearsNote that the blog post referenced here is from 2014, which given the pace of Docker (and systemd) development is comparatively ancient.
-
Tensibai over 6 yearsThe security hole doesn't really depend on what you're doing, it is here, it's more about the fact you acknowledge and accept it for what you're doing. (sorry but I need to stress the point that mounting /sys/'anything' is a large security hole as it gives the container access to a large part of the underlying host for which the container has been isolated)