Playing with Docker on ARM

It's been a while since i started using operating system/container/lightweight virtualization or wathever name you find suitable for it. In the end is a more efficient way of executing isolated systems without the weight of a hypervisor that recreates a computer.

I've used User Mode Linux that allows you to execute multiple kernels inside the computer, Linux-Vserver that creates execution context to isolate and manage the resources the “virtual machines” and Linux Containers (LXC) that use cgroups to isolate and restrict resources for certain proceses or the whole operating system.
LXC and Linux Vserver are somewhat equivalent technologies with a very different implementation, the advantage of LXC is that is being supported by a big community of developers and the underlaying infrastructure for them (cgroups) is part of the official Linux kernel distribution so you can say that LXC is supported in the upstream kernel.
On the LXC arena there's a very interesting approach: docker a system that allows us to create containers and establish reationships between them in a very easy way. It also allows you to upload your images to a central repository or maintain your own.
In this post i'm gonna setup a little proof of concept wordpress service using docker, let's get our hands dirty…

The “docker way” is to have small containers that perform only one task but you can use them as you please (eg. launching a Full OS on a container by just calling /sbin/init or /usr/lib/systemd/systemd)
So let's try a basic example that's been around the net for a while[2]: a wordpress site.
We all know that wordpress needs a database so the logical assumption would be to create two containers but we really need 3: one for wordpress, mysql and data store.

First we have to create the data store. Basically we create a container with an associated volume /var/lib/mysql thanks to the aufs all the containers that get associated to this volume will “mount” it in their respective /var/lib/mysql location.

$ docker run -v /var/lib/mysql --name=mysql_datastore -d busybox echo "Initiaizing MySQL DataStore"

#checkout the volume directory

$ sudo ls -la /var/lib/docker/vfs/dir/e5937a892ebf9a6a35bc6cdca89d9637a7964f72a908d48746453abcd242940e
[sudo] password for ichavero: 
total 8
drwxr-xr-x 2 root root 4096 Sep 11 06:49 .
drwx------ 3 root root 4096 Sep 11 06:49 ..



We can see the directory associated to the volume that i've created.<br /> This container does not have to be running, just have to be created an associated to the volume we created with it.
Then we create the mysql container:

$ docker run --name=mysql_server -e MYSQL_ROOT_PASSWORD=testpass -d mysql



Whoops! i'm using a arm operating system and most docker images are x86_64 so i had to create a arm fedora image. Note that this also should work for arm images ;)
First of all i created a tarball with a minimum system:

yum -y --releasever=20 --nogpg --installroot=/home/ichavero/lxcStuff/filesystems/fedora-arm \
          --disablerepo='*' --enablerepo=fedora install \
          systemd passwd yum fedora-release vim-minimal openssh-server procps-ng



Once the tarball was created i loaded it to docker using the <i>docker import</i> command:

$ cat fedora-arm.tar | docker import - fedora-arm
$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
fedora-arm             latest              34fed62416f0        3 minutes ago       490.8 MB
mysql                   latest              a950533b3019        3 weeks ago         235.6 MB
fedora                  latest              88b42ffd1f7c        8 weeks ago         373.7 MB
busybox                 latest              a9eb17255234        3 months ago        2.433 MB


We have to create a container in order to be able to create an image that we can upload to a repository. Run the container with docker run, execute bash and make appropiate changes in this case i'll just modify the /etc/issue file since this container is going to be a generic image.

$ docker run --name=fedora-20-arm -i -t fedora-arm   /usr/bin/bash
bash-4.2# vi /etc/issue
bash-4.2# cat /etc/issue
Fedora release 20 (Heisenbug) - by SotolitoLabs (imcsk8)
Kernel \r on an \m (\l)
bash-4.2# exit
exit
$ docker diff fedora-20-arm
A /.bash_history
C /etc
C /etc/issue



To save the sate of the container in a image you issue <i>docker commit</i>

$ docker commit fedora-20-arm imcsk8/fedora-20-arm
c120847615dc560d089ec84b5d194b9824af83c81231a2f2db8e7242116be210

ichavero@kickflip:~$ docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
imcsk8/fedora-20-arm   latest              c120847615dc        6 seconds ago       490.8 MB
fedora-arm             latest              34fed62416f0        55 minutes ago      490.8 MB
mysql                   latest              a950533b3019        3 weeks ago         235.6 MB
fedora                  latest              88b42ffd1f7c        8 weeks ago         373.7 MB
busybox                 latest              a9eb17255234        3 months ago        2.433 MB



I wanted my friends to enjoy this beautiful image so i uploaded it to the docker registry:

ichavero@kickflip:~$ docker push imcsk8/fedora-20-arm
The push refers to a repository [imcsk8/fedora-20-arm] (len: 1)
Sending image list
Pushing repository imcsk8/fedora-20-arm (1 tags)
34fed62416f0: Image successfully pushed 
c120847615dc: Image successfully pushed 
Pushing tag for rev [c120847615dc] on {https://cdn-registry-1.docker.io/v1/repositories/imcsk8/fedora-20-arm/tags/latest}


I created two more containers: one for mysql and another for wordpress, this time i had to install the proper software in each one.

$ docker run --name=fedora-20-arm-mysql -i -t imcsk8/fedora-20-arm   /usr/bin/bash
bash-4.2# exit
$ docker run --name=fedora-20-arm-wordpress -i -t imcsk8/fedora-20-arm   /usr/bin/bash
bash-4.2# exit


This is just a way of creating them and it might not be the best one.
To prepare the mysql container, i took the entrypoint.sh from the official mysql container to make things more docker style:
First i had to copy the file but the version of docker i used a little trick that i learned when i used Linux Vserver, find the container filesystem and copy the files there (better than a KVM VM right?).
Get the container ID:

$ docker inspect -f '{{.Id}}'  fedora-20-arm-mariadb
b78d09e751bbeb955cf07c7f0a834d76ce2334a555f13add7621506b14a76cdc


Then just copy the file:

$ sudo cp entrypoint.sh /var/lib/docker/aufs/mnt/b78d09e751bbeb955cf07c7f0a834d76ce2334a555f13add7621506b14a76cdc/.


Check the system:

$ docker start -a -i fedora-20-arm-mariadb
bash-4.2# ls -la /entrypoint.sh 
-rwxr-xr-x 1 root root 1289 Sep 23 19:56 /entrypoint.sh
bash-4.2# exit


Commit our changes to a image:

$ docker commit fedora-20-arm-mariadb imcsk8/fedora-20-arm-mariadb


References