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:

[code]
sudo docker run hello-world
[/code]

Test 2: Expanded sample

This worked flawlessly…

Test 3: Interactive sample

Ditto, worked perfectly

Test 4: Do my own thing

I made a “looper.py” app with the following code:

[code]
#!/usr/bin/python
import time
while True:
print "Hi! ", time.time()
time.sleep(1)
[/code]

I then made the following Dockerfile

[code]
FROM docker.io/centos:latest
RUN yum install python -y
COPY looper.py /
CMD /looper.py
[/code]

And create the image with

[code]
docker build -t looper .
[/code]

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:

[code]
docker run looper
[/code]

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:

[code]
#!/usr/bin/python
import time
import sys
while True:
print "Hi! ", time.time()
sys.stdout.flush()
time.sleep(1)
[/code]

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:

[code]
docker run -d looper
[/code]

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:

[code]
docker run -tdi looper
[/code]

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 looper.py to write to stdout and a file:

[code]
#!/usr/bin/python
import time
import sys
while True:
msg = "Hi! " + str(time.time())
print msg
with open(‘myfile’,’a’) as f:
f.write(msg + ‘\n’)
sys.stdout.flush()
time.sleep(1)
[/code]

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:

[code]
# docker diff f04849645523
A /myfile
[/code]

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:

[code]
docker exec -t -i <cid> /bin/bash
[/code]

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:

[code]
docker cp <cid>:<src> <dest>
[/code]

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.


Leave a Reply

Your email address will not be published. Required fields are marked *