kubernetes for engineers who know literally nothing

작성자

카테고리:

← 피드로
DEV Community · Frank Snelling · 2026-09-28 개발(SW)

Disclaimer: this is not a post from a seasoned DevOps engineer. So if you also know very little about Kubernetes, ignorance loves company.

To start with some (somewhat) fun facts:

  • Kubernetes was created by Google (in 2014)
  • Kubernetes is also known as K8s (K********s = K + 8 letters + s)

Why would you even need Kubernetes?

Well, let’s start simple. Imagine you’ve created a report generation app. It has 2 services — a backend and a frontend. People upload some information and you return a .txt report.

Simple report generation architecture diagram

But obviously returning a .txt file is ugly. Users want graphs, nice fonts, interactive links. You need to create PDFs. But creating PDFs can be heavy work and your backend needs to remain fast and responsive. Introducing PDF generation inside the backend will seriously slow stuff down.

So you decide to add a third service for PDF generation. This allows your main backend service to remain fast and responsive, while the heavy work is done separately.

More complex report generation article

A lot more moving parts right? And each part has different deployment requirements too. The PDF generation service may need more memory than the backend to generate the PDFs. Plus, when there is a surge of PDF requests you may need to add extra capacity. And this illustrative architecture isn’t even complete. You probably want a queue, a database, observability, and a bunch of networking rules between all your services.

As the application grows, it’s going to get harder and harder to manage everything. Because this is just one feature in one simple app. Imagine a company with hundreds of teams and hundreds of services.

Before getting into Kubernetes, let’s start with a key concept. The container.

A container is an isolated process with its own packaged environment. In other words, a running instance of the code you’ve written and the packages you’ve installed. Containers are the solution to “well it works for me!” because building a container image (the blueprint for a container) involves declaring dependencies and versions. This makes it easy to run the service consistently across different environments.

With our report generation app, we would package the backend, the frontend, and the PDF generation service into separate containers. This means each service can run independently with as many instances as we need. For example, running several PDF generation containers during peak times.

Once you’ve got containers, this is where Kubernetes comes in.

Kubernetes allows you to manage the containers that make up your application.

You define the desired state of your system and Kubernetes works to make this a reality.

So what does your “desired state” actually look like?

Well for us, our desired state might be 3 PDF generation containers running at any time. Or it could be more complex too, like having more instances when traffic is heavy and less instances when traffic is light, to optimise cost and latency. We can define these rules with Kubernetes.

With this basic mental model, we can start unpacking the key parts of Kubernetes.

At the top level is the cluster. A cluster is a group of machines — known as Nodes — managed by Kubernetes.

The cluster acts as an operational boundary — for example, you might have a production and a staging cluster. Within the cluster, there are two key things:

  1. The control plane
  2. The worker nodes

The control plane is the brains of your system, managing the cluster. It stores your instructions and works to enforce them. The worker nodes actually run your containers.

The control plane has a few key components:

  • The API server is how you communicate with the control plane.
  • etcd is a key/value database that Kubernetes uses to store cluster configuration and state.
  • The scheduler decides which Node to run stuff on.
  • The controller manager… manages your controllers (more on this).

The worker nodes are easy to understand as a hierarchy.

cluster
└── worker node
    └── pod
        └── container

Enter fullscreen mode Exit fullscreen mode

We are already familiar with the cluster. Worker nodes are just Nodes that run your application code.

A Pod seems a little harder to define and is often described as:

“The smallest deployable units of computing that you can create and manage in Kubernetes” K8s docs.

A Pod contains containers. Usually a Pod contains just a single application container. So our PDF generation container, frontend container, and backend container would all have separate Pods. A Pod usually only has multiple containers if you need a supporting container (e.g., a container for collecting logs).

Instead of managing raw containers, Kubernetes manages Pods. This means multiple containers can “live together”, sharing storage, networking, and a lifecycle. But a Pod is ephemeral. When it dies, Kubernetes can recreate it (not repair it) and it gets a new identity. You must treat Pods as being disposable.

TL;DR — a cluster is a group of Nodes, Kubernetes schedules Pods onto those Nodes, and a Pod contains one or more containers.

Kubernetes manages Nodes and Pods to enforce our desired state. But how do we define what is “desired”?

Resources. (Almost) everything in Kubernetes is a resource. You can define the resources you desire in a .yaml manifest. A simplified manifest might look like this:

apiVersion: apps/v1
kind: Deployment

metadata:
  name: pdf-generator

spec:
  replicas: 3

  selector:
    matchLabels:
      app: pdf-generator

  template:
    metadata:
      labels:
        app: pdf-generator

    spec:
      containers:
        - name: pdf-generator
          image: my-company/pdf-generator:v1
          resources:
            requests:
              cpu: "500m"
              memory: "1Gi"

Enter fullscreen mode Exit fullscreen mode

The manifest has a few key fields:

  • apiVersion tells Kubernetes which version of the API this resource belongs to.
  • kind is the type of resource.
  • metadata is information about the resource.
  • spec is where the desired state lives. Its content and meaning depends on the resource kind.

In our example above, we have defined kind: Deployment. This means the resource is a Deployment. There are many resource kinds defined by Kubernetes (and you can even create custom resources).

A Deployment is a resource for running stateless applications with a certain number of replicas. A replica is an interchangeable copy of a Pod. We want multiple replicas of our PDF generation service so we can handle many requests and keep the service available if a replica goes down.

 So Kubernetes knows what we desire, how does it enforce it?

Controllers. Controllers do the following loop called reconciliation:

observe -> compare -> act -> repeat

Enter fullscreen mode Exit fullscreen mode

In our manifest above, we requested 3 replicas. The Deployment controller creates and updates a ReplicaSet resource. A ReplicaSet controller ensures the requested replicas exist. If one Pod goes down:

  1. the ReplicaSet controller observes that only 2 Pods are running.
  2. the ReplicaSet controller compares this with the desired number of 3.
  3. the ReplicaSet controller acts by creating a replacement Pod.

So you know a bit about Kubernetes now. But do you need it?

Maybe. But maybe not.

Kubernetes is undoubtedly powerful, but this comes with significant complexity. Kubernetes is widely used and growing (82% of container users run Kubernetes in production according to CNCF) but it’s worth noting the other options. Cloud providers offer managed container platforms like Cloud Run and ECS/Fargate. You hand over your containers and the cloud provider manages the infrastructure.

You might think: “I’m not paying a premium for something like Cloud Run”. But I wouldn’t dismiss it too fast. While Kubernetes exposes all the primitives you need to optimise for cost, it is significant setup and ongoing work. And time is money. Not to mention that a poorly configured Kubernetes cluster can definitely cost more money than it needs to.

As always, it’s all about tradeoffs.

Appendix

More Resource Kinds

  • A Pod runs 1+ containers.
  • A Deployment keeps a replicated app running.
  • A ReplicaSet maintains a desired number of Pods.
  • A Service provides a stable network endpoint for a set of Pods (because Pods get a new IP address when replaced).
  • A Job runs a task until it completes successfully.
  • A CronJob creates Jobs on a schedule.
  • A ConfigMap stores non-sensitive information.
  • A Secret stores sensitive information.
  • A PersistentVolume (PV) represents disk storage independent of a Pod. It survives even when a Pod dies.
  • A PersistentVolumeClaim (PVC) is how you order a PV.
  • A Namespace creates a logical boundary in a cluster. This means you can have a backend Deployment in multiple Namespaces (for example, production and staging).

원문에서 계속 ↗