How Cloud, Docker, and Kubernetes Differ

#Cloud#Docker#Kubernetes#Infrastructure

How Cloud, Docker, and Kubernetes Differ

Cloud, Docker, and Kubernetes often show up together when you study deployment, servers, or containers. That's why, at first, the three technologies can feel like they play similar roles.

But once you sort them out, the three are connected to each other yet clearly solve different problems.

  • Cloud is a way of renting infrastructure
  • Docker is a tool that bundles an application's runtime environment into an image and runs it as a container
  • Kubernetes is the platform environment that operates those containers across multiple servers

In other words, the three technologies aren't concepts at the same layer — they each handle a different problem.

In this post, rather than mixing the three together, I've organized them around the question of what problem each one solves.

What is the cloud?

The cloud is often understood as "a server somewhere on the internet." That isn't entirely wrong, but the key isn't where the server is. It's renting the resources you need, paying based on usage, and receiving operations in the form of a service.

In the past, running a service meant preparing servers yourself, configuring networks, and managing storage and incident response on top of it all. In a cloud environment, on the other hand, you can spin up these resources when you need them and scale them down when you don't. That reduces the upfront setup burden and lets you scale flexibly depending on the situation.

The cloud is usually divided into:

  • IaaS: Provides infrastructure like servers, networks, and storage.
  • PaaS: Provides the application runtime environment as a managed service as well.
  • SaaS: Users only consume the software itself.

In short, the cloud answers the question of where to run your application.

What does Docker solve?

Docker is a tool that bundles your application together with its runtime environment so you can run it the same way anywhere.

When developing, you often run into cases where things work on your machine but not on the server. That can happen because library versions differ, the runtime environment differs, or the OS itself differs, leading to different results.

To reduce this kind of problem, Docker packages the things needed to run as an image and executes it as a container. This narrows the gap between the development and operations environments, and lets you run the same application in a more consistent way.

In short, Docker is a tool for standardizing application runtime environments.

How do layers, images, and containers differ?

Layers, images, and containers are the concepts that come up most often when learning Docker.

  • Layer: A snapshot of filesystem changes.
  • Image: An executable package built by stacking layers.
  • Container: A process that actually runs an image.

For example, when you run commands like COPY, RUN, or ADD in a Dockerfile, each result stacks up as a layer. Thanks to this structure, unchanged steps can reuse the cache, which speeds up builds.

An image is an executable bundle built on top of these stacked layers, and a container is that image actually running.

Why are containers called disposable?

Containers can create or modify files while running, but those changes are stored by default in the container's writable layer. So if you delete the container, the changes inside can disappear with it.

The image, on the other hand, doesn't change. So the usual pattern is to leave the image alone and, when needed, delete and recreate the container.

Important data isn't kept only inside the container — it's typically stored in volumes, external storage, databases, and so on.

In short, a container is closer to an easily replaceable execution unit than something meant for long-term storage.

Why do we need a Dockerfile?

A Dockerfile is the blueprint for building an image. It records which base image to use, which files to copy, which commands to run, and what to execute when the container starts.

For example:

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
CMD ["node", "dist/server.js"]

Each instruction here means:

  • FROM: Specifies the base image to start from.
  • COPY: Copies files into the image.
  • RUN: Runs a command during build.
  • CMD: Specifies the default command to run when the container starts.

In short, a Dockerfile is a file that records the runtime environment as code.

What does Kubernetes solve?

With Docker you can build images and run containers, but in real operations that's often not enough by itself.

For example, problems like these can come up:

  • How do you bring a container back up if it dies?
  • How do you scale up the number of instances when traffic grows?
  • How do you distribute deployments across multiple servers?
  • How do you deploy a new version with zero downtime?

Kubernetes is the platform for solving these problems. So if Docker is closer to a tool for building containers, Kubernetes is closer to a platform for operating those containers across multiple servers.

How are Docker and Kubernetes connected?

Their relationship, put simply, looks like this:

  1. Build an application image with Docker.
  2. Get that image ready to run as a container.
  3. Kubernetes manages those containers across multiple servers.

In other words, Docker creates the unit of execution, and Kubernetes manages that unit as an operational unit.

What should I use locally?

Rather than practicing in a cloud environment from the start, it's easier to grasp the structure by checking it locally. The tools commonly used here are kind and kubectl.

  • kind: A tool that creates a Kubernetes cluster locally by using Docker containers as nodes.
  • kubectl: The CLI tool for inspecting and operating Kubernetes clusters.

With this combination, you can practice the basic flow — creating a cluster, deploying resources, hooking up services — right on your local machine.

Wrapping up

At first, cloud, Docker, and Kubernetes can all look like similar technologies. But once you sort them out, the roles they each play are clearly different.

  • The cloud is an environment for renting infrastructure
  • Docker is a tool for bundling application runtime environments
  • Kubernetes is a platform for operating those containers

In other words, a cluster isn't just an environment for running a few containers — it's a structure where multiple nodes and management components work together.

Control Plane and Worker Node

Control Plane

The Control Plane manages the cluster as a whole. Its main components include:

  • API Server: The gateway every request to the cluster passes through.
  • Scheduler: Decides which Pod gets placed on which node.
  • Controller: Keeps the current state aligned with the desired state.

For example, if the desired state is "keep 3 Pods running," when one Pod disappears the Controller brings the count back up.

Worker Node

The Worker Node is where Pods actually run. You can think of it as the runtime environment where applications actually live.

Why do we need Namespaces?

A Namespace is a logical space for separating resources within the same cluster.

It can be used in ways like:

  • Separating development / staging / production environments
  • Separating resources by team
  • Managing resources with the same name in different spaces

In short, a Namespace is a unit for separating and organizing resources within a single cluster.

What is a Pod?

A Pod is the smallest unit of execution in Kubernetes. It can consist of one or more containers, and containers within the same Pod can share network and volumes.

The important point is that a Pod isn't a permanent instance. It can be recreated at any time due to node failures, rescheduling, or updates.

So a Pod isn't something you hold onto and manage long-term — it's an execution unit that can be replaced as needed.

Why do we need Deployments?

Because Pods can be recreated, you generally don't operate Pods directly. Instead, you manage Pods through a Deployment.

A Deployment handles things like:

  • Maintaining the desired number of Pods
  • Rolling updates
  • Rollbacks
  • Recovery when failures occur

Internally, it operates with this structure:

Deployment → ReplicaSet → Pod

So the Deployment declares the desired state, and the ReplicaSet adjusts the actual number of Pods to match.

Why do we need a Service?

When a Pod is recreated, its IP can change. Because of that, accessing Pods directly isn't reliable.

A Service solves this by providing a fixed access point. A Service uses label selectors to find and connect to specific Pods, and clients connect through the Service rather than directly to Pods.

So even if Pods get replaced, the Service continues to accept requests under the same name and virtual IP.

What should I use locally?

Rather than practicing in a cloud environment from the start, it's easier to grasp the structure by checking it locally. The tools commonly used here are kind and kubectl.

  • kind: A tool that creates a Kubernetes cluster locally by using Docker containers as nodes.
  • kubectl: The CLI tool for inspecting and operating Kubernetes clusters.

With this combination, you can practice the basic flow — creating a cluster, deploying resources, hooking up services — right on your local machine.

Wrapping up

Cloud, Docker, and Kubernetes often appear together, but each handles a different problem.

  • The cloud is an environment for renting infrastructure.
  • Docker is a tool for bundling application runtime environments.
  • Kubernetes is a platform for operating those containers.

And within Kubernetes itself, the following structure matters:

  • Cluster
  • Control Plane / Worker Node
  • Namespace
  • Pod
  • Deployment
  • Service

Once you understand this flow first, it becomes much easier to look at resources like Storage, Gateway API, or HPA later on.