Basics of Docker

8 minute read

Few Terminologies

Docker Engine

Docker Engine is a client-server application with these major components:

  • A server which is a type of long-running program called a daemon process (the dockerd command).
  • A REST API which specifies interfaces that programs can use to talk to the daemon and instruct it what to do.
  • A command line interface (CLI) client (the docker command).

2

The CLI uses the Docker REST API to control or interact with the Docker daemon through scripting or direct CLI commands. Many other Docker applications use the underlying API and CLI.
The daemon creates and manages Docker objects, such as images, containers, networks, and volumes.

Docker daemon

The Docker daemon (dockerd) listens for Docker API requests and manages Docker objects such as images, containers, networks, and volumes. A daemon can also communicate with other daemons to manage Docker services.

Docker client

The Docker client (docker) is the primary way that many Docker users interact with Docker. When you use commands such as docker run, the client sends these commands to dockerd, which carries them out. The docker command uses the Docker API. The Docker client can communicate with more than one daemon.

Docker registries

A Docker registry stores Docker images. Docker Hub is a public registry that anyone can use, and Docker is configured to look for images on Docker Hub by default. You can even run your own private registry.
When you use the docker pull or docker run commands, the required images are pulled from your configured registry. When you use the docker push command, your image is pushed to your configured registry.

Images

An image is a read-only template with instructions for creating a Docker container. Often, an image is based on another image, with some additional customization. For example, you may build an image which is based on the ubuntu image, but installs the Apache web server and your application, as well as the configuration details needed to make your application run.

CONTAINERS

A container is a runnable instance of an image. You can create, start, stop, move, or delete a container using the Docker API or CLI. You can connect a container to one or more networks, attach storage to it, or even create a new image based on its current state.
By default, a container is relatively well isolated from other containers and its host machine. You can control how isolated a container’s network, storage, or other underlying subsystems are from other containers or from the host machine.
A container is defined by its image as well as any configuration options you provide to it when you create or start it. When a container is removed, any changes to its state that are not stored in persistent storage disappear.

Docker Architecture

Docker uses a client-server architecture. The Docker client talks to the Docker daemon, which does the heavy lifting of building, running, and distributing your Docker containers. The Docker client and daemon can run on the same system, or you can connect a Docker client to a remote Docker daemon. The Docker client and daemon communicate using a REST API, over UNIX sockets or a network interface.

3

First Docker Container

$ docker container run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:4cf9c47f86df71d48364001ede3a4fcd85ae80ce02ebad74156906caff5378bc
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

The steps are clearly shown on above output. First the docker daemon looked for the local image with name hello-world. If the image is not found locally, then it checked whether it is on default docker registry which is docker hub. As there was a image called hello-world on the docker hub, it pulled that image down, ran it on a container and exited.

1.png

Docker vs VM

Looking at above example, docker kind of looked like vm. But here are few differences.

  • The VM is a hardware abstraction: it takes physical CPUs and RAM from a host, and divides and shares it across several smaller virtual machines. There is an OS and application running inside the VM, but the virtualization software usually has no real knowledge of that.
  • A container is an application abstraction: the focus is really on the OS and the application, and not so much the hardware abstraction. Many customers actually use both VMs and containers today in their environments and, in fact, may run containers inside of VMs.

Docker images

Fetching docker image from the registry

$ docker image pull alpine
Using default tag: latest
latest: Pulling from library/alpine
df20fa9351a1: Pull complete
Digest: sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest

This command will look at the default docker registry ie dockerhub (can be changed) for image called alpine and if found, it will download the image on our local box. Now with this image, we can create multiple containers which are like the multiple instances of this image.

Alpine Linux is a Linux distribution based on musl and BusyBox, designed for security, simplicity, and resource efficiency.

Listing the images on our box

$ docker image ls
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
alpine              latest              a24bb4013296        3 months ago        5.57MB
hello-world         latest              bf756fb1ae65        8 months ago        13.3kB

We have two images on the box, one being hello-world which we fetched earlier and other one is alpine.

Running container based on the image

$ docker container run alpine ls -la
total 8
drwxr-xr-x    1 root     root             6 Sep 24 06:19 .
drwxr-xr-x    1 root     root             6 Sep 24 06:19 ..
-rwxr-xr-x    1 root     root             0 Sep 24 06:19 .dockerenv
drwxr-xr-x    2 root     root          4096 May 29 14:20 bin
drwxr-xr-x    5 root     root           340 Sep 24 06:19 dev
drwxr-xr-x    1 root     root            66 Sep 24 06:19 etc
drwxr-xr-x    2 root     root             6 May 29 14:20 home
drwxr-xr-x    7 root     root           223 May 29 14:20 lib
drwxr-xr-x    5 root     root            44 May 29 14:20 media
drwxr-xr-x    2 root     root             6 May 29 14:20 mnt
drwxr-xr-x    2 root     root             6 May 29 14:20 opt
dr-xr-xr-x  768 root     root             0 Sep 24 06:19 proc
drwx------    2 root     root             6 May 29 14:20 root
drwxr-xr-x    2 root     root             6 May 29 14:20 run
drwxr-xr-x    2 root     root          4096 May 29 14:20 sbin
drwxr-xr-x    2 root     root             6 May 29 14:20 srv
dr-xr-xr-x   13 root     root             0 Aug 21 07:57 sys
drwxrwxrwt    2 root     root             6 May 29 14:20 tmp
drwxr-xr-x    7 root     root            66 May 29 14:20 usr
drwxr-xr-x   12 root     root           137 May 29 14:20 var

What happened in the background when we ran the command is that the docker client requested docker daemon to search for image called alpine and when the daemon found the image name called alpine then it created a brand new container and ran the command inside the container. Then container shut down.

Now if we were to run the same command again, the container that will be created this time will be a brand new container. I will demonstrate this in a second.

Creating new container executing /bin/sh

$ docker container run alpine /bin/sh

Command executed successfully but nothing happened. WHY? It is because the command executed successfully and the container shut itself down. To tell the docker that we need a interactive session we use following commands.

$ docker container run -it alpine /bin/sh
/ # ls -la
total 8
drwxr-xr-x    1 root     root            18 Sep 24 07:00 .
drwxr-xr-x    1 root     root            18 Sep 24 07:00 ..
-rwxr-xr-x    1 root     root             0 Sep 24 07:00 .dockerenv
drwxr-xr-x    2 root     root          4096 May 29 14:20 bin
drwxr-xr-x    5 root     root           360 Sep 24 07:00 dev
drwxr-xr-x    1 root     root            66 Sep 24 07:00 etc
drwxr-xr-x    2 root     root             6 May 29 14:20 home
drwxr-xr-x    7 root     root           223 May 29 14:20 lib
drwxr-xr-x    5 root     root            44 May 29 14:20 media
drwxr-xr-x    2 root     root             6 May 29 14:20 mnt
drwxr-xr-x    2 root     root             6 May 29 14:20 opt
dr-xr-xr-x  910 root     root             0 Sep 24 07:00 proc
drwx------    1 root     root            26 Sep 24 07:00 root
drwxr-xr-x    2 root     root             6 May 29 14:20 run
drwxr-xr-x    2 root     root          4096 May 29 14:20 sbin
drwxr-xr-x    2 root     root             6 May 29 14:20 srv
dr-xr-xr-x   13 root     root             0 Aug 21 07:57 sys
drwxrwxrwt    2 root     root             6 May 29 14:20 tmp
drwxr-xr-x    7 root     root            66 May 29 14:20 usr
drwxr-xr-x   12 root     root           137 May 29 14:20 var
/ # exit

This time the container didnot shut down but instead gave us a shell to work with.Now on this shell inside of our newly created container we can execute shell commands.

Listing the containers

Active Containers

To list the currently active container we can use following command.

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Looks like there is no any results. It is because we do not have any active running containers.

All Containers

$ docker container ls -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
21bcebe696a3        alpine              "/bin/sh"           6 minutes ago       Exited (0) 3 minutes ago                        strange_bouman
6684f8bd6f73        alpine              "/bin/sh"           8 minutes ago       Exited (0) 8 minutes ago                        brave_wescoff
d5d18e291759        alpine              "ls -la"            47 minutes ago      Exited (0) 47 minutes ago                       funny_blackburn
32045da0a193        hello-world         "/hello"            50 minutes ago      Exited (0) 50 minutes ago                       recursing_chaum

These are the list of containers that were created. And we can see from the status that they exited some N minutes ago. One interesting thing here is notice the CONTAINER ID of each of the container created, they all are different which means all the containers we have created are indeed different from each other even though they are created from same image.

Reference

https://training.play-with-docker.com/ops-s1-hello/
https://docs.docker.com/get-started/overview/

Tags:

Categories:

Updated: