March 18, 2017

Docker Default Executable

Docker Default Executable

A Default Executable is the command that will run when the container is started. It is defined in the Dockerfile as an ENTRYPOINT or CMD instruction. CMD and ENTRYPOINT instructions both define the startup command for a container. You can enter one or the other, or both in the Dockerfile.
  • This example runs the debian container and starts a shell. The default executable, the shell, is defined in the Dockerfile as a default executable.
  • If a default executable is not specified in the Dockerfile and an argument is not given at the command line, the container will error out when called:


  • The above error can be remedied by entering the starting command at the command line. In this example, the shell, sh, is given as the starting command:
  • Entry Point instruction
  • An ENTRYPOINT allows you to configure a container to behave as it were the configured default executable. It is typically used when you don't expect the user to override the executable in the ENTRYPOINT instruction.
    • Application runs as PID 1
    • ENTRYPOINT gives a container its default nature or behavior, i.e. the container will always run the command given in the ENTRYPOINT instruction, unless overridden at the command line with the --entrypoint option.
    • In the exec form, ENTRYPOINT can be used to define the default command and arguments. Optionally CMD can be added to supply optional arguments. CMD arguments can be overridden with command line arguments, e.g. an image built from the following Dockerfile:
    • FROM ubuntu
      ENTRYPOINT ["top", "-b"]
      CMD ["-n 2"]
      will run the command top -b -n 2. The CMD instruction can be overridden by specifying an argument at the command line, e.g. $ docker run top -n 4 will run top -b -n 4 instead.
    • In the exec form, command line arguments, e.g. $ docker run will append to, NOT override the ENTRYPOINT instruction.
      • With the following Dockerfile:
      • FROM debian
        MAINTAINER neokobo.blogspot.com
        ENTRYPOINT ["top","-n 1"]
      • Build an image, tagged with the name top and version 1:
      • With the defined ENTRYPOINT, you can run the container as $ docker run --rm -t top:1:
      • You can override the ENTRYPOINT instruction with the --entrypoint option:

      The above example runs ping bbc.co.uk -c 1 in the container, instead of top -n 1 specified in the Dockerfile. Note: command ping is specified with --entrypoint, and the rest is given as an argument in the command line.
    • If there are multiple ENTRYPOINT instructions in the Dockerfile, only the last one will have an effect.
    • In the EXEC form, the default executable is run directly by the kernel without a parent shell. As a result, it runs with a process ID (PID) of 1. And in Linux, if a process with PID 1 is terminated, the operating system is also terminated.
    • A SIGTERM signal (or issuing CTRL-C)  sent to the docker container will be passed to the default executable. As this is running as PID 1 in the Linux kernel, the application is terminated and the container is stopped
  • CMD (Command) Instruction
    • Specified as CMD in the Dockerfile, e.g. CMD ["/bin/bash"]
    • The command (is started as a subcommand of a shell, /bin/sh -c, as such it) does NOT run under PID 1 in the shell
    • In this form, the command is prepended with /bin/sh -c:
    • "Cmd": [
                      "/bin/sh",
                      "-c",
                      "#(nop) ",
                      "CMD [\"/bin/bash\"]"
                    ],
    • The CMD instruction allows the default executable to be overridden at the command line:

    • In the above example, the default executable of the debian image is bash -- we know that by looking at its Dockerfile. With the command above, bash, default executable is overridden at the command line with ls -Fs. The container runs this command and exits.
    • As it's easier to override the CMD instruction at the command line, the recommendation is to use CMD instead of ENTRYPOINT in your Dockerfile when you want flexibility in choosing a container command at runtime.
  • Exec vs Shell Form
    • Both CMD and ENTRYPOINT instructions support two forms: exec and shell.
    • Arguments in the shell form is space-delimited, executable param1 param2:, e.g. CMD ps -ef:
    • FROM debian
      MAINTAINER neokobo.blogspot.com
      CMD ps -ef
      Build the above Dockerfile, e.g. $ docker build -t pscmd . and run it:

      Note: the process running as PID 1 is the shell, /bin/sh, as opposed to the default executable, ps -ef, . There are two consequences of this:
      • the image now must include a shell layer, increasing its size
      • it is more difficult to kill the container by sending a POSIX signal. The signal gets intercepted by the shell as opposed to the default executable, ps.
    • Arguments in the exec form are formatted as a JSON array, ["executable","param1","param2"], e.g.
    • FROM debian
      MAINTAINER neokobo.blogspot.com
      CMD ["ps", "-ef"]
      Build the above Dockerfile, e.g. $ docker build -t psexec . and run it:

      Note: the process running as PID 1 is the default executable, ps -ef.
      Here's another example of the exec form, this time with the ENTRYPOINT instruction:
      FROM debian
      MAINTAINER neokobo.blogspot.com
      ENTRYPOINT ["/bin/ping","bbc.co.uk","-c 1"]
      Build the above Dockerfile, e.g. $ docker build -t pingexec . and run it:

      When run, the pingexec container pings bbc.co.uk once and exits.
Reference

Docker Container

Container

A container is a lightweight, portable encapsulation of an environment in which to run applications. It shares the kernel of the host system and is isolated from other containers in the system.
  • is a running instance of a Docker image
  • an image can be thought of an architectural drawing of a house; a container is a house built based on that drawing; several houses can be built from the drawing, optionally with differences, e.g. color, roof type, additions/replacements
  • Following the programming analogy, if an image is a class, a container is an instance of a class—a runtime object
  • To instantiate a container, Docker engine takes the image, adds a writable layer, and initializes settings such as network ports, container name, ID and resource limits
  • Because each container has its own thin writable container layer, and all changes are stored in this layer, multiple containers can share the same underlying image and yet have their own data state, minimizing the size of each container.
  • You can run, start, stop, move, or delete a container using Docker API or CLI commands. Here are examples of Docker commands dealing with containers:

Docker Image

Docker Image

  • Similar in concept to a class in object-oriented programming
  • Can be built or updated from scratch or existing images can be downloaded and used
  • Images can be thought of as golden images. They are read-only. They cannot be modified except by modifying the associated container, then "committing" the changes to a new image
  • Dockerfile is to Image as Source Code is to Executable:

  • Docker images are stored as a series of read-only layers:

  • When a container is started, Docker adds a read-write layer on top of the read-only layers/images:

March 14, 2017

Dockerfile

Dockerfile

A Docker Image is built from a simple, descriptive set of steps called instructions, which are stored in a text file called a Dockerfile. To create an image from a Dockerfile, the Docker daemon reads the file, executes the instructions, and outputs an image.

  • Dockerfile
    • Has been described as the source code of the image or an artifact that describes how a Docker image is created
    • Dockerfile is a text file with two types of entries:
      • # Comment
        • a line beginning with a hash symbol, used to insert comments into the file
      • INSTRUCTION
        • instructions are executed in order listed, each one creating a layer in the image
        • uppercase names used by convention
      • Example Dockerfile:
      • # Start with ubuntu 16.04
        FROM ubuntu:16.04

        MAINTAINER neokobo.blogspot.com

        # Instruction with three components
        RUN apt-get update && apt-get install emacs24 && apt-get clean

        CMD ["/bin/bash"]

    • Dockerfile Instructions include:
      • FROM - Specify the base image (required entry)
      • MAINTAINER - Specify the maintainer, i.e. the Author field of the generated image (deprecated)
      • LABEL - A key-value pair that adds metadata to an image; One or more LABEL entries and/or multiple key-value pairs per entry; Replaces MAINTAINER
      • RUN - Run a command
      • ADD - Add a file or directory
      • ENV - Create an environment variable
      • COPY - Copy files/directories from a source to a destination in the container file system
      • VOLUME - enable access to a directory
      • CMD - process to run when executing the container; defaults for an executing container
      • ENTRYPOINT - sets the primary command for the image
    • The name, Dockerfile is used by convention
    • Special note about the FROM instruction:
      • The FROM instruction in the Dockerfile specifies the "base image"
        • e.g. to build a Debian-based MySQL container, the Dockerfile will start with FROM debian.
      • The special instruction, FROM scratch can be used as a starting point for creating containers that don't require a "base image". E.g. an application such as the "hello" executable, compiled with the -static flag, does not need any specific binaries and libraries, as such it can run without a "base image" and on top of the host OS kernel
        • The scratch image is essentially an empty base image
        • What type of application can be run on top of an empty base image? An application with all the dependencies baked-in. I.e. an application where all the dependencies were statically linked during compilation.
        • Note: The Linux ldd command will show which libraries are dynamically linked in an application

Docker Installation Platform

  • Docker Installation Platform
    • Linux
      • Later versions of 64-bit Ubuntu, RHEL 7, CentOS 7, Fedora 24, 25, Debian, Oracle Linux 7 with UEK 4, SLES 12, and others
    • Mac
      • Docker for Mac
      • 2010 or newer model
      • OS X El Capitan 10.11 and newer
    • Windows
      • Docker for Windows
      • 64bit Windows 10 Pro, Enterprise / Education with Microsoft Hyper-V
    • AWS
    • Azure
    • Docker Toolbox
      • Support for older Windows and macOS versions

References:

Docker Components

Docker Components

Docker is a Container management tool. It consists of core technologies such as images and union filesystems, administration and management software such as the Docker engine and Swarm, concepts such as layers, and tags, supporting plug-ins for volumes and networks, and more. In the next several posts, I will describe some of these main components, including:
  • Docker Installation Platform
  • File Systems and Layer Objects: Dockerfile, Image, Container, etc.
  • Docker Host
  • Docker Storage
  • Docker Networking
  • Docker Swarm
  • Docker Compose

March 12, 2017

Docker Layered Environment

A Layered Environment


A docker image is built up of layers. Each layer represents a portion of the images' filesystem that either adds to or replaces (overlays) the layer below it. For instance you might start with a Debian base image, add the Emacs editor, and the nginx reverse proxy server. Each of these is a distinct layer.

Finally, to instantiate a container, the image is loaded into memory and a writable layer is added. This is where changes during runtime are kept.


The topology consists of the following components:
  • Kernel
    • this is the kernel of the host operating system
    • shared across all containers on host
  • Bootfs
    • boot filesystem (with bootloader and kernel)
    • same across different Linux distributions
  • Base image
    • binaries/libraries
    • functionality needed by the container, not in the host OS kernel
  • Rootfs
    • root filesystem (with required directories: /bin, /boot, /dev, /lib, …)
    • differences across Linux distributions
  • Image(s)
    • application run on top of the base image
    • zero or more read-only layers
  • Container
    • writeable layer
    • changed container data exists here
A container object is started by loading the image object layers into memory and adding a writable top layer.


A container provides a way to create a run-time environment on top of the underlying host kernel.

Note: The run-time environment includes a set of binaries and libraries needed by the specific application (default executable) running in the container and a writeable layer where changes are stored.

References:

Container and the Host OS Kernel

Container and the Host OS Kernel


Docker uses the host operating systems' kernel as a base. All containers which run on the host share this kernel. Any required resources not in the host kernel (e.g. binaries, libraries, frameworks, etc.) will be provided by the container's base image and any additional application layers.


If Docker is deployed on top of an Ubuntu Linux OS, containers built on this host will use the Ubuntu kernel.

Examples of other OS kernels deployments include:

    • Boot2docker
      • is a lightweight Linux distribution based on a stripped down Tiny Core Linux
      • developed to run Docker containers
      • Based on a recent Linux kernel (4.4.41 as of Docker 1.12.6) with AUFS storage driver
    • Container Linux
      • formerly CoreOS
      • an open-source lightweight operating system based on the Linux kernel
      •  provides minimal functionality required for deploying applications inside software containers
    • RancherOS
      • an OS made of Containers
      • two types of containers:
        • system containers (running system services)
        • user-level containers (running application services)
    • Windows Kernel

Docker Machine has default base operating systems for both local and remote providers. For local providers such as VirtualBox, Fusion, Hyper-V, etc., the default base operating system is Boot2Docker. For cloud providers, the base operating system is the latest Ubuntu LTS the provider supports.

Operating System Version Notes
Boot2Docker 1.5+ default for local
Ubuntu 12.04+ default for remote
RancherOS 0.3+
Debian 8.0+ experimental
RedHat Enterprise Linux 7.0+ experimental
CentOS 7+ experimental
Fedora 21+ experimental

The default base operating systems: Boot2docker, Ubuntu, CoreOS, etc. are bare bones Linux OS; just enough functionality to create a runtime environment (e.g. non-essential files, such as man pages are not included).

References: