What is a Container?
Even though Docker is used as a synonym for containers, the reality is that they have existed long before Docker was a thing. Unix and Linux have had containers in some form or another since the late 70s, when chroot was introduced. Chroot allowed system admins to run programs in a kind-but-not-really-isolated filesystem. Later, the idea was refined and enhanced into container engines such as FreeBSD Jails, OpenVZ, or Linux Containers (LXC).
But what are containers?
A container is a logical partition where we can run applications isolated from the rest of the system. Each application gets its own private network and a virtual filesystem that is not shared with other containers or the host.

Running containerized applications is a lot more convenient than installing and configuring software. For one thing, containers are portable; we can build in one server with the confidence that it will work in any server. Another advantage is that we can run multiple copies of the same program simultaneously without conflict or overlap, something really hard to do otherwise.
However, for all this to work, we need a container runtime, a piece of software capable of running containers.
What is Docker?
Docker is the most popular container runtime — by a long shot. It shouldn’t be surprising, as it brought the concept of containers into the mainstream, which in turn inspired the creation of platforms like Kubernetes.
Before Docker, running containers was indeed possible, but it was hard work. Docker made things simple because it’s a complete tech stack that can:
- Manage container lifecycle.
- Proxy requests to and from the containers.
- Monitor and log container activity.
- Mount shared directories.
- Set resource limits on containers.
- Build images. The
Dockerfileis the de-facto format for building container images. - Push and pull images from registries.
In its first iterations, Docker used Linux Containers (LXC) as the runtime backend. As the project evolved, LXC was replaced by containerd, Docker’s own implementation. A modern Docker installation is divided into two services: containerd, responsible for managing containers, and dockerd, which does all the rest.

What is Kubernetes?
Kubernetes takes the idea of containers and turns it up a notch. Instead of running containerized applications in a single server, Kubernetes distributes them across a cluster of machines. Applications running in Kubernetes look and behave like a single unit, even though, in reality, they may consist of an arrangement of loosely-coupled containers.
Kubernetes adds distributed computing features on top of containers:
- Pods: pods are logical groups of containers that share resources like memory, CPU, storage, and network.
- Auto-scaling: Kubernetes can automatically adapt to changing workloads by starting and stopping pods as needed.
- Self-healing: containers are monitored and restarted on failure.
- Load-balancing: requests are distributed over the healthy available pods.
- Rollouts: Kubernetes supports automated rollouts and rollbacks. Making otherwise complex procedures like Canary and Blue-Green releases trivial.
We can think of Kubernetes’ architecture as a combination of two planes:
- The control plane is the coordinating brain of the cluster. It has a controller that manages nodes and services, a scheduler that assigns pods to the nodes, and the API service, which handles communication. Configuration and state are stored on a highly-available database called etcd.
- The worker nodes are the machines that run the containers. Each worker node runs a few components like the kubelet agent, a network proxy, and the container runtime. The default container runtime up to Kubernetes version v1.20 was Docker.

Docker Vs. Kubernetes
Here is where things get a bit more technical. I said that each Kubernetes worker node needs a container runtime. In its first original design, Docker was inseparable from Kubernetes because it was the only runtime supported.
Docker, however, was never designed to run inside Kubernetes. Realizing this problem, the Kubernetes developers eventually implemented an API called Container Runtime Interface (CRI). This interface allows us to choose among different container runtimes, making the platform more flexible and less dependent on Docker.



Comments
Loading comments…