Docker – Basics

Docker is the container runtime and orchestration engine.

  • Enterprise Edition (EE) and Community Edition (CE)
  • Moby is the Open Source project of Docker — Moby consists of modular components.

When to use Docker

  • Simplifying Configuration – Put the configuration and environment settings in the code
  • Application Isolation
  • Server Consolidation
  • Dev/Production environment are the same
  • Debugging – Bugs in production can be replicated in Development easily

Docker Architecture

Docker is a client-server architecture.

  • Clients communicate with the Docker daemon (server) using REST APIS through UNIX sockets or Network Interfaces.
  • Docker daemon (dockerd) handles building, running, and distribute containers.
    • dockerd manages the following docker objects: Images, Containers, Networks, and Volumes.
  • Docker client (Docker) sends the user commands to dockerd.
  • Docker Registries store docker images.
    • Private Registry
    • Public Registry such as DockerHub

Docker Images

Docker image is a read-only template and contains instructions for creating a Docker container.

  • An Image can be based on other images – multiple layers -.
    • Each layer represents an instruction in the image’s Dockerfile.
    • Each layer is read-only, except the last one.
    • Each layer has only a set of differences from the layer before it.
  • A container adds a new writable layer on top of the underlying layers.

Docker Containers

A container is a runnable instance of an image.

  • Containers can connect to networks and can attach persistent storages.
  • A new image can be created based on the container’s current state.
  • Containers are isolated from other containers and the host machine.
  • All changes are stored in the writable layer, and the writable layer is deleted when the container is deleted. The image remains unchanged.

Build Images with Dockerfile

A Dockerfile is a set of instructions (called directives) used to construct a Docker image.

  • FROM: sets the basic image
  • ENV: sets environment variables
  • RUN: creates a new layer on top of the previous one
  • CMD: specifies a default command to run a container at the execution time
  • USER: sets the user name (or UID) and optional group name (or GID)
    • USER <user>[:<group>]
    • USER <UID>[:<GID>]
  • WORKDIR: sets the working directory
FROM ubuntu:jammy

ENV NGINX_VERSION 1.23.2

RUN apt-get update && apt-get install -y curl
RUN apt-get update && apt-get install -y nginx=$NGINX_VERSION

CMD ["nginx", "-g", "daemon off;"]

You can build the image with the “docker build” command.

docker build -t {TAG_NAME} .

Services

  • Services can scale containers across multiple Docker daemons.
  • Services define and manage the desired state.
  • Service is load-balanced.

Docker Swarm

  • Multiple Docker daemons (Master and Workers) are working together.
  • The daemons all communicate using the Docker API
  • Features
    • Scaling, Load Balancing
    • Service Discovery: Each service is assigned with a unique DNS name
    • Rolling update
  • Supported in Docker 1.12 and higher

Docker Engine

Docker engine is base on open-standards by the Open Container Initiative (OCI) and modular in design.

  • Initial Release of Docker: Docker daemon + LXC (Lightweight Linux container)
  • LXC was replaced with libcontainer

Docker became more modular:

  • runc
    • Implementation of the OCI container-runtime-spec
    • CLI wrapper for libcontainer
    • Responsible to create containers
  • containerd
    • Manages Container lifecycle: start, stop, pause, delete
  • shim
    • Implementation of daemon-less Containers

Container Lifecycle

  • Running
  • Stopped
  • Restarted

Creating a Container

  1. Executing a command using CLI
  2. Docker client uses the appropriate API payload and POSTs to the correct API endpoint
  3. Docker daemon receives requests
  4. Docker daemon calls ‘containerd‘ to start a new container
  5. containerd‘ creates an OCI bundle from the Docker image
  6. containerd‘ instructs ‘runc‘ to create a container using the OCI bundle
  7. ‘runc’ interfaces with the OS kernel to get the constructs needed to create a container (namespaces, cgroups, etc.)
  8. Container process starts as a child process
  9. runc‘ exits once the container starts
  10. Container is running

Running Containers

docker run [options] Image[:Tag] [Command] [Arg…]
  • Image (required): the name of the container image to run.
  • Tag (optional): a specific image tag, usually used to pull a specific version
  • Command (optional): the command to run inside the container
  • Arg (optional): arguments to pass when running the command

Examples

# image only
docker run hello-world
docker image ls
docker container ls -a
#image:tag
docker run nginx:1.23.2 
# the process is running
Ctrl + C # to exit
# image command arg1 arg2
docker run busybox echo hello world!

Run Command Options

  • -d, detach: run the container in a detached mode in the background
  • name: a container name; not specified, a random name is assigned.
  • restart: specify when the container should restart
    • no (default): never restart the container
    • on-failure: only if the container fails
    • always: always restart
    • unless-stopped: always restart unless the container was manually stopped
  • -p <host port>:<container port> : port mapping
  • -m, memory: hard limit on memory usage
  • -i, interactive: keep STDIN open even if not attached
  • -t, tty: allocate a pseudo-TTY
docker run -d --name my-nginx-server --restart on-failure -p 8080:80 -m 256M nginx
docker container ls
curl localhost:8080

Storage Driver

Storage drivers provide a pluggable framework for the temporary internal storage of a container’s writable layer.

  • devicemapper
    • Block-storage
    • Efficient for doing a lot of writes
    • Default for CentOS 7 and earlier
  • overlay2
    • File-based storage
    • Default for CentOS 8+ and Ubuntu
docker info

Selecting a Storage Driver

By default, Docker automatically selects a storage driver compatible with your environment.

You can override the storage driver in two ways:

  • Set the –storage-driver flag when starting Docker
  • [Recommended] Update the “storage-driver” value in the “/etc/docker/daemon.json”
sudo vi /etc/docker/daemon.json
{
  "storage-driver: "devicemapper"
}

sudo systemctl restart docker
docker info

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s