Working with Linux Containers
What are Linux Containers?
Linux Containers (LXC) are a lightweight approach to virtualisation. Linux containers offer virtualisation at the Operating System level through a virtual environment that has its own process and network space. With LXC, there is no need for a Virtual Machine. Linux containers allow you to run multiple containers of different operating systems all within a sand-boxed environment (isolated from each other).
What is Docker?
Docker is a container based virtualisation tool that allows you to easily create and manage your containers. Docker is a very lightweight virtualisation framework providing the following features:
Sand-Box Environments isolated from the outside world
Portability - Containers are simply directories that can be copied and moved around quickly
Lightweight - Only uses the resources requested by each application
In the following example we are going to install the Docker framework onto an Ubuntu 14.04 LTS (64 bit) environment.
Installing Docker - Ubuntu 14.04 LTS (64 bit)
First we will update our repositories with the command: sudo apt-get update
$ sudo apt-get update
Next we issue the install command: sudo apt-get install docker.io
$ sudo apt-get install docker.io
Create a symbolic link:
$ sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker
Verify Docker Installation
The easiest way to verify our installation is to actually try it. In the following test, we are going to pull down an "Ubuntu" image and open a shell. The command to use for this is $ sudo docker run -i -t ubuntu /bin/bash
$ sudo docker run -i -t ubuntu /bin/bash
The output from the above command running is below:
john@ubuntu1404:~$ sudo docker run -i -t ubuntu /bin/bash Unable to find image 'ubuntu' locally Pulling repository ubuntu a7cf8ae4e998: Pulling image (quantal) from ubuntu, endpoint: https://cdn-registry-1.docker.io/v1/ 3db9c44f4520: Pulling image (lucid) from ubuntu, endpoint: https://cdn-registry-1.docker.io/v1/ 74fe38d11401: Pulling image (precise) from ubuntu, endpoint: https://cdn-registry-1.docker.io/v1/ a7cf8ae4e998: Download complete 3db9c44f4520: Download complete 74fe38d11401: Download complete 316b678ddf48: Download complete 99ec81b80c55: Download complete 5e019ab7bf6d: Download complete 511136ea3c5a: Download complete 6cfa4d1f33fb: Download complete ef519c9ee91a: Download complete 02dae1c13f51: Download complete e2aa6665d371: Download complete 5e66087f3ffe: Download complete f10ebce2c0e1: Download complete f0ee64c4df74: Download complete 2209cbf9dcd3: Download complete 82cdea7ab5b5: Download complete 07302703becc: Download complete 5dbd9cb5a02f: Download complete e7206bfc66aa: Download complete cf8dc907452c: Download complete cb12405ee8fa: Download complete 4d26dd3ebc1c: Download complete d4010efcfd86: Download complete WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : [188.8.131.52 184.108.40.206]
We can verify that we are now running within an Ubuntu 14.04 LTS container with the following commands issued from within the container:
lsb_release -a : Displays OS related information:
root@594825c51052:/# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 14.04 LTS Release: 14.04 Codename: trusty
Note the number that follows the "root@" is the container ID.
ifconfig : Display Network interface information:
john@ubuntu1404:~$ ifconfig docker0 Link encap:Ethernet HWaddr 00:00:00:00:00:00 inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::6010:2aff:fef4:ddb5/64 Scope:Link UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:16 errors:0 dropped:0 overruns:0 frame:0 TX packets:55 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1072 (1.0 KB) TX bytes:8619 (8.6 KB)
Notice the term "docker0" is specified at the start of the second line of output.
As we mentioned earlier, you are not limited to a single Operating System using containers. Below is a quick example of a Fedora image being used:
john@ubuntu1404:~$ sudo docker.io run -i -t fedora /bin/bash Unable to find image 'fedora' locally Pulling repository fedora b7de3133ff98: Pulling image (rawhide) from fedora, endpoint: https://cdn-registrb7de3133ff98: Download complete 511136ea3c5a: Download complete ef52fb1fe610: Download complete WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : [220.127.116.11 18.104.22.168] bash-4.2# bash-4.2# cat /etc/fedora-release Fedora release 20 (Heisenbug)
docker info : Display Docker Related information. This command is issued from the host system
john@ubuntu1404:~$ sudo docker info Containers: 1 Images: 23 Storage Driver: aufs Root Dir: /var/lib/docker/aufs Dirs: 25 Execution Driver: native-0.1 Kernel Version: 3.13.0-24-generic WARNING: No swap limit support
Displaying Docker Containers
To display running docker container information you can issue the command: docker ps
john@ubuntu1404:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
To display all docker containers we add the "-a" flag:
john@ubuntu1404:~$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 594825c51052 ubuntu:14.04 /bin/bash 5 minutes ago Exit 0 sharp_bohr
In this section we will look at how to control our containers. We will create a container using the following command:
$ JOB=$(sudo docker run -d ubuntu /bin/sh -c "while true; do echo Hello World; sleep 1; done") WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : [22.214.171.124 126.96.36.199]
The above command will run a simple "while true" loop in an Ubuntu container. We can confirm that this command is running by using the "ps" command as follows:
Display Running Containers
john@ubuntu1404:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f49ff80088f5 ubuntu:14.04 /bin/sh -c while tru About a minute ago Up About a minute jolly_pasteur
Stopping a Container
To stop the container we can issue the command: docker stop followed by its Job ID:
john@ubuntu1404:~$ sudo docker stop $JOB f49ff80088f517b46a57ae74dea225a515f0809446c830bdbec15b5b7dfd213f john@ubuntu1404:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
We can see from the "ps" command that our container is no longer running.
Starting a Container
We can restart our container by issuing the command: docker start followed by its Job ID.
john@ubuntu1404:~$ sudo docker start $JOB f49ff80088f517b46a57ae74dea225a515f0809446c830bdbec15b5b7dfd213f john@ubuntu1404:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f49ff80088f5 ubuntu:14.04 /bin/sh -c while tru 4 minutes ago Up 4 seconds jolly_pasteur
We can now see that our container is running again.
Killing/Stopping a Container
To kill our running container and remove it permanently we issue the following series of commands:
john@ubuntu1404:~$ sudo docker kill $JOB f49ff80088f517b46a57ae74dea225a515f0809446c830bdbec15b5b7dfd213f john@ubuntu1404:~$ sudo docker stop $JOB f49ff80088f517b46a57ae74dea225a515f0809446c830bdbec15b5b7dfd213f john@ubuntu1404:~$ sudo docker rm $JOB f49ff80088f517b46a57ae74dea225a515f0809446c830bdbec15b5b7dfd213f john@ubuntu1404:~$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Note: To remove a container, it has to be stopped first!
Set DNS settings - Domain Search order for containers
To set the DNS server for all our Docker containers we can use the command docker -d --dns 188.8.131.52
To set the DNS search domain for all our Docker containers, we can use the command docker -d --dns-search example.com
Docker User Permissions
By default normal users are unable to issue docker commands unless they use the "sudo" option to escalate their privileges. However, it is possible to give normal users the necessary permissions by adding their userid to the "docker" group. If a normal user tries to run a docker command and they are not a member of the docker group, you will see a message similar to the following:
john@ubuntu1404:~$ docker ps 2014/05/07 11:24:08 dial unix /var/run/docker.sock: permission denied
Add User to docker group
To add a user to the docker group, issue the following command: sudo usermod -a -G docker userid
john@ubuntu1404:~$ sudo usermod -a -G docker john
Now if we issue the "groups" command followed by the relevant userid we will notice that we still do not appear to be within the docker group. This is ok, all you need to do is logoff and then log back in.
Before logging out:
john@ubuntu1404:~$ groups john adm cdrom sudo dip plugdev lpadmin sambashare
After logging out and Logging back in:
john@ubuntu1404:~$ groups john adm cdrom sudo dip plugdev lpadmin sambashare docker
You should now see the group docker has been added. Now you should be able to issue docker commands without the sudo prefix:
john@ubuntu1404:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 11500463ac8a fedora:20 /bin/bash 7 minutes ago Exit 0 backstabbing_turing
Starting and Stopping the Docker Daemon
To verify that the docker daemon is running we can use the status command: sudo service docker.io status
To Stop the docker daemon we use the command: sudo service docker.io stop
To Start the docker daemon we use the command: sudo service docker.io start
To Restart the docker daemon we can use the command: sudo service docker.io restart
john@ubuntu1404:~$ sudo service docker.io status docker.io start/running, process 2656 john@ubuntu1404:~$ sudo service docker.io stop docker.io stop/waiting john@ubuntu1404:~$ sudo service docker.io start docker.io start/running, process 2729 john@ubuntu1404:~$ sudo service docker.io restart docker.io stop/waiting docker.io start/running, process 2788
For a list of commands available within Docker, simply issue the docker command with no arguments.
List of available Docker Commands
Commands: attach Attach to a running container build Build a container from a Dockerfile commit Create a new image from a container's changes cp Copy files/folders from the containers filesystem to the host path diff Inspect changes on a container's filesystem events Get real time events from the server export Stream the contents of a container as a tar archive history Show the history of an image images List images import Create a new filesystem image from the contents of a tarball info Display system-wide information insert Insert a file in an image inspect Return low-level information on a container kill Kill a running container load Load an image from a tar archive login Register or Login to the docker registry server logs Fetch the logs of a container port Lookup the public-facing port which is NAT-ed to PRIVATE_PORT ps List containers pull Pull an image or a repository from the docker registry server push Push an image or a repository to the docker registry server restart Restart a running container rm Remove one or more containers rmi Remove one or more images run Run a command in a new container save Save an image to a tar archive search Search for an image in the docker index start Start a stopped container stop Stop a running container tag Tag an image into a repository top Lookup the running processes of a container version Show the docker version information wait Block until a container stops, then print its exit code
As you have seen so far, docker is fairly simple to install and use. For a complete overview of docker, you should take a look at the docker site: Getting Started with Docker
This site is the official docker site and has an excellent interactive command tutorial that you can use to help learn and strengthen your docker knowledge. Manuals and documentation can also be found at this site.