Category Archives: Containers

Containers for Fun and Profit

With all the whirl about containers I decided I could wait no longer to join the fray. Here is a log of some of the things I learned.

Basic test, e.g. what the heck is this?

I spun up a cent7 vm several months back. Apparently my repos were a tad old and things didnt work until i did a yum update first, then reboot. Then I could systemctl enable docker, systemctl start docker

Note you MUST sudo in for docker commands to work

Also note: cent7 has docker in it natively – no need to wget install it (unless you want to use some of the new features like the networking module)

The following is your smoke test:

sudo docker run hello-world 

Test 2: Expanded sample

This worked flawlessly…

Test 3: Interactive sample

Ditto, worked perfectly

Test 4: Do my own thing

I made a “” app with the following code:

import time
while True:
	print "Hi! ", time.time()

I then made the following Dockerfile

RUN yum install python -y

And create the image with

	docker build -t looper .

When i ran the build one of the things I noticed is that python was already installed in the centos image. I modified the Dockerfile by removing the RUN line, and one cool thing is that when i re-ran the build command, the python install layer was automatically removed, and everything else was basically a noop. In other words docker appears to do a good job at being efficient.

I then ran my looper:

	docker run looper

Nothing happened… So i thought…and though… and eventually decided to try and attach. Ubeknowest to me, by doing docker run i WAS attached, but nonetheless I learned a few things:

  • To attach you need your container id
  • To get your container id you run “docker ps”

Once I did a docker attach to my container id, i saw nothing, still. I did a Ctrl-C and viola, my looper output appeared! I suspected buffering, which turned out to be the case. I modified looper as follows:

import time
import sys
while True:
	print "Hi! ", time.time()

Then rebuilt, and re-ran, and it all worked.

Note that this only runs the command in the foreground. To run it in the background:

	docker run -d looper

You can then docker ps, find the cid, docker attach to it. But… you cannot detach (without sending a SIGKILL)! The docks say Ctrl-P + Ctrl+Q will detach, but this appears to only work if you use the following command when running it:

	docker run -tdi looper

Where t means create a tty, and i means “keep stdin open even if not attached”. This works well.

Note that each time i make changes to looper, when i rebuild it takes at most 20 seconds.. if no changes, docker takes milliseconds…

Test 5: layers

What if the container modifies a file?

I modified to write to stdout and a file:

import time
import sys
while True:
	msg = "Hi! " + str(time.time())
	print msg
	with open('myfile','a') as f:
		f.write(msg + '\n')

For fun i created a file named “myfile”, then build the image, then ran the container. When it runs i can do a docker diff:

# docker diff f04849645523
A /myfile

And to be clear, this means the file was added in the image. Docker wont let the app reach into my own version of “myfile”.

What if i want to see the file? In older versions of docker, apparently you had a few options, such as running ssh, or making a snapshot, but now its easy:

	docker exec -t -i <cid> /bin/bash

You can then just cat the file, etc. If you actually want to copy the files out,
you can export the whole filesystem (docker export ) as a tar, but this seems nuts. If you just want a single file, use docker cp:

docker cp <cid>:<src> <dest>

Test 6: CPU limit

You can do a couple things:

1) Limit the share of cpu usage across multiple containers. This is done by specifying a relative weighting (with -c)

2) Pin the process to certain cpus with —cpuset-cpus=

I havent been able to find an equivalent to the simple “limit to N processors” idea on virtual machines. The weighting is fairly close.