With systemd, comes systemd-nspawn. (I will not talk about love/hate of systemd, not in this post at least. Let’s just say if you start out saying you are writing an init system, why does your init system takeover acpi?). Anyway, part of the systemd monstrosity is something called nspawn. In short, its a “more powerful” chroot, but still should not be relied upon soley for security (think defense in depth people!). Why would you use this over lxc? If you just want to run something in a chroot, its great for it. If you need a full container, lxc is probably a better choice. Because I like to try new things, I chose systemd-nspawn to run certain applications (http, mysql, minecraft). I also did not see many tutorials specifically targeting centos 7 which seems to be using and older verson of systemd-nspawn/machinectl so some features are missing in those tools.
Create a basic centos 7 bootstrap
This will install a basic bootstrap centos 7 environment
Reset the password in the container
If you are a good person, you are running selinux in enforcing mode. However there is a known bug in centos 7 that will not let you change the password if you “boot” your container. So currently, you can be fancy and make modules, or be only a slightly bad person and disable selinux, change the password, re-enable (things work fine after this point with selinux enabled)
Boot your container and install your fancypants stuff
This will drop you into a shell, where you can yum install/configure to your hearts desire.
Note: This will also by default make your “container” listen on your network interfaces. So if you have port 80 open in your firewall, and have httpd started and listening in your container (but not on your host), it will be as if you are serving httpd on your host.
When you are done installing fancy stuff, I just issue
And it stops the container and takes you out of your chroot.
You can also bind paths outside of your container into the container’s chroot
Start your container with systemd
edit the following file: /etc/systemd/system/yaystuff.service
[Unit] Description=yaystuff container [Service] ExecStart=/usr/bin/systemd-nspawn -jbD /srv/yaystuff/ -bind=/path/on/host:/path/in/container KillMode=process
Then reload systemd and start the container
Now the version of machinectl on centos 7.0 does not have a login feature. So you have to use nsenter. To use nsenter, you have to get the pid of your container. That is logged in /var/log/messages (or if you started your container from the cli)
Grab the pid there and then execute:
To leave just type exit.
Excellent reference: http://0pointer.de/blog/projects/changing-roots.html
Redhat 7.2 (CentOS Linux release 7.2.1511) has a newer version of machinectl that has login. No need to use nsenter anymore.