What do we want to containerize  

This can be done with whatever binary you choose. You will just need to make sure you properly satisfy the dependencies. I decided to go with containerizing ping. It has a reasonable number of dependencies, and provides a realistic view of how dirty this can really get.

Gather out dependencies

This machine is running CentOS 7. If you are using another distro, this should work just fine, but your library names/paths might look a bit different. Follow the instructions regardless, and you should still have a working container by the time your reach the end.

[root@testbox docker-stuff]# mkdir ping-container
[root@testbox docker-stuff]# cd ping-container
[root@testbox ping-container]# ldd /bin/ping
	linux-vdso.so.1 =>  (0x00007ffc6c9e4000)
	libcap.so.2 => /lib64/libcap.so.2 (0x00007f88ad181000)
	libidn.so.11 => /lib64/libidn.so.11 (0x00007f88acf4e000)
	libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007f88acaec000)
	libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f88ac8d2000)
	libm.so.6 => /lib64/libm.so.6 (0x00007f88ac5d0000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f88ac20c000)
	libattr.so.1 => /lib64/libattr.so.1 (0x00007f88ac007000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007f88abe03000)
	libz.so.1 => /lib64/libz.so.1 (0x00007f88abbec000)
	/lib64/ld-linux-x86-64.so.2 (0x00005578ba8cf000)
[root@testbox ping-container]# 

note: It is important that you create a directory for the container, as it will later be our “/”.  

ldd shows us the libraries needed to run the ping binary. The second field is the absolute path. Interesting side note, linux-vdso.so.1 is a library injected into every process by the kernel. So we dont need to copy it.

[root@testbox ping-container]# cp --parents /bin/ping ./
[root@testbox ping-container]# for i in `ldd /bin/ping | grep -v linux-vdso.so.1 | awk {' if ( $3 == "") print $1; else print $3 '}`; do cp --parents $i ./ ; done
[root@testbox ping-container]# 

Don’t let this fool you, my for-loop was just a sloppy way of pulling in most of those library files mentioned in ldd. It doesnt matter how you get it there, just get your dependencies in a directory with “relative-absolute” pathing.

Double check our work

[root@testbox ping-container]# find ./
[root@testbox ping-container]# 

This is what our soon-to-be container will have in it. I can’t stress enough that you ensure all the dependencies enumerated from ldd are met.

Build out container

[root@testbox ping-container]# cd ..
[root@testbox docker-stuff]# tar -C ping-container -c . | docker import - ping-container
[root@testbox docker-stuff]# 

So we have our binary /bin/ping, and all the necessary libraries. This part can be tricky, if you mess up the tar, and dont include the current directory, your container will not work.  

Dont fight this, just do it how I did, it will save you some time. If you mess up the tar, it will just contain the directories inside ‘ping-container’, but not actually ping-container itself to act as “/” so the whole thing just fails.  

The above cd’s into ping-container and tarballs “.”. This is then piped over to docker import. So now, we should have a new image named ping-container

[root@testbox docker-stuff]# docker images | grep ping-container
ping-container                               latest              b5bf65ceff1a        9 minutes ago       6.48 MB
[root@testbox docker-stuff]# 


Test it out

[root@testbox docker-stuff]# docker run -it ping-container /bin/ping -c 4
PING ( 56(84) bytes of data.
64 bytes from icmp_seq=1 ttl=57 time=1.35 ms
64 bytes from icmp_seq=2 ttl=57 time=1.03 ms
64 bytes from icmp_seq=3 ttl=57 time=1.03 ms
64 bytes from icmp_seq=4 ttl=57 time=1.00 ms

--- ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 1.006/1.108/1.359/0.150 ms
[root@testbox docker-stuff]# 

Success! We were able to ping googles resolvers with our containerized ping.