← All Posts
10 March 2026 by Michael
KubernetesBusinessDevOps

I explain Kubernetes to clients a lot. Usually because their dev team has proposed it and nobody else in the room knows what any of the words mean. So here is every concept you are likely to hear, explained in plain English.

Kubernetes itself

Kubernetes is a system that runs your software across multiple servers and manages it for you. It decides which server each piece of your application runs on, restarts things that crash, and scales up when traffic increases. Instead of someone logging into a server and starting things manually, you tell Kubernetes what you want running and it works out the details.

The whole thing is called a cluster. A cluster is just a group of servers working together, managed by Kubernetes.

Containers vs virtual machines

Before Kubernetes makes sense, you need to understand containers.

A virtual machine is a full computer running inside another computer. It has its own operating system, its own memory allocation, its own everything. If you want to run three applications, you spin up three VMs, each running a complete copy of Linux or Windows. It works, but each VM uses a lot of resources just running the operating system before your application even starts.

A container is lighter. It packages your application and its dependencies together, but it shares the host machine’s operating system. No separate OS per application. Starting a container takes seconds instead of minutes. You can run dozens of containers on a machine that would struggle with a handful of VMs.

The trade-off is isolation. VMs are completely separated from each other. Containers share a kernel, so the isolation is not as strong. For most applications that does not matter. For anything that needs hard security boundaries between workloads, it is worth knowing.

Docker is the tool most people use to build containers. Kubernetes then runs those containers using a runtime called containerd (which is actually part of Docker under the hood). You build with Docker, Kubernetes handles the running.

Pods

A pod is the smallest thing Kubernetes runs. It wraps one or more containers together as a single unit. Most of the time a pod is just one container, one copy of one part of your system.

If your application has a web frontend and an API backend, those are probably two separate pods. If you need three copies of the API running to handle traffic, that is three pods.

Pods are disposable. Kubernetes kills them and creates new ones regularly. That is by design. You should never think of a pod as something permanent.

Deployments

A deployment tells Kubernetes how many copies of a pod you want running and what version of the software to use. If you say “I want three copies of my API running version 2.4,” that is a deployment.

When you release a new version, you update the deployment. Kubernetes rolls out the new version gradually, replacing old pods with new ones a few at a time. If the new version starts crashing, it stops the rollout so your old pods keep handling traffic. You can then roll back to the previous version with a single command.

Most of the things you run in Kubernetes will be deployments. They are the default choice for stateless applications, meaning software that does not need to remember anything between requests.

StatefulSets

Some software needs to remember things. Databases are the obvious example. If you restart a database, it needs its data to still be there when it comes back.

A StatefulSet is like a deployment but for software that needs stable storage and a consistent identity. Each pod in a StatefulSet gets its own persistent storage that stays with it even if the pod restarts. The pods also get predictable names (my-database-0, my-database-1) instead of the random names that deployments give.

You use these for databases, message queues, and anything that stores data locally. In practice, a lot of teams run their databases outside Kubernetes entirely (on something like RDS) and only use StatefulSets for things like Redis or Elasticsearch.

DaemonSets

A DaemonSet runs one copy of a pod on every server in your cluster. Not three copies, not ten copies. One per server.

This is useful for infrastructure tools. Log collection agents that need to run on every server to gather logs. Monitoring agents that collect metrics from each machine. Network plugins that handle traffic routing on each node.

You will not use DaemonSets for your application. Your operations team or whoever manages the cluster will use them for the plumbing that keeps everything working.

Services

Pods come and go. Their IP addresses change every time they restart. So how does one part of your application talk to another part if the address keeps changing?

A service gives a stable address to a group of pods. If you have three API pods behind a service, other parts of your system just talk to the service address and Kubernetes routes the request to one of the three pods. If a pod dies and gets replaced, the service still works because it automatically updates to point at the healthy pods.

There are different types. A ClusterIP service is only reachable inside the cluster, which is what you want for internal communication between your services. A NodePort service opens a port on every server so you can reach it from outside, though you rarely use this in production. A LoadBalancer service creates an actual cloud load balancer (on AWS, this creates an ELB) that routes traffic from the internet to your pods.

Ingress and Gateways

A service gets your traffic into the cluster, but you usually want more control than that. You want requests to api.example.com to go to your API service and requests to app.example.com to go to your frontend service. You want HTTPS termination. You might want rate limiting or authentication.

That is what an Ingress does. It sits in front of your services and routes traffic based on hostnames and paths. One Ingress can handle routing for your entire application. Under the hood, it is usually running Nginx or something similar.

Gateway API is the newer version of Ingress. It does the same job but with more flexibility. You will hear both terms. If your team is setting up something new, they will probably use Gateway API. If they have something existing, it is probably still on Ingress. Both work fine.

Namespaces

A namespace is a way of dividing your cluster into sections. Think of it like folders on a computer. You might have a namespace called “production” and one called “staging.” The software running in each namespace is isolated from the other, so your staging experiments do not accidentally interfere with production.

Most teams use namespaces to separate environments, or to give different teams their own space within a shared cluster. You can also set resource limits per namespace, so one team cannot accidentally use all the CPU and starve everyone else.

When you first set up Kubernetes there is a “default” namespace. Everything goes there unless you say otherwise. It gets messy quickly. Setting up proper namespaces early saves a lot of confusion later.

ConfigMaps and Secrets

Your application needs configuration. Database connection strings, API URLs, feature flags. You do not want to bake these into your container image because then you need a different image for staging and production.

A ConfigMap stores configuration as key-value pairs. Your pod reads from it at startup. If you need to change a setting, you update the ConfigMap rather than rebuilding and redeploying your application.

Secrets work the same way but for sensitive data. Passwords, API keys, TLS certificates. Kubernetes stores them separately and restricts access to them. They are base64 encoded by default, which is not encryption, so most teams add something like Sealed Secrets or an external secrets manager to handle this properly.

Persistent Volumes

By default, when a pod dies, anything stored inside it disappears. That is fine for your web server, which does not store anything locally. It is not fine for a database.

A Persistent Volume is storage that exists independently of any pod. You create the volume, and then your pod mounts it like a hard drive. If the pod restarts, the volume is still there with all its data. If the pod moves to a different server, the volume follows it.

In practice, on AWS this usually means an EBS volume. On GCP it is a persistent disk. You do not usually create these manually. You define a Persistent Volume Claim, which is your pod saying “I need 50GB of storage,” and Kubernetes provisions it automatically.

How it all fits together

Your application gets packaged into containers. Kubernetes runs those containers as pods. Deployments manage how many pods are running and handle updates. Services give stable addresses so pods can find each other. Ingress or a Gateway routes external traffic to the right service. Namespaces keep things organised. ConfigMaps and Secrets handle configuration. Persistent Volumes keep data alive when pods restart.

That covers every concept you are likely to hear in a Kubernetes conversation. If your team is proposing it and you want to understand whether it makes sense, get in touch. I am happy to have that conversation in plain English.

Want to talk about this?

If something here is relevant to what you are working on, we are happy to chat.

Get In Touch