Getting Started with Docker

Lance Watanabe
Don’t Leave Me Out in the Code
6 min readApr 13, 2022

--

  • Goal: Docker isolates an application and its dependencies into a self-contained unit that can run anywhere. Remove the need for physical hardware, allowing for more efficient use of computing resources, both in terms of energy consumption and cost effectiveness.
  • A virtual machine is an emulation of a real computer that executes programs like a real computer. VMs run on top of a physical machine using a “hypervisor”. A hypervisor, in turn, runs on either a host machine or on “bare-metal”. A hypervisor is a piece of software, firmware, or hardware that VMs run on top of. The hypervisors themselves run on physical computers, referred to as the “host machine”. The host machine provides the VMs with resources, including RAM and CPU.
  • The hypervisor plays an essential role in providing the VMs with a platform to manage and execute this guest operating system. It allows for host computers to share their resources amongst the virtual machines that are running as guests on top of them.
  • A hosted virtualization hypervisor runs on the operating system of the host machine. For example, a computer running OSX can have a VM installed on top of that OS. The benefit of a hosted hypervisor is that the underlying hardware is less important. The host’s operating system is responsible for the hardware drivers instead of the hypervisor itself, and is therefore considered to have more “hardware compatibility.” On the other hand, this additional layer in between the hardware and the hypervisor creates more resource overhead, which lowers the performance of the VM. The key is that each virtual machine has its own guest operating system atop the hypervisor.
  • A bare metal hypervisor environment tackles the performance issue by installing on and running from the host machine’s hardware. Because it interfaces directly with the underlying hardware, it doesn’t need a host operating system to run on.
  • The kernel is located in the operating system and controls the interactions between hardware and software.
  • For all intent and purposes, containers look like a VM. For example, they have private space for processing, can execute commands as root, have a private network interface and IP address, allow custom routes and iptable rules, can mount file systems, and etc. The one big difference between containers and VMs is that containers do not have a dedicated guest operating system.
  • Docker is an open-source project based on Linux containers. It uses Linux Kernel features like namespaces and control groups to create containers on top of an operating system. A Docker container wraps an application’s software into an invisible box with everything the application needs to run. That includes the operating system, application code, runtime, system tools, system libraries, and etc. Docker gives you the ability to snapshot the OS into a shared image, and makes it easy to deploy on other Docker hosts. You can’t run completely different OSes in containers like in VMs. However you can run different distros of Linux because they do share the same kernel. Lastly, Docker creates a network interface so that the container can talk to the local host, attaches an available IP address to the container
  1. Easy: It allows anyone to package an application on their laptop, which in turn can run unmodified on any public cloud, private cloud, or even bare metal. The mantra is: “build once, run anywhere.”
  2. Fast: Docker containers are very lightweight and fast. Since containers are just sandboxed environments running on the kernel, they take up fewer resources.
  3. Docker Templates: Docker users also benefit from the increasingly rich ecosystem of Docker Hub. Docker Hub has tens of thousands of public images created by the community that are readily available for use.
  4. Modularity and Scalability: Docker makes it easy to break out your application’s functionality into individual containers. For example, you might have your Postgres database running in one container and your Redis server in another while your Node.js app is in another. With Docker, it’s become easier to link these containers together to create your application, making it easy to scale or update components independently in the future.

Docker Components:

  • Docker Engine: Docker engine is the layer on which Docker runs. It’s a lightweight runtime and tooling that manages containers, images, builds, and more. It runs natively on Linux systems and is made up of:
  1. A Docker Daemon that runs in the host computer. The Docker daemon is what actually executes commands sent to the Docker Client — like building, running, and distributing your containers. The Docker Daemon runs on the host machine, but as a user, you never communicate directly with the Daemon.
  2. A Docker Client that then communicates with the Docker Daemon to execute commands.
  3. A REST API for interacting with the Docker Daemon remotely.
  • Docker Client: The Docker Client is what you, as the end-user of Docker, communicate with. Think of it as the UI for Docker. For example, when you are communicating to the Docker Client, which then communicates your instructions to the Docker Daemon.
  • A Dockerfile is where you write the instructions to build a Docker image. . Once you’ve got your Dockerfile set up, you can use the docker build command to build an image from it.
  1. RUN apt-get y install some-package: to install a software package
  2. EXPOSE 8000: to expose a port
  3. ENV ANT_HOME /usr/local/apache-ant to pass an environment variable
  • Docker Images are read-only templates that you build from a set of instructions written in your Dockerfile. Images define both what you want your packaged application and its dependencies to look like and what processes to run when it’s launched. The Docker image is built using a Dockerfile. Each instruction in the Dockerfile adds a new “layer” to the image, with layers representing a portion of the images file system that either adds to or replaces the layer below it. Layers are key to Docker’s lightweight yet powerful structure.
  • Docker uses Union File Systems to build up an image. You can think of a Union File System as a stackable file system, meaning files and directories of separate file systems (known as branches) can be transparently overlaid to form a single file system.
  • Volumes are the “data” part of a container, initialized when a container is created. Volumes allow you to persist and share a container’s data. Data volumes are separate from the default Union File System and exist as normal directories and files on the host filesystem. So, even if you destroy, update, or rebuild your container, the data volumes will remain untouched.
  • Namespaces provide containers with their own view of the underlying Linux system, limiting what the container can see and access. When you run a container, Docker creates namespaces that the specific container will use.
  1. NET: Provides a container with its own view of the network stack of the system (e.g. its own network devices, IP addresses, IP routing tables, /proc/net directory, port numbers, etc.).
  2. PID: PID stands for Process ID. The PID namespace gives containers their own scoped view of processes they can view and interact with
  3. MNT: Gives a container its own view of the “mounts” on the system.
  4. UTS: UTS stands for UNIX Timesharing System. It allows a process to identify system identifiers (i.e. hostname, domainname, etc.). UTS allows containers to have their own hostname
  5. IPC: IPC stands for InterProcess Communication. IPC namespace is responsible for isolating IPC resources between processes running inside each container.
  6. USER: This namespace is used to isolate users within each container.
  • Control groups (also called cgroups) is a Linux kernel feature that isolates, prioritizes, and accounts for the resource usage (CPU, memory, disk I/O, network, etc.) of a set of processes. In this sense, a cgroup ensures that Docker containers only use the resources they need — and, if needed, set up limits to what resources a container *can* use.

--

--