Kubernetes vs Docker: Different Jobs, One Team

Kubernetes vs Docker: Different Jobs, One Team

A beginner-friendly guide to what each tool really does, how each one works on the inside, where they overlap, and how to choose between them. Every new word is explained the moment it appears.

Imagine you cook a wonderful lunch at home and pack it into a lunchbox. Anyone can open that box at any desk in any city and eat exactly the same lunch. Now imagine you are asked to feed five thousand children every day at a huge school. You would need many kitchens, many cooks, a schedule, a plan for when a cook falls sick, and someone to make sure nobody goes hungry. The lunchbox and the school cafeteria are both about food, but they solve very different problems.

That is the easiest way to remember the difference between Docker and Kubernetes. Docker helps you pack an application into a neat, portable box. Kubernetes helps you run thousands of those boxes across many computers without losing sleep. People often ask “Kubernetes or Docker?” as if they must pick one, but in most real companies the answer is “both, each doing its own job”. This guide walks through the whole story from the ground up, so that by the end you can explain it to a friend and choose sensibly for your own project.

AWhy Everyone Confuses Kubernetes and Docker

The two names appear side by side in job posts, tutorials, and conference talks, so it is natural to think they are rivals. They are not, and this chapter shows why.

Let us start with three plain definitions. A container is a small, sealed package that holds an application together with everything it needs to run, such as its code, its libraries, and its settings. Docker is the most famous set of tools for building and running such containers on a single computer. Kubernetes is a system that takes many containers and decides which computer should run each one, keeps them healthy, and connects them to each other and to the outside world. The word for that management job is orchestration, just like a conductor guiding an orchestra of musicians who each play their own instrument.

Analogy

Docker is the lunchbox. It packs one meal so it stays fresh and can travel anywhere. Kubernetes is the school cafeteria manager. The manager does not cook your meal. The manager decides how many meals are needed, which kitchen prepares them, what happens when a cook is absent, and how every child receives the right plate on time.

2013
Docker was shown to the public
2014
Google announced Kubernetes
5,000
Machines officially supported in one Kubernetes cluster

Where the confusion comes from

There are three main reasons. First, the word “Docker” is used for many things. It is the name of a company, of a desktop application, of a background program called the Docker Engine, and loosely of the whole idea of containers. When someone says “we use Docker”, they might mean any of these.

Second, Docker once had its own built-in orchestrator called Docker Swarm. Swarm did a smaller version of what Kubernetes does, so for a few years the two really were competitors. Kubernetes won that race, and Swarm became a niche choice. The memory of that rivalry still lingers in many articles.

Third, in 2022 Kubernetes version 1.24 removed a small piece of code that let it talk to the Docker Engine directly. Headlines shouted that Kubernetes was “dropping Docker”, and many beginners panicked. In truth, almost nothing changed for everyday users, and we will explain exactly why in a later chapter.

i
Remember this

Docker answers the question “how do I package and run one application?” Kubernetes answers the question “how do I run many applications reliably across many machines?” Different questions, different tools.

BContainers 101: The Building Block Both Tools Share

Before comparing the two tools, we must understand the one thing they both depend on: the container.

The “it works on my machine” problem

Every programmer has heard the sentence “but it works on my machine”. An application that runs perfectly on one laptop may crash on a server because the server has a different version of a library, a different setting, or a different operating system. Teams used to lose days chasing such differences. A container fixes this by carrying the application and its surroundings together, so the app sees the same world everywhere it goes.

Analogy

Before 1956, loading a ship meant handling sacks, barrels, and crates of every shape by hand. Then Malcolm McLean popularised the standard steel shipping container. Cranes, trucks, trains, and ships all learned to handle one shape of box, no matter what was inside. Software containers do the same for programs. The box is standard, so every machine knows how to carry it, and nobody cares what is inside.

Containers versus virtual machines

You may have heard of virtual machines, or VMs. A virtual machine pretends to be a whole computer, including its own full operating system. That is powerful, but heavy. A single VM often needs several gigabytes of disk space and may take minutes to start. A container is lighter because it borrows the operating system core, called the kernel, from the machine it runs on. It only carries the application and its libraries. A very small base image such as Alpine Linux is only about 5 megabytes, and a container usually starts in a second or less.

flowchart TB
    subgraph VMSIDE["Virtual Machines"]
        direction TB
        VH["Physical Server"] --> VHY["Hypervisor"]
        VHY --> VA["Guest OS 1 + App 1"]
        VHY --> VB["Guest OS 2 + App 2"]
    end
    subgraph CSIDE["Containers"]
        direction TB
        CH["Physical Server"] --> COS["Host Operating System Kernel"]
        COS --> CR["Container Runtime"]
        CR --> CA["App 1 + Libraries"]
        CR --> CB["App 2 + Libraries"]
    end
Figure 1. A virtual machine carries a whole guest operating system. A container shares the host kernel and carries only what the app needs.

Because containers are light, one server can run dozens or even hundreds of them. That is why companies such as Netflix, Uber, and Spotify use them heavily: the same hardware serves more work at a lower cost.

Four words you will see everywhere

Word 1

Image

A read-only template that holds the app and everything it needs. Think of it as a frozen meal kit that is ready to be heated.

Word 2

Container

A running copy of an image. Start ten containers from one image and you get ten identical, separate running apps.

Word 3

Registry

An online library where images are stored and shared. Docker Hub and Amazon Elastic Container Registry are well-known examples.

Word 4

Host

The computer, real or virtual, that actually runs the containers. In Kubernetes, hosts are called nodes.

i
Good to know

The difference between an image and a container is the same as the difference between a recipe card and a cooked dish. One recipe card can produce many dishes, and eating a dish does not change the card.

CWhat Docker Actually Is

Docker did not invent containers, but it made them easy enough for everyone to use. That ease is the reason it changed the industry.

A short history

Container ideas existed long before Docker. Unix systems had a feature called chroot in 1979, and Linux gained the building blocks of modern containers in the 2000s. But using them was hard and needed deep expert knowledge. In 2013 an engineer named Solomon Hykes showed Docker to the world at a Python conference. It came from a small company called dotCloud. Docker wrapped the difficult pieces in a friendly command line and a simple file format, and within a few years almost every software team was talking about it.

The main parts of Docker

Program

Docker Engine

The core software installed on a machine. It contains a background program called the daemon that does the real work, plus a command-line tool that you type into.

File

Dockerfile

A plain text recipe that lists, step by step, how to build an image: start from this base, add these files, install these libraries, run this program.

Artifact

Docker Image

The result of following the recipe. It is built in layers and can be copied to any machine that has a container runtime.

Service

Registry

The place where finished images are uploaded and downloaded. Docker Hub is the public default. Companies often run private ones.

Tool

Docker Compose

A helper that starts several related containers together on one machine, such as a web app, a database, and a cache, using a single description file.

App

Docker Desktop

A friendly application for Windows and Mac laptops that bundles the engine, a graphical dashboard, and extras for developers.

The three basic moves: build, ship, run

1

Build

You write the recipe and Docker turns it into an image. Each step in the recipe becomes a layer, and unchanged layers are reused, so later builds are much faster.

2

Ship

You upload the image to a registry. Now any teammate, test server, or production machine can download the exact same package.

3

Run

Any machine with Docker downloads the image and starts a container from it. The app behaves the same as it did on the developer laptop.

Analogy

The Dockerfile is a restaurant recipe, the image is the sealed meal kit made from it, the registry is the warehouse that stores meal kits, and the container is the hot dish being served at a table. You can always throw the dish away and cook a fresh one from the same kit.

!
Watch out

Containers are disposable by design. When a container is removed, anything it saved inside itself is gone. Data that must survive, like a customer database, needs to live in a separate place called a volume, or in a managed database service outside the container.

DInside Docker: How a Container Really Runs

A container looks like magic, but it is built from a few clever features of the Linux operating system. Knowing them removes the mystery.

Here is the surprising truth: a container is not a tiny computer. It is just an ordinary program running on the host, wrapped in rules that limit what it can see and how much it can use. Two Linux features create those rules, and a third makes images efficient.

Namespaces: what the program can see

A namespace gives a program its own private view of part of the system. One namespace hides other programs so the container thinks it is the only thing running. Another gives it its own network address. Another gives it its own file system view and its own computer name. The program lives inside a small illusion of having a whole machine to itself.

Control groups: how much the program can use

A control group, usually shortened to cgroup, sets limits. It can say “this container may use at most half a processor and 512 megabytes of memory”. Without such limits, one greedy program could starve all its neighbours. Engineers at Google contributed the original cgroups feature to the Linux kernel in 2007, years before Docker existed. That is a hint about where Kubernetes ideas came from.

Layered file systems: how images stay small

A Docker image is made of stacked, read-only layers. When a container starts, Docker adds one thin writable layer on top. If ten containers use the same base layers, the computer stores those layers once and shares them. This saves disk space and makes downloads faster, because only missing layers need to travel over the network.

Analogy

Picture an old classroom overhead projector with stacked transparent sheets. Each sheet adds some drawing, and together they form one picture. The bottom sheets never change. A student can scribble on the top sheet without damaging the ones underneath, and wiping the top sheet restores the original picture instantly.

Networking and storage for a single container

A container is sealed, so it needs deliberate doorways to talk to the world. Docker gives every container a private network address on a virtual network inside the host. To let visitors reach a web application, you publish a port, which means telling Docker “send traffic arriving at this number on the host to that number inside the container”. Containers placed on the same virtual network can also find each other by name, which is how a web container reaches its database container.

Storage works in a similar deliberate way. A volume is a folder managed by Docker that lives outside the container’s own layers. When the container is deleted, the volume stays, and a new container can attach to it and carry on where the old one stopped. A bind mount is a simpler cousin that connects a folder from the host directly into the container, which developers love because they can edit code on their laptop and see changes instantly inside the running app.

Analogy

A container is like a hotel room with the door locked. The published port is the reception phone that guests outside can call, the private virtual network is the internal hotel telephone between rooms, and a volume is the hotel safe that keeps your valuables even after you check out and a new guest takes the room.

The chain of programs behind one command

When you type a Docker command, several programs cooperate. The command-line tool sends your request to the daemon. The daemon hands the job to a lower-level manager called containerd, which downloads images and tracks running containers. Containerd then calls runc, a tiny program that asks the kernel to create the namespaces and cgroups and start your application. Once the container is running, runc exits and the kernel keeps enforcing the rules.

flowchart LR
    U["Developer runs Docker command"] --> CLI["Docker CLI"]
    CLI --> D["Docker Daemon dockerd"]
    D --> R["Registry such as Docker Hub"]
    D --> C["containerd"]
    C --> RC["runc"]
    RC --> K["Linux Kernel"]
    K --> NS["Namespaces: private view"]
    K --> CG["Cgroups: resource limits"]
    NS --> APP["Running Container"]
    CG --> APP
Figure 2. From one command to a running container: the CLI, the daemon, containerd, runc, and finally the kernel.

Why images work everywhere: open standards

In 2015 the industry created the Open Container Initiative, or OCI, to write shared rules for how images and runtimes should behave. Because of OCI, an image built by Docker can be run by other tools such as containerd, CRI-O, or Podman. This portability is the hidden reason that the 2022 Kubernetes change did not break anyone’s images.

!
Two confusing twins

Linux namespaces and Kubernetes namespaces share a name but are different things. The Linux kind isolates what a process can see. The Kubernetes kind is just a way to group and separate objects inside a cluster, like folders. Keep them apart in your mind.

i
Mac and Windows note

Containers need a Linux kernel. On a Mac or a Windows laptop, Docker Desktop quietly runs a small hidden Linux virtual machine and starts your containers inside it. On a Linux server there is no such extra layer.

EWhat Kubernetes Actually Is

Docker gets one container running. Kubernetes exists for the moment you have hundreds or thousands of them and a single human cannot keep track any more.

Where the name and the idea came from

The word Kubernetes comes from a Greek word meaning helmsman, the person who steers a ship. People often write it as K8s, because there are eight letters between the K and the s. Google created it, building on lessons from an internal system called Borg, which had been starting and managing Google’s own programs across huge fleets of machines for many years. Google announced Kubernetes in June 2014, released version 1.0 in July 2015, and handed it to a neutral home called the Cloud Native Computing Foundation, so that no single company controls it.

The problems it solves

Imagine your shop grows from one container to five hundred, spread over forty machines. Suddenly you face questions that Docker alone does not answer.

Problem 1

Where should it run?

Which of the forty machines has enough free memory and processor power for this new container? Kubernetes picks one automatically.

Problem 2

What if it crashes?

If a container dies or a whole machine breaks, something must start a replacement. Kubernetes does this without waking anybody up.

Problem 3

What if traffic doubles?

During a sale, you need more copies of the app, and afterwards fewer. Kubernetes can add and remove copies based on load.

Problem 4

How do parts find each other?

Containers come and go, and their addresses change. Kubernetes gives groups of them a stable name and spreads the traffic fairly.

Problem 5

How do I update safely?

Replacing every copy at once causes downtime. Kubernetes swaps them gradually and can roll back if the new version misbehaves.

Problem 6

Where do settings and passwords go?

Hard-coding them into images is dangerous. Kubernetes stores settings and secrets separately and delivers them to the right containers.

The big idea: you describe the goal, not the steps

With Kubernetes you do not give orders such as “start container A on machine 7”. Instead you write a description of the world you want, for example “I want three copies of my web app running, using this image, each with this much memory”. This description is called the desired state. Kubernetes constantly compares desired state with the actual state and fixes any difference. This repeating check-and-fix routine is called a control loop or reconciliation loop.

Analogy

A home thermostat is a perfect example. You do not tell the heater when to switch on. You set the temperature you want, say 22 degrees, and the thermostat keeps checking the room and turning the heater on or off until reality matches your wish. Kubernetes is a thermostat for applications.

3 a year
New Kubernetes minor versions arrive about three times each year
110
Default limit of pods on a single node
150,000
Pods officially supported in one large cluster
i
Important boundary

Kubernetes does not build images and it is not a container runtime itself. It relies on other tools to build images and on a runtime such as containerd to start containers. Kubernetes is the manager, not the worker.

FKubernetes Architecture: Control Plane and Worker Nodes

A Kubernetes installation is called a cluster. Every cluster has a thinking part and a working part, and knowing who does what makes everything else easier.

A cluster is a group of computers that act as one big machine. The computers that run your applications are called worker nodes. The computers that make decisions and keep records form the control plane. In small setups these can be the same machines, but in production they are usually separated.

Analogy

Think of a restaurant chain. Head office decides the menu, keeps records, and sends instructions. Each branch kitchen has a local manager who follows the instructions, cooks the food, and reports back. The control plane is head office. The worker nodes are the branch kitchens, and the kubelet on each node is the local manager.

flowchart TB
    USER["Engineer using kubectl or CI pipeline"] --> API
    EXT["Users on the internet"] --> LB["Cloud Load Balancer"]
    LB --> ING["Ingress Controller"]
    subgraph CP["Control Plane"]
        API["API Server"]
        ETCD["etcd database"]
        SCH["Scheduler"]
        CM["Controller Manager"]
        API  ETCD
        SCH --> API
        CM --> API
    end
    subgraph N1["Worker Node 1"]
        KL1["kubelet"]
        KP1["kube-proxy"]
        RT1["Container Runtime"]
        P1["Pod A"]
        P2["Pod B"]
        KL1 --> RT1
        RT1 --> P1
        RT1 --> P2
    end
    subgraph N2["Worker Node 2"]
        KL2["kubelet"]
        KP2["kube-proxy"]
        RT2["Container Runtime"]
        P3["Pod C"]
        KL2 --> RT2
        RT2 --> P3
    end
    API --> KL1
    API --> KL2
    ING --> P1
    ING --> P3
Figure 3. A Kubernetes cluster: the control plane decides, the worker nodes run pods, and the load balancer and ingress bring users in.

The parts, one by one

Control plane

API Server

The front door. Every request, from engineers, tools, and internal parts, passes through it. It checks who you are and whether you are allowed to do the thing.

Control plane

etcd

The cluster’s memory. A small, reliable database that stores every object and setting. It uses a voting method called Raft so that its copies agree with each other.

Control plane

Scheduler

The matchmaker. It watches for new pods without a home and picks the best node using free resources, rules, and preferences.

Control plane

Controller Manager

A bundle of control loops. One keeps the right number of copies, another handles failed nodes, another manages endpoints, and so on.

Worker node

kubelet

The agent on every node. It receives assignments, tells the runtime to start containers, checks their health, and reports back to the API server.

Worker node

kube-proxy

Keeps network rules on the node up to date so that traffic sent to a service name reaches one of the healthy pods behind it.

Worker node

Container Runtime

The software that really pulls images and starts containers. Common choices are containerd and CRI-O.

Add-on

DNS and Network Plugin

CoreDNS turns service names into addresses. A network plugin gives every pod its own address so pods can talk without tricks.

How pods talk to each other

Kubernetes follows one simple networking promise: every pod gets its own address, and every pod can reach every other pod without clever tricks, no matter which node each one lives on. The network plugin makes this promise true. Because pods are replaced often and their addresses change, other programs should never remember a pod’s address. They talk to a Service instead, which has a fixed name and address, and kube-proxy quietly forwards each request to one of the healthy pods behind it.

Traffic from the internet follows a slightly longer road. A cloud load balancer receives the visitor first and spreads visitors across nodes. An ingress controller, which is a web server that understands Kubernetes rules, then looks at the web address and decides which service should receive the request. You can think of it as the reception desk of a large building, sending each guest to the right office.

Analogy

Think of a big company phone system. Employees change desks all the time, so nobody memorises personal numbers. Customers call the department number, and the switchboard routes the call to whoever is free and present. Services are the department numbers, and kube-proxy is the switchboard.

!
Protect the memory

If etcd is lost with no backup, the cluster forgets everything it was supposed to run. Production clusters run three or five etcd copies, always an odd number so that a clear majority can always vote, and they take regular backups. Managed services like Amazon EKS run this part for you.

GKubernetes Objects You Must Know

In Kubernetes, everything you want is described as an object. A handful of objects cover most of daily life.

The pod: the smallest unit

Kubernetes does not run bare containers. It wraps one or more containers in a pod. The containers in a pod always land on the same node, share one network address, and can share storage. Most pods hold just one container, but a second helper container can sit next to it when the two must work as a pair.

Analogy

A pod is like a small apartment shared by a few roommates. They have one street address, one front door, and a shared fridge. Visitors knock on the apartment, not on individual roommates. If the apartment is demolished, all roommates leave together.

Labels: stickers that hold everything together

A label is a small tag such as “app equals shop” that you stick on objects. Other objects then find their targets by asking for “everything with this sticker”. This loose connection is what lets a service find its pods even as pods are replaced.

The most important objects at a glance

ObjectIts jobEveryday comparison
PodRuns one or more tightly linked containersA shared apartment
ReplicaSetKeeps a fixed number of identical pods aliveA shift manager counting staff
DeploymentManages ReplicaSets and handles smooth updates and rollbacksA store manager who plans staff changes
ServiceGives a stable name and address to a changing set of podsA restaurant’s single phone number
IngressRoutes outside web traffic to the right serviceA building’s reception desk
ConfigMapHolds non-secret settingsA notice board of rules
SecretHolds sensitive values such as passwords and tokensA locked key cabinet
NamespaceSplits one cluster into separate areasFloors in an office block
Volume and PersistentVolumeClaimProvide storage that outlives a podA rented storage unit
StatefulSetRuns pods that need stable names and their own storageNumbered lockers assigned to named people
DaemonSetRuns one pod on every nodeA security guard at every entrance
Job and CronJobRun tasks once or on a scheduleA one-off errand or a weekly chore
HorizontalPodAutoscalerAdds or removes pods based on loadOpening extra checkout counters at rush hour

Deployment and Service: the everyday pair

Most stateless web applications use just two objects together. A Deployment says “keep three copies of this image running and update them gently”. A Service says “give all pods with this label one steady name and share incoming traffic between them”. Users and other apps talk to the service name and never worry about which pod answers.

i
Stateless first

Applications that keep no important data inside themselves, called stateless, are the easiest to run on Kubernetes. Databases and other stateful programs are possible, but they need extra care. Many teams prefer a managed database service outside the cluster for that reason.

HData Flow and Lifecycle: From Code to Running App

Let us follow one application from the developer’s keyboard to a live service, first with Docker alone and then with Kubernetes added.

Path one: Docker on a single server

1

Write and package

The developer writes the app and a Dockerfile, then builds an image on a laptop or a build server.

2

Test locally

The developer starts a container from the image and checks that it behaves properly.

3

Push to a registry

The image is uploaded with a version tag so everyone can fetch the same package.

4

Run on the server

Someone logs in to the server, downloads the image, and starts the container. If it crashes, a restart policy may bring it back, but nothing more clever happens.

Path two: Kubernetes across a cluster

The first three steps are the same. The difference begins when the image is ready to run. Instead of logging in to servers, the engineer sends a description of the desired state to the cluster. Here is what happens inside, step by step.

sequenceDiagram
    participant E as Engineer
    participant A as API Server
    participant D as etcd
    participant C as Controllers
    participant S as Scheduler
    participant K as kubelet on Node
    participant R as Container Runtime
    E->>A: Submit Deployment with 3 replicas
    A->>D: Save desired state
    A-->>E: Accepted
    C->>A: Notice Deployment, create ReplicaSet and 3 Pods
    S->>A: Find Pods with no node, assign each to a node
    K->>A: See Pods assigned to my node
    K->>R: Pull image and start containers
    R-->>K: Containers running
    K->>A: Report Pod status Running
    Note over K,A: Health probes keep checking every few seconds
Figure 4. Every step goes through the API server. The parts never talk to each other directly, they read and write shared records.

Notice a beautiful detail: the parts of Kubernetes do not give commands to each other. Each one simply watches the API server for work that belongs to it, does that work, and writes the result back. This makes the system loosely coupled, so one part can crash and restart without confusing the others.

The life of a pod

A pod moves through a few simple phases. It starts as Pending while the scheduler finds a node and the images download. It becomes Running when at least one container has started. If it finishes its work successfully, as a batch job does, it becomes Succeeded. If a container fails and cannot be restarted, it becomes Failed. If the node stops talking to the control plane, the state is Unknown. Pods are treated as disposable: when one dies, Kubernetes does not repair it, it creates a fresh replacement.

Health checks and rolling updates

Kubernetes uses small tests called probes. A liveness probe asks “is this container stuck?” and triggers a restart if it fails. A readiness probe asks “is this container ready to receive visitors?” and keeps traffic away until the answer is yes. When you release a new version, a rolling update starts a few new pods, waits for them to become ready, and only then removes old ones. Users see no interruption. If the new pods never become ready, the update pauses, and you can roll back to the previous version with one action.

You tell Kubernetes what you want, not how to do it, and it keeps working until the world matches your wish.

Scaling in action

Suppose an online shop normally needs four pods to serve its visitors, but on a festival sale day traffic jumps to ten times the usual amount. A HorizontalPodAutoscaler watches a number such as average processor use. When the number climbs above the target you set, it raises the desired count of pods, and the normal control loops create them. If the cluster runs out of room, a separate cluster autoscaler can ask the cloud provider for more nodes. When the sale ends and traffic falls, the same process runs in reverse, and you stop paying for unused machines.

With plain Docker, the same event would need a human to start extra containers, adjust a load balancer, and remember to shut everything down afterwards. That manual effort is exactly the pain that Kubernetes was created to remove. It is also why companies with sudden traffic spikes, such as ticketing, food delivery, and streaming services, value it so highly.

i
Why readiness matters

Without a readiness probe, Kubernetes assumes a pod is ready the instant its process starts. A slow-starting app would then receive visitors before it can answer, and users would see errors during every release.

IDocker vs Kubernetes Side by Side

Now that both tools are clear on their own, we can compare them fairly. The table below shows why they are teammates and not opponents.

QuestionDockerKubernetes
Main jobBuild images and run containersManage many containers across many machines
Typical scopeOne machineA cluster of machines
Smallest unitContainerPod
Builds images?YesNo, it only runs them
Self-healingBasic restart policies onlyReplaces failed pods and moves work off broken nodes
ScalingManual, or scripted by youAutomatic scaling based on load
Load balancingLimited, mostly by adding another toolBuilt in through Services and Ingress
Rolling updates and rollbackNot built in for single-host useBuilt in
Storage handlingVolumes on the hostRich storage system that works across nodes
Learning curveGentle, a weekend to get startedSteep, months to feel comfortable
Best fitDevelopment, testing, small appsLarge or growing production systems

Where Compose and Swarm fit

Single machine

Docker Compose

Describes a small application made of several containers and starts them together. Perfect for laptops, demos, and small servers.

Small cluster

Docker Swarm

Docker’s own orchestrator. It is simpler than Kubernetes but has far fewer features and a much smaller community today.

Any size

Kubernetes

The industry standard for orchestration, with a huge ecosystem of tools, cloud services, and trained engineers.

Swarm’s decline was helped by business events. Docker announced support for Kubernetes in 2017, and in 2019 the company sold its enterprise business to Mirantis. Swarm mode still works and some small teams like its simplicity, but most new projects choose Kubernetes.

The famous “Kubernetes dropped Docker” story

Kubernetes talks to container runtimes through a standard plug-in interface called the Container Runtime Interface, or CRI. The Docker Engine was created before this interface existed and does not speak it. To keep supporting Docker, Kubernetes carried a special adapter named dockershim. Maintaining that adapter was a burden, so version 1.24, released in 2022, removed it.

But remember the chain from Chapter D: the Docker Engine itself uses containerd underneath. Kubernetes simply started talking to containerd directly and skipped the middle layer. Images built with Docker follow the OCI standard, so they run unchanged. What really changed is that you can no longer type Docker commands on a Kubernetes node to inspect containers, and you use CRI tools instead.

i
In one sentence

Kubernetes stopped needing the Docker Engine to run containers, but it still happily runs every image you build with Docker tools.

JAdvantages, Disadvantages and Trade-offs

Every tool gives something and takes something. Being honest about the costs is what separates a good decision from a fashionable one.

Docker

Advantages

  • Easy to learn and quick to start using
  • Removes the “works on my machine” problem
  • Fast to build and start, thanks to layers and shared kernels
  • Huge library of ready-made images
  • Great for local development and automated testing

Disadvantages

  • Does not manage groups of machines by itself
  • Weaker isolation than virtual machines because the kernel is shared
  • Limited self-healing and scaling on a single host
  • Data inside containers is lost unless volumes are used
  • A single host is a single point of failure

Kubernetes

Advantages

  • Automatic recovery from crashes and machine failures
  • Scales up and down with demand
  • Safe rolling updates and quick rollbacks
  • Works on any major cloud or your own data centre
  • Very large ecosystem and community support

Disadvantages

  • Steep learning curve with many new terms
  • Operating the control plane yourself is hard work
  • Can be overkill and expensive for small applications
  • Complex networking and security settings that are easy to get wrong
  • Frequent releases mean regular upgrade chores
Analogy

Owning a bicycle is cheap, simple, and perfect for a trip across town. Running a bus company can carry thousands of people, but you need drivers, a depot, timetables, and mechanics. Nobody should start a bus company to ride to the corner shop, and nobody should run a big city on a single bicycle.

The trade-offs that matter most

Power against simplicity. Kubernetes gives you automation, but each feature is one more thing to learn, configure, and debug. Flexibility against lock-in. Kubernetes runs almost anywhere, which protects you from depending on one cloud, but a fully managed cloud service can be faster to operate. Efficiency against isolation. Sharing a kernel packs more work onto each machine, yet a serious flaw in the kernel or runtime could affect all containers on that machine. For highly sensitive work, teams add extra sandboxing or separate machines.

Notice also the hidden cost: people. A Kubernetes platform needs engineers who understand it. For a team of three people running one website, the time spent on cluster upkeep may be larger than the benefit.

Thinking about cost honestly

Cost has three parts. The first is infrastructure: the machines, storage, and network traffic. Containers help here because they pack more work onto each machine, and Kubernetes helps further by scheduling pods onto nodes that have room. The second is platform overhead: a Kubernetes cluster runs its own helper programs on every node, and managed services usually charge a small hourly fee for each control plane. The third and biggest is human time: learning, upgrades, incident handling, and security reviews.

A useful rule of thumb is to compare the cost of a mistake with the cost of prevention. If an hour of downtime would cost your business a lot of money or trust, then automatic recovery and safe releases are worth their price. If an hour of downtime on a quiet evening costs almost nothing, a simpler setup is the wiser purchase.

KSecurity in Docker and Kubernetes

Containers make delivery fast, but they also make it easy to ship a mistake to thousands of machines at once. Security must be planned in layers.

Analogy

Think of a large apartment building. The main gate checks visitors, each flat has its own lock, cameras watch the corridors, and the caretaker keeps a list of who may enter which floor. No single lock is trusted alone. Container security also relies on many small protections stacked together.

Docker-level protection

Images

Trust your base

Start from small, well-known official images, scan them for known flaws, and rebuild often. Fewer packages inside means fewer holes to attack.

Users

Do not run as root

By default a process inside a container may run as the all-powerful root user. Create a normal user in the image so a break-in has less power.

Daemon

Guard the Docker socket

The Docker daemon usually runs with high privileges. Anyone who can talk to its control socket can effectively control the whole host. Never expose it carelessly.

Runtime

Limit abilities

Drop unneeded Linux capabilities, use a read-only file system where possible, and apply built-in filters such as seccomp that block dangerous system calls.

Kubernetes-level protection

Access

RBAC

Role-Based Access Control decides who may do what. Give each person and each program only the permissions it truly needs, and nothing more.

Network

Network Policies

By default, any pod can talk to any other pod. Network policies act like internal walls so that, for example, only the web tier may contact the database.

Pods

Pod Security Standards

Three levels, called privileged, baseline, and restricted, describe how risky a pod’s settings may be. Production workloads should aim for restricted.

Secrets

Protect stored secrets

Kubernetes Secrets are only encoded, not encrypted, unless you turn on encryption at rest. Many teams keep the real secrets in a vault service such as AWS Secrets Manager.

Lessons from real incidents

In 2018, security researchers found that an administration console for a Kubernetes cluster at Tesla was reachable from the internet with no password. Attackers had used it to run hidden cryptocurrency mining inside the company’s cloud account. The lesson is simple and timeless: never leave management doors open to the public internet, and always require strong login. In 2019 a flaw in runc, the small program from Chapter D, allowed a malicious container to break out to the host on unpatched systems. The lesson: keep runtimes and nodes updated, because a shared kernel means bugs in the shared layer matter to everyone.

!
Never bake secrets into images

An image can be copied and inspected by anyone who can pull it. A password placed in the image lives in its layers forever, even if a later step deletes it. Provide secrets at run time from a secure store instead.

i
Public API endpoint

Keep the Kubernetes API server private wherever possible, or limit which network addresses may reach it. Turn on audit logs so you can see who did what and when.

LMonitoring, Logging and Metrics

Containers appear and vanish quickly, so you cannot log in and look around after a problem. You must record what happens as it happens.

Analogy

A car has a dashboard that shows speed and fuel right now, which are its metrics. An aircraft has a black box that records everything for later study, which are its logs. A tracking system that follows a parcel through every depot is like tracing. A healthy system needs all three.

The three pillars

Numbers

Metrics

Counts and measurements over time, such as processor use, memory use, requests per second, and error rate. They tell you that something is wrong.

Text

Logs

Time-stamped messages written by your programs. They tell you what happened and often why.

Journeys

Traces

A record of one request as it travels through many services. They tell you where the time was spent.

Monitoring with Docker

A healthy container writes its messages to standard output and standard error, and Docker collects them. You can read them with the logs command and see live processor and memory use with the stats command. Docker also supports health checks, which mark a container as healthy or unhealthy. For a single server this is often enough. For many servers you need a central place to gather everything.

Monitoring with Kubernetes

Kubernetes has no complete monitoring system built in, but it provides hooks for a rich ecosystem. A small add-on called metrics-server supplies basic processor and memory numbers and powers automatic scaling. kube-state-metrics reports the state of objects, such as how many pods are ready. Prometheus collects and stores metrics, Grafana draws dashboards, and Alertmanager sends messages to people when something crosses a limit. For logs, a small agent such as Fluent Bit runs on every node, reads container output, and forwards it to a search system like OpenSearch or Amazon CloudWatch. For traces, teams commonly use OpenTelemetry.

flowchart LR
    P["Pods write logs and expose metrics"] --> FB["Log agent on each node"]
    P --> PR["Prometheus collects metrics"]
    P --> OT["OpenTelemetry collector for traces"]
    FB --> LS["Central log store"]
    PR --> GF["Grafana dashboards"]
    PR --> AM["Alertmanager"]
    OT --> TS["Trace viewer"]
    AM --> ON["On-call engineer"]
    LS --> ENG["Engineers searching logs"]
    GF --> ENG
    TS --> ENG
Figure 5. A typical observability pipeline: pods produce data, collectors gather it, and people see dashboards, searches, and alerts.

What to watch first

Google’s engineers, in their well-known reliability book, suggest four golden signals that suit almost any service. They are latency, which is how long requests take; traffic, which is how many requests arrive; errors, which is how many requests fail; and saturation, which is how full your resources are. In Kubernetes also watch pod restarts, pods stuck in Pending, and nodes that are running out of memory or disk space.

i
Write to standard output

Because pods are disposable, do not write log files inside a container. Print messages to standard output and let the platform collect them. The logs then survive even after the pod is gone.

MDesign Patterns and Anti-Patterns

Engineers have discovered reliable shapes for container applications, and also some tempting shapes that cause trouble.

Patterns that work well

Basic rule

One job per container

Each container should run one main program. This makes updates, scaling, and debugging much simpler than a container that hides many programs.

Pod pattern

Sidecar

A helper container runs beside the main one to add a feature, such as shipping logs or handling secure connections. Service meshes like Istio use sidecar proxies based on Envoy, a tool first built at Lyft.

Pod pattern

Init container

A short task that must finish before the main container starts, for example waiting until a database is reachable or preparing files.

Pod pattern

Ambassador and adapter

An ambassador hides the messy details of talking to outside systems. An adapter converts output into a format that other tools expect.

Release pattern

Rolling, blue-green, canary

Rolling replaces pods gradually. Blue-green keeps two full environments and switches traffic at once. Canary sends a tiny share of users to the new version first.

Extension

Operator

A custom controller that teaches Kubernetes to manage a complex program, like a database, using the same desired-state idea.

Analogy

A canary release is named after the canary birds that miners once carried underground. If the bird was fine, the air was safe. Sending a small group of users to the new version first works the same way: if they stay healthy, everyone else can follow.

Anti-patterns to avoid

ANTI-PATTERN 01Avoid
What it is

The fat container: putting the web server, the database, and several helper programs into one container to keep things “simple”.

Why it hurts

You cannot scale one part without scaling all of them, one crash takes everything down, and every update rebuilds the entire bundle.

Better approach

Give each program its own container and connect them through a network or, in Kubernetes, through pods and services.

ANTI-PATTERN 02Avoid
What it is

Using the moving tag called latest for production images.

Why it hurts

The word latest points to whatever was uploaded most recently. Two servers may pull different versions at different times, and a rollback becomes guesswork.

Better approach

Use exact version tags, or even the image’s unique fingerprint called a digest, so that every machine runs precisely the same package.

ANTI-PATTERN 03Avoid
What it is

Premature orchestration: setting up a full Kubernetes cluster for one small application with a handful of users.

Why it hurts

You pay for the complexity of upgrades, security, and networking long before you receive the benefits of scale.

Better approach

Begin with Docker and Compose on a single server or a managed container service, and move to Kubernetes when real needs appear.

ANTI-PATTERN 04Avoid
What it is

Keeping important data inside a container’s own writable layer or on a single pod’s local disk.

Why it hurts

The moment the container is replaced, the data is gone. This is the most common cause of surprise data loss for beginners.

Better approach

Store data in volumes, persistent storage claims, or managed databases that live independently of any container.

NBest Practices and Common Mistakes

These habits come from years of painful lessons in real production systems. Adopt them early and you skip most of the pain.

Good habits for Docker images and containers

1

Keep images small

Choose a minimal base image and remove tools you do not need at run time. Smaller images download faster, start faster, and expose fewer weaknesses.

2

Build in stages

Use one stage to compile your program with heavy tools, then copy only the finished result into a clean final image. The heavy tools never reach production.

3

Order the recipe wisely

Put steps that rarely change, like installing libraries, near the top, and steps that change often, like copying your code, near the bottom. Docker then reuses cached layers and builds in seconds.

4

Pin versions

Name exact versions for base images and libraries so that a build today matches a build next month.

5

Run as a normal user and add a health check

Reduce power and make problems visible from the very first day.

Good habits for Kubernetes

Resources

Set requests and limits

A request tells the scheduler how much a pod needs. A limit stops it taking too much. Without them, one busy pod can starve its neighbours.

Health

Always add probes

Use readiness probes so traffic only reaches ready pods, and liveness probes so stuck pods restart.

Availability

Run several copies in several zones

Two or more replicas spread across different data-centre zones keep the service alive when one zone has trouble.

Safety

Use disruption budgets

A PodDisruptionBudget tells Kubernetes the minimum number of pods that must stay up during maintenance, so upgrades never remove everything at once.

Process

Keep desired state in version control

Store your descriptions in a Git repository and apply them through automation. This practice, called GitOps, gives you history, reviews, and easy rollbacks.

Cost

Right-size and autoscale

Review real usage regularly. Clusters often run at a small fraction of their capacity, and that idle space is money wasted.

Common mistakes and how to fix them

MistakeWhat happensFix
No memory limit setA leaky app eats the whole node and neighbours crashSet requests and limits based on measured use
Memory limit set far too lowThe pod is killed again and again with an out-of-memory statusMeasure real usage, then add sensible headroom
Only one replicaAny restart or node failure causes downtimeRun at least two or three replicas
No readiness probeUsers receive errors during every releaseAdd a probe that checks the app is truly ready
Secrets inside imagesAnyone with the image can read themInject them at run time from a secure store
Ignoring etcd backupsA control-plane failure loses all cluster recordsUse a managed service or schedule and test backups
Skipping upgradesOld versions lose security fixes and upgrades become a huge jumpUpgrade one version step at a regular rhythm
Too many tiny clustersEvery cluster needs care, so effort and cost multiplyUse namespaces and policies to share clusters safely

Failure scenarios and how each tool reacts

Good engineers plan for failure before it arrives. Consider three common events. If a single container crashes, Docker with a restart policy will start it again on the same machine, and Kubernetes will create a replacement pod, possibly on a different node. If a whole machine dies, Docker has no answer beyond a person noticing and acting, while Kubernetes notices that the node stopped reporting, waits a short grace period, and recreates its pods on healthy nodes. If a bad release is deployed, Docker offers no built-in memory of the previous version, while a Kubernetes Deployment keeps a history and can return to the last good version quickly.

These differences explain why teams practise failure on purpose. Netflix made this famous with its Chaos Monkey tool, which randomly shuts down servers during working hours to prove that the system survives. The same spirit works well on a Kubernetes cluster: delete a pod, drain a node, and watch that users notice nothing.

i
Learning order

Learn Docker first, then Kubernetes. Docker teaches you images, containers, networking, and volumes in a small, friendly setting. Kubernetes then feels like the same ideas at a larger scale, instead of a wall of unfamiliar words.

OReal-World Examples and How to Choose

Theory is useful, but seeing how real companies think makes the choice clearer.

How well-known organisations use these tools

Google: the origin story

Google ran its own services in containers for many years using Borg long before Docker became popular. Kubernetes carried those lessons to the public, and Google now offers it as a managed product called Google Kubernetes Engine.

Niantic and Pokémon GO: surviving a surprise

When Pokémon GO launched in 2016, it ran on Google’s cloud with Kubernetes. Player numbers rose far above the company’s own forecasts, and the ability to add capacity quickly helped the game keep running through the rush.

Spotify: moving from a home-made tool

Spotify first built its own orchestrator called Helios, then moved its services to Kubernetes so it could use the shared ecosystem instead of maintaining a custom system.

Airbnb: many teams, one platform

Airbnb has written publicly about moving its services onto Kubernetes so hundreds of engineers can deploy and scale independently on a shared, consistent platform.

Netflix: proof that there is more than one road

Netflix built its own container platform, called Titus, to match its very particular needs. Not every giant follows the crowd, but it also shows that big companies invest heavily in some form of orchestration.

Amazon: a menu of choices

On AWS you can use Amazon ECS, which is Amazon’s own simpler orchestrator, or Amazon EKS, which is managed Kubernetes. Both can run on AWS Fargate, a mode where Amazon manages the underlying servers so you only think about containers.

A small agency or startup: Docker on one server

A five-person team that runs a website, an API, and a database often does perfectly well with Docker Compose on one or two servers. Keeping it simple lets them spend time on customers rather than cluster upkeep.

A simple way to decide

flowchart TD
    S["Start: I have an application"] --> Q1{"Do I need it to run the same everywhere?"}
    Q1 -->|"Yes"| D["Package it with Docker"]
    Q1 -->|"No"| STOP["Plain servers may be enough for now"]
    D --> Q2{"More than a few services or servers?"}
    Q2 -->|"No"| C["Docker Compose on one server or a simple managed container service"]
    Q2 -->|"Yes"| Q3{"Need auto-scaling, self-healing, zero-downtime updates?"}
    Q3 -->|"Yes"| Q4{"Do I have a platform team?"}
    Q3 -->|"No"| C
    Q4 -->|"Yes"| K["Kubernetes, self-managed or managed"]
    Q4 -->|"No"| M["Managed Kubernetes such as EKS, GKE, AKS, or ECS with Fargate"]
Figure 6. A friendly decision path. Docker is almost always the first step, and Kubernetes is added when the need is real.
Your situationSensible starting point
Learning, building a prototype, or working aloneDocker and Docker Compose on your laptop
Small production app with steady trafficDocker on one or two servers, or a simple managed container service
Growing product with many services and spiky trafficManaged Kubernetes, for example Amazon EKS
Large company with many teams and strict rulesKubernetes with a platform team, policies, and GitOps
Need to run in several clouds or on your own hardwareKubernetes, because it looks the same nearly everywhere
i
Prefer managed services

If you choose Kubernetes, let a cloud provider run the control plane. Managed offerings such as Amazon EKS, Google GKE, and Azure AKS handle the hardest parts, like etcd and upgrades of the control plane, so your team can focus on applications.

PFrequently Asked Questions

Short, plain answers to the questions beginners ask most.

Q1Is Kubernetes replacing Docker?
No. They do different jobs. Docker tools build and run containers, while Kubernetes manages containers across many machines. Kubernetes stopped needing the Docker Engine to start containers, but it still runs Docker-built images every day.
Q2Can I use Kubernetes without Docker?
Yes. Kubernetes can use containerd or CRI-O as its runtime, and you can build images with tools other than Docker. Many clusters have no Docker Engine installed at all.
Q3Do I need to learn Docker before Kubernetes?
It is strongly recommended. Understanding images, containers, ports, and volumes first makes Kubernetes concepts much easier to grasp.
Q4Is Kubernetes a container runtime?
No. It is an orchestrator. It asks a runtime such as containerd to actually pull images and start containers.
Q5What is the difference between Docker Compose and Kubernetes?
Compose describes and starts several containers on one machine. Kubernetes runs and supervises containers across many machines and adds scaling, self-healing, and rolling updates.
Q6Is Docker Swarm dead?
Not officially, but it is far less popular. Most new projects and most job listings now focus on Kubernetes.
Q7What are Podman and containerd?
Both are other tools in the container world. Containerd is a runtime that Docker itself uses underneath. Podman is a Docker-like tool that can build and run containers without a central daemon.
Q8How is Amazon ECS different from Kubernetes?
ECS is Amazon’s own container orchestrator. It is simpler and tightly linked to AWS. Kubernetes is an open standard with a larger ecosystem that works across clouds. The right pick depends on how much portability and flexibility you need.
Q9When is Kubernetes too much?
If you run only a few containers, have steady traffic, and have no one to look after a cluster, simpler tools will serve you better and cost less.
Q10Are Docker and Kubernetes free?
Both core technologies are open source. Docker Desktop has paid plans for larger companies, and running Kubernetes costs money for the machines, storage, and network it uses, plus a small fee for managed control planes on most clouds.
Q11Can Kubernetes run databases?
Yes, using StatefulSets, persistent storage, and often operators. It needs careful planning, so many teams choose a managed database service outside the cluster instead.
Q12Are containers as secure as virtual machines?
Not by default. Containers share the host kernel, so their isolation is lighter. With careful settings, non-root users, updates, and policies they can be run safely, and extra sandboxing is available for sensitive work.

QSummary and Key Takeaways

Let us close the loop with the lunchbox and the cafeteria one more time.

Docker made packaging simple. It taught the world to put an application and its surroundings into one portable box and to move that box anywhere. Kubernetes then solved the next problem: when there are thousands of boxes and hundreds of machines, someone must place them, watch them, replace the broken ones, connect them, and update them without stopping the service. The two tools meet at the container image, which is the standard box they both understand. Choosing between them is rarely an either-or decision. It is a question of timing, and of how much complexity your project can honestly justify.

Key Takeaways

  • Different jobs: Docker builds and runs containers on a machine, while Kubernetes orchestrates containers across a whole cluster of machines.
  • Shared foundation: Both rest on Linux namespaces, cgroups, layered images, and the Open Container Initiative standards, which is why Docker-built images run on Kubernetes.
  • Desired state: Kubernetes works like a thermostat. You describe what you want, and its control loops keep fixing reality until it matches.
  • The 2022 change: Removing dockershim in Kubernetes 1.24 only removed the middle layer. Docker-built images still run everywhere.
  • Start simple: Begin with Docker and Compose, and adopt Kubernetes when you truly need auto-scaling, self-healing, and zero-downtime releases.
  • Security in layers: Use small trusted images, non-root users, RBAC, network policies, encrypted secrets, and regular updates.
  • Lean on managed services: If you choose Kubernetes, let a provider such as Amazon EKS run the control plane and spend your energy on your applications.