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 “looper.py” app with the following code:
#!/usr/bin/python
import time
while True:
print "Hi! ", time.time()
time.sleep(1)
I then made the following Dockerfile
FROM docker.io/centos:latest
RUN yum install python -y
COPY looper.py /
CMD /looper.py
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:
#!/usr/bin/python
import time
import sys
while True:
print "Hi! ", time.time()
sys.stdout.flush()
time.sleep(1)
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 looper.py to write to stdout and a file:
#!/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)
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.