If you have used Docker or Linux Containers (LXC) in the current version of Ubuntu (13.10 Saucy Salamander), you will have noticed that it doesn’t come with the User namespace activated by default:
root@server:~# lxc-checkconfig --- Namespaces --- Namespaces: enabled Utsname namespace: enabled Ipc namespace: enabled Pid namespace: enabled User namespace: missing Network namespace: enabled Multiple /dev/pts instances: enabled --- Control groups --- Cgroup: enabled Cgroup clone_children flag: enabled Cgroup device: enabled Cgroup sched: enabled Cgroup cpu account: enabled Cgroup memory controller: enabled Cgroup cpuset: enabled --- Misc --- Veth pair device: enabled Macvlan: enabled Vlan: enabled File capabilities: enabled
The fully supported versions of LXC and the user namespace are planned to be included in the next Long Term Release of Ubuntu: Ubuntu 14.04 (Trusty Tahr). However, the kernel that ships with Ubuntu 13.10 (3.10) already has support for user namespaces if you want to try it out before then, but it’s deactivated by default.
Setting up the environment
From a vanilla Ubuntu 13.10 64-bit installation, we have to first set up our development environment for the kernel reconfiguration:
sudo apt-get update sudo apt-get install -y git fakeroot ncurses-dev sudo apt-get build-dep -y linux-image-$(uname -r)
Then, download the latest kernel sources from Ubuntu’s git repository:
git clone git://kernel.ubuntu.com/ubuntu/ubuntu-saucy.git
Configuring the kernel
In order to start the kernel configuration process, we can run the following:
cd ubuntu-saucy/ chmod a+x debian/scripts/* chmod a+x debian/scripts/misc/* fakeroot debian/rules clean fakeroot debian/rules editconfigs
The last command will go through all the architectures supported and ask us if we want to change the default configuration for it. In our case, we only want to configure the amd64 architecture:
Do you want to edit config: amd64/config.flavour.generic? [Y/n]
If we press enter we will get into the kernel configuration screen for the amd64 architecture. To activate the user namespace, we have to first deactivate XFS support (this will likely change in future versions of the kernel). To do so, we navigate to File Systems -> XFS filesystem support and press N to deactivate. Then, if we navigate to General setup -> Namespaces support we will see that a new entry User namespace (NEW) has appeared. Activate it by pressing Y.
There are other options in the kernel related to LXC/Docker that are worth mentioning:
If we want to activate cgroup’s memory swap controller in the kernel configuration without the need to append cgroup_enable=memory swapaccount=1 to our GRUB configuration later on, we can do it by just activating the entry General setup -> Control Group support -> Memory Resource Controller Swap Extension enabled by default
If we want to increase the security of our containers and prevent non-privileged users from running the dmesg command, we can activate the option Security options -> Restrict unprivileged access to the kernel syslog
If we want to activate the AUFS filesystem support in our kernel without the need to install the linux-image-extra package later on, we can bundle AUFS in the main kernel configuration at this point by activating Ubuntu Supplied Third-Party Device Drivers -> Aufs (Advanced multi layered unification filesystem) support pressing Y
To exit, press ESC ESC to go back until you get a prompt to save the changes. Save them and exit the wizard. You can skip configuring the remaining architectures.
Building and installing the kernel
Once configured, we are ready to compile the kernel by executing:
fakeroot debian/rules clean fakeroot debian/rules binary-headers binary-generic skipabi=true skipmodule=true
The skipabi=true and skipmodule=true flags are to skip some checks of the kernel compilation process that are used when building official kernels. After the kernel is compiled and packaged, we’ll have the following files in the parent folder:
linux-headers-3.11.0-15_3.11.0-15.23_all.deb linux-headers-3.11.0-15-generic_3.11.0-15.23_amd64.deb linux-image-3.11.0-15-generic_3.11.0-15.23_amd64.deb linux-image-extra-3.11.0-15-generic_3.11.0-15.23_amd64.deb linux-tools-3.11.0-15-generic_3.11.0-15.23_amd64.deb
In our case, we just want to install the kernel headers and the main image, and restart:
sudo dpkg -i linux-headers*.deb sudo dpkg -i linux-image-3*.deb sudo shutdown -r now
Once the host is up and running again, we can check that the user namespace has been activated:
root@server:~# lxc-checkconfig --- Namespaces --- Namespaces: enabled Utsname namespace: enabled Ipc namespace: enabled Pid namespace: enabled User namespace: enabled Network namespace: enabled Multiple /dev/pts instances: enabled --- Control groups --- Cgroup: enabled Cgroup clone_children flag: enabled Cgroup device: enabled Cgroup sched: enabled Cgroup cpu account: enabled Cgroup memory controller: enabled Cgroup cpuset: enabled --- Misc --- Veth pair device: enabled Macvlan: enabled Vlan: enabled File capabilities: enabled
Docker and the user namespace
Docker does not yet support the use of user namespaces for its containers, but for the impatients, it’s possible to make it work in the current version (0.7.1) by hacking the code a little bit. But let’s save that for another blog post!
Thanks for reading!