For clarification upfront: The “I” stands for Intershop and with that series of articles I want to elaborate a little bit on our recent adventures into the latest and greatest hype within the IT scene, which undoubtedly is Docker, the most successful containerization approach yet known. In this first part, I’m going to give a simplified and belletristic overview about what this technology is about, compare it to the approach of virtual machines and try to get started with the ultimate “hello world” example.
Two years back a colleague held an introduction talk about a “new” and “hot” technology. I’ve already heard rumors about that Docker-Container-Images buzz which was about to impiously exhume these ancient process isolation mechanisms of chroot, known in the Unix world since the 1980s. And yes, it was taking these principles and puts it on steroids by automating and simplifying it’s usage. I was hooked, when I saw one hundred Apache instances fired up by a tiny shell script, each one isolated on one host running the docker daemon while binding it’s own port to the containers port 80. In a matter of seconds everything was up and running.
Some basics
So, what is it about? The key difference between docker and traditional virtualization is that docker containers are a flavor of so called “Operating System-Level Virtualization”, while the opposite is sometimes called “Machine-Level Virtualization”. The pictures below show the difference between both approaches.
Operating System-Level Virtualization:
Machine-Level Virtualization:
The container based solution provides you with images at the size of the application and it’s dependencies sharing resources of the host operating system through a daemon service called docker engine, a virtual machine brings in the application, it’s dependencies plus the so called guest operating system which shares the host system resources through a hypervisor. While it seems to be comparable, let’s compare it by some points.
Size does matter, after all
First is size: Virtual machines bring their own complete operating system on which you can install your application. They need to be assigned CPU/RAM resources and disk space in terms of virtual disks. Every docker image just relies on it’s applications size and the dependencies it needs. Since the kernel resources of the host system are shared, so your hosts resources are shared as well. You build or deploy your application on base images which can vary from very small (alpine image at 5MB) to relatively large images (Ubuntu at 188MB).
If you need another virtual machine on that host similar to the first one you’ve created, the same size of it will be required to store another virtual machine instance. You also double the amount of virtual resources you lock for that virtual machine. In Docker you automatically re-use existing layers, since every image consists of a pancake style set of union filesystem layers (UFS). On top of this filesystem you have a so called writable container which saves only the changes, once you instantiated the image. Remember, it’s a static image – think of it as a template or class, and you when you run an image, a container is instantiated, comparably to the object of a class. Since the process started in the running container runs in the userspace of the host system, the hosts resources are shared directly. This saves quite some overhead.
Time to spin it up
The virtual machine needs to boot up. Depending on the underlying OS and specifics, this takes up to tens of seconds until the virtual machine is up and running. Docker instead is running the application as a single process in userspace of the host system and needs exactly the time it needs to be loaded into memory and started up.
Hands on – the hello world project
Instead of listing and comparing further features of VM versus Docker, let’s just have a look at some simple example. Starting from the precondition, that you installed docker on your host system, you should be able to run docker version.
[code]$ docker version
Client:
Version: 1.12.1
API version: 1.24
Go version: go1.6.3
Git commit: 23cf638
Built: Thu Aug 18 05:33:38 2016
OS/Arch: linux/amd64
Server:
Version: 1.12.1
API version: 1.24
Go version: go1.6.3
Git commit: 23cf638
Built: Thu Aug 18 05:33:38 2016
OS/Arch: linux/amd64
While you’re there, just create a simple Dockerfile with the following content.
[code]$ cat Dockerfile
FROM centos:7
RUN yum -y install epel-release && yum -y update && yum -y install figlet
ENTRYPOINT ["figlet"] [/code]
In the first line we denote, that we’re using the official centos7 image as base for our hello world application. We then install the epel-release repository, update the package repository tree and finally install the figlet application. The ENTRYPOINT declaration is said to allow you to run the container as it would be an executable. To build the image, call docker build like this. The “-t” sets a tag name for the image “hello” and the “.” says, that the dockerfile in the current working directory is used.
[code]$ docker build -t hello .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM centos:7
—> 980e0e4c79ec
Step 2 : RUN yum -y install epel-release && yum -y update && yum -y install figlet
—> Running in b6501f46fdd7
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
* base: centos.mirrors.as250.net
* extras: mirror.netcologne.de
* updates: artfiles.org
Resolving Dependencies
–> Running transaction check
—> Package epel-release.noarch 0:7-6 will be installed
–> Finished Dependency Resolution
Dependencies Resolved
…. snipped ….
Total download size: 125 k
Installed size: 657 k
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : figlet-2.2.5-9.el7.x86_64 1/1
Verifying : figlet-2.2.5-9.el7.x86_64 1/1
Installed:
figlet.x86_64 0:2.2.5-9.el7
Complete!
—> 825d21e349ad
Removing intermediate container b6501f46fdd7
Step 3 : ENTRYPOINT figlet
—> Running in e76749a43257
—> e3071cb3f134
Removing intermediate container e76749a43257
Successfully built e3071cb3f134
We now have built a hello world image, which we can find in our local image registry. Now start the image as simple as:
[code]$ docker run -it hello Hello Intershop
_ _ _ _ ___ _ _
| | | | ___| | | ___ |_ _|_ __ | |_ ___ _ __ ___| |__ ___ _ __
| |_| |/ _ \ | |/ _ \ | || ‘_ \| __/ _ \ ‘__/ __| ‘_ \ / _ \| ‘_ \
| _ | __/ | | (_) | | || | | | || __/ | \__ \ | | | (_) | |_) |
|_| |_|\___|_|_|\___/ |___|_| |_|\__\___|_| |___/_| |_|\___/| .__/
|_|
Summary
In this introduction post about Docker @ Intershop, we compared some aspects as time and space of virtual machines with the container approach and created a little hello world example using docker containers.
[1] Docker: a Software as a Service, Operating System-Level Virtualization Framework. 2014. http://journal.code4lib.org/articles/9669?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+c4lj+(The+Code4Lib+Journal) [2] The docker platform. https://docs.docker.com/engine/
Pictures taken from https://www.docker.com/what-docker