Run systemd in an unprivileged(!!!) docker container

Many people have tried running systemd inside a docker container.
Some have succeeded to some extend. See: http://developerblog.redhat.com/2014/05/05/running-systemd-within-docker-container/ for a reference.

The issues mentioned there are still problematic.
Also a drastic approach was used. Files in /lib/systemd/ were deleted and so on.

The biggest issue remaining however is the fact that you need to run docker in privileged mode.
Which adds a lot of kernel capabilities to the container and makes it less secure.
The root-cause of this is D-BUS. For reference: https://bugzilla.redhat.com/show_bug.cgi?id=1115533
D-BUS wants to drop some capabilities which it did not have in the first place….

To work around that issue I created a small fake C library and inject it into D-BUS via LD_PRELOAD. It tells D-BUS that those systemcalls succeeded. The source code is just a few lines and can be found here: https://github.com/maci0/docker-systemd-unpriv/blob/master/fakecap.c

So after getting the messagebus to work the next step is to get all the rest of systemd working.
As mentioned by Daniel Walsh in his blog entry. We need to disable some systemd unit files.
So I disabled ALL of them 🙂
It was simple, just remove all files in /etc/systemd/system and systemctl mask all files in /lib/systemd/system/ a simple for-loop does the trick.

After that I unmask some mandatory systemd targets and unit files and enable some as well.

In addition to that we need the cgroup filesystem mounted in the container for systemd to work. This is achieved with a simple option -v /sys/fs/cgroup:/sys/fs/cgroup:ro.

So now I tried to run it but without any success.
The only output I ever got was
Failed to mount /run: Operation not permitted
There is an entry in bugzilla as well: https://bugzilla.redhat.com/show_bug.cgi?id=1033604
After trying to figure out a workaround for some time I just mounted a directory into the container as /run.
To my surprise after that it worked.
I started putting the pieces together and just uploaded everything to github:
https://github.com/maci0/docker-systemd-unpriv/

Simply execute build.sh and after that run.sh
Now you should have a docker container running which runs systemd.
You can login with user root, password root.
Or run docker inspect to find out the IP of the container and simply ssh into it 😀

You can find out the IP of the container using docker inspect and ssh into the container.
You can login with user root, password root.

Give it a spin !

My thanks go to Daniel Walsh from RedHat who did the groundwork for this.

Advertisements

3 thoughts on “Run systemd in an unprivileged(!!!) docker container

    1. maci0 Post author

      It is not required anymore since I use a custom dbus.service unit file now which works around dbus trying to drop the capabilities.

      Reply
  1. Pingback: TECH::Using NFS with Docker – Where does it fit in? | Why Is The Internet Broken?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s