Wednesday, February 1, 2017

Docker's namespaces - See them in CentOS

In the Docker Networking Cookbook (I got my copy directly from Pact Publishing), Jon Langemak explains why the iproute2 utilities can't see Docker's network namespaces: Docker creates its namespace objects in /var/run/docker/netns, but iproute2 expects to find them in /var/run/netns.

Creating a symlink from /var/run/docker/netns to /var/run/netns is the obvious solution:

 $ sudo ls -l /var/run/docker/netns  
 total 0  
 -r--r--r--. 1 root root 0 Feb 1 11:16 1-6ledhvw0x2  
 -r--r--r--. 1 root root 0 Feb 1 11:16 ingress_sbox  
 $ sudo ip netns list  
 $ sudo ln -s /var/run/docker/netns /var/run/netns  
 $ sudo ip netns list  
 1-6ledhvw0x2 (id: 0)  
 ingress_sbox (id: 1)  

But there's a problem. Look where this stuff is mounted:

 $ ls -l /var/run  
 lrwxrwxrwx. 1 root root 6 Jan 26 20:22 /var/run -> ../run  
 $ df -k /run  
 Filesystem   1K-blocks Used Available Use% Mounted on  
 tmpfs      16381984 16692 16365292  1% /run  

The symlink won't survive a reboot because it lives in a memory-backed filesystem. My first instinct was to have a boot script (say /etc/rc.d/rc.local) create the symlink, but there's a much better way.

Fine, I'm starting to like systemd

Systemd's tmpfiles.d is a really elegant way of handling touch files, symlinks, empty directories, device nodes, pipes and whatnot which live in volatile filesystems. The feature works from these directories:
  • /etc/tmpfiles.d
  • /run/tmpfiles.d
  • /usr/lib/tmpfiles.d
When the directives found in these directories contradict one another, the instance I've listed earlier wins. This allows an administrator to override package declarations in /usr/lib/tmpfiles.d by creating an entry in /etc/tmpfiles.d. Conflicts between files are resolved by the order of their appearance in a lexical sort.

So, what goes in these directories? Files named <whatever>.conf. Each line in these files controls creation of a file / folder / symlink / etc... There are switches and options to control ownership, permissions, overwrite condition, contents, and so forth.

Here's the file that causes systemd to create my symlink on every boot:

 $ cat /etc/tmpfiles.d/netns.conf   
 L /run/netns - - - - ./docker/netns  

I'm still not quite ready to forgive systemd for taking away the udev network interface naming persistency stuff and replacing it with something that's useless in virtual machines (this helps). But I'm getting there.

Lately I've been really liking each new facet of systemd as I've discovered it.