Docker internal working: One of the goals of modern software development is to keep applications on the same host or cluster isolated from one another so they don’t unduly interfere with each other’s operation or maintenance. One solution to this problem has been virtual machines, which keep applications on the same hardware entirely separate, but they are bulky and require its own OS, so it is typically gigabytes in size—and difficult to maintain and upgrade.
Containers run in user space on top of the operating system’s kernel. It can be called as OS-level virtualization. Each container will have its isolated user space and you can run multiple containers on a host, each having its own userspace. It means you can run different Linux systems (containers) on a single host.
Containers allow a developer to package up an application with all of the parts it needs, such as libraries and other dependencies, and ship it all out as one package. Containers are isolated in a host using the two Linux kernel features called namespaces and control groups.
Docker uses a technology called namespaces
to provide the isolated workspace called the container. When you run a container, Docker creates a set of namespaces for that container. These namespaces provide a layer of isolation. Each aspect of a container runs in a separate namespace and its access is limited to that namespace.
- Docker Engine uses namespaces such as the following on Linux:
- The
pid
namespace: Process isolation (PID: Process ID). - The
net
namespace: Managing network interfaces (NET: Networking). - The
ipc
namespace: Managing access to IPC resources (IPC: InterProcess Communication). - The
mnt
namespace: Managing filesystem mount points (MNT: Mount). - The
uts
namespace: Isolating kernel and version identifiers. (UTS: Unix Timesharing System).
- Docker Engine on Linux relies on a technology called control groups (
cgroups
). A cgroup limits an application to a specific set of resources. Control groups allow Docker Engine to share available hardware resources to containers and optionally enforce limits and constraints. For example, you can limit the memory available to a specific container. - Docker uses Copy-on-write union file system for its backend storage. Whenever changes are made to a container, only the changes will be written to disk using copy on write model. Docker originally used LinuX Containers (LXC), but later switched to runC (formerly known as libcontainer), which runs in the same operating system as its host.
- Docker Engine uses UnionFS to provide the building blocks for containers. Union file systems, or UnionFS, are file systems that operate by creating layers, making them very lightweight and fast.
Docker Engine combines the namespaces, control groups, and UnionFS into a wrapper called a container format. The default container format is libcontainer
A full virtualized system gets its own set of resources allocated to it and does minimal sharing. You get more isolation, but it is much heavier (requires more resources). With Docker, you get less isolation, but the containers are lightweight (require fewer resources). Docker containers keep apps isolated not only from each other but from the underlying system. This not only makes for a cleaner software stack, but makes it easier to dictate how a given containerized application uses system resources—CPU, GPU, memory, I/O, networking, and so on. It also makes it easier to ensure that data and code are kept separate.