Kubernetes Explained (2026): Pods, Deployments, Services for Beginners
The first time I used Kubernetes I spent an afternoon deleting a Pod that kept coming back, convinced the cluster was broken. It was working exactly as designed: I had told a Deployment I wanted one copy running, and it kept its promise. Most beginner confusion about Kubernetes comes from that one idea, so this post explains Kubernetes for beginners from the top down: what the control plane and nodes are, what Pods, Deployments, ReplicaSets and Services actually do, where Ingress and Gateway API fit, what ConfigMaps, Secrets and namespaces are for, and, step by step, how a kubectl apply becomes a running container. It is written against Kubernetes v1.37, the current minor release, and ends with a list of things you can ignore for your first few months.
What is Kubernetes, in one paragraph?
Kubernetes is a database of desired state with a set of programs that keep reality matching it. You do not tell it "start three containers". You write down "there should be three copies of this container, reachable on port 80", store that record in the cluster, and a collection of controllers works continuously to make it true, including after a node dies or someone deletes a Pod by hand. Everything else sits on top of that reconciliation loop.
v1.37 arrived on 26 August 2026 and the latest patch, v1.37.2, on 28 October. The upstream project maintains the three most recent minor versions, listed on the releases page. Adoption is no longer the question it was: the CNCF's 2025 annual survey found 82 percent of container users running Kubernetes in production, up from 66 percent in 2023. Whether you need it is a separate question, which I tackled in Is Kubernetes still worth it in 2026?.
Control plane vs nodes: the two halves of a cluster
A cluster has a control plane, which decides, and nodes, which run your containers. The components page lists them, and it is short enough to memorise.
The control plane is:
- kube-apiserver: the front door. Every read and write, from
kubectl, from controllers, from nodes, goes through it. It authenticates the caller, checks authorisation (RBAC), runs admission checks, validates the object and stores it. - etcd: a consistent key-value store holding every object. If etcd is lost without a backup, the cluster has forgotten what it was supposed to be running.
- kube-scheduler: watches for Pods that have no node yet and picks one, based on resource requests, affinity rules, taints and so on.
- kube-controller-manager: a bundle of controllers (Deployment, ReplicaSet, Job, EndpointSlice, Node and others), each a loop that compares desired state with actual state and acts on the difference.
- cloud-controller-manager (optional): the part that talks to AWS, GCP or Azure to create load balancers and learn about VMs.
Each node runs:
- kubelet: the agent that watches the API server for Pods assigned to its node and makes the container runtime start them, then reports status back.
- a container runtime, such as containerd or CRI-O, which actually pulls images and runs containers.
- kube-proxy, now marked optional in the docs, which programs node networking rules so that Service addresses work. Some network plugins, Cilium for example, replace it entirely.
On EKS, GKE or AKS you never see the control plane machines, but every error message you read still comes from one of them.
Pods, ReplicaSets and Deployments: what is the difference?
A Pod is the smallest thing Kubernetes schedules: one or more containers that share a network namespace (one IP address, so they talk over localhost) and can share volumes. Pods are disposable. They are not restarted onto a new node when their node dies; they are replaced by new Pods with new names and new IPs. That is why you almost never create a bare Pod.
A ReplicaSet keeps a set number of identical Pods running. If one disappears, it creates another. That is the thing that kept resurrecting the Pod I was deleting.
A Deployment manages ReplicaSets so that you can change the Pod template safely. When you change the image tag, the Deployment creates a new ReplicaSet and scales it up while scaling the old one down. Only changes to the Pod template (spec.template) trigger a rollout; changing the replica count does not. The API defaults in v1.37 are worth knowing because they explain what you see during an update: maxSurge and maxUnavailable both default to 25 percent, revisionHistoryLimit keeps 10 old ReplicaSets around for rollback, and progressDeadlineSeconds reports a rollout as failed after 600 seconds without progress. The Deployment docs cover kubectl rollout undo, which simply scales an old ReplicaSet back up.
In practice you write Deployments, Kubernetes writes ReplicaSets, and you read Pods when debugging. StatefulSets (stable identities) and DaemonSets (one Pod per node) exist, but the Deployment covers most web services.
Each container in the Pod template should declare resource requests, because that is what the scheduler uses to place it. I wrote a separate explainer on requests and limits, and another on the liveness, readiness and startup probes that tell Kubernetes when a container is ready for traffic.
What is a Kubernetes Service, and which type do I need?
Pods come and go and their IPs change, so clients need something stable. A Service gives a set of Pods one virtual IP and a DNS name such as web.default.svc.cluster.local. It finds its Pods by label selector: any Pod whose labels match is a backend. The Service docs describe the mechanism: a controller watches for matching Pods and keeps a list of their addresses in EndpointSlice objects, and kube-proxy or the network plugin turns that list into forwarding rules on every node. A Pod that fails its readiness probe is taken out of the list, which is why readiness probes matter more than most beginners think.
There are four types:
- ClusterIP (the default): reachable only inside the cluster. Most Services are this.
- NodePort: also opens the same port on every node, from a default range of 30000 to 32767 (set in the API server source).
- LoadBalancer: asks the cloud provider for an external load balancer pointing at the nodes. On a laptop cluster this stays pending unless you install something to fulfil it.
- ExternalName: a DNS alias to something outside the cluster, with no proxying at all.
Ingress or Gateway API: how traffic gets in
For host- and path-based HTTP routing there are two APIs. Ingress is the old one, and the Ingress docs now say plainly that the API "has been frozen": it stays GA and will not be removed, but it gets no new features, and the project recommends Gateway API instead. The most popular controller, ingress-nginx, was retired in March 2026 with no further releases or security fixes, and its GitHub repository is now archived.
Gateway API splits the job into roles: a GatewayClass (which implementation, such as Envoy Gateway, Istio or Cilium), a Gateway (the listener, often owned by a platform team) and HTTPRoutes (owned by app teams). It is installed as CRDs rather than built in; v1.7.0, released on 29 October 2026, promoted HTTPRoute retries to the Standard channel. If you are starting today, learn Gateway API and treat Ingress as something you will meet in older clusters. My ingress-nginx retirement post compares the replacements.
ConfigMaps, Secrets and namespaces
A ConfigMap holds non-secret configuration as key-value pairs that you inject into Pods as environment variables or mounted files, so the same image runs in staging and production. A Secret is the same shape for sensitive values, with one trap every beginner should hear early. The Secrets docs warn that Secrets are "by default, stored unencrypted" in etcd, and the base64 in a Secret manifest is encoding, not encryption. Anyone who can create a Pod in a namespace can read that namespace's Secrets indirectly by mounting them. Secrets are capped at 1 MiB (MaxSecretSize). Turn on encryption at rest, restrict who can read them with RBAC, and do not commit them to Git in plain text.
A namespace is a name scope and a boundary for permissions and quotas. Two teams can each have a Service called api in different namespaces. Without NetworkPolicies, Pods in different namespaces can still talk to each other.
| Object | What it does | Beginner needs it? | Docs |
|---|---|---|---|
| Pod | One or more containers sharing an IP and volumes | Read it, rarely write it | Pods |
| ReplicaSet | Keeps N identical Pods running | Created for you | ReplicaSet |
| Deployment | Rolling updates and rollback over ReplicaSets | Yes, day one | Deployments |
| Service | Stable virtual IP and DNS name for Pods | Yes, day one | Service |
| Ingress | HTTP routing; API frozen | Only in older clusters | Ingress |
| Gateway, HTTPRoute | HTTP routing, role-oriented, CRDs | When you expose apps | Gateway API |
| ConfigMap | Non-secret config as env vars or files | Yes, week one | ConfigMaps |
| Secret | Sensitive values, unencrypted in etcd by default | Yes, with care | Secrets |
| Namespace | Name scope for objects, RBAC and quotas | Yes | Namespaces |
What happens when you run kubectl apply?
Here is the smallest useful pair of objects. It is close to what I use in the step-by-step kind tutorial, where you run it on your laptop.
# web.yaml: a Deployment and a ClusterIP Service (apps/v1 and v1 are the stable APIs)
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 3 # desired state: three Pods
selector:
matchLabels: { app: web } # which Pods this Deployment owns
template: # changing anything here triggers a rollout
metadata:
labels: { app: web }
spec:
containers:
- name: web
image: ghcr.io/stefanprodan/podinfo:6.17.0 # pinned tag, never :latest
ports:
- containerPort: 9898
resources:
requests: { cpu: 50m, memory: 64Mi } # what the scheduler reserves
readinessProbe:
httpGet: { path: /readyz, port: 9898 } # gate traffic until ready
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
type: ClusterIP # the default; in-cluster only
selector: { app: web } # matches the Pod labels above
ports:
- port: 80 # the Service port clients use
targetPort: 9898 # the container port traffic goes to
When you run kubectl apply -f web.yaml, this is the sequence:
- kubectl reads your kubeconfig, converts the YAML to JSON and sends it to kube-apiserver over HTTPS.
- The API server authenticates you, checks RBAC, runs admission controllers (which may add defaults or reject the object), validates it and writes the Deployment and Service to etcd. At this point nothing is running.
kubectl applyreturns as soon as the records are stored. - The Deployment controller notices a Deployment with no ReplicaSet and creates one. The ReplicaSet controller notices it has zero of three Pods and creates three Pod objects. They have no node yet, so
kubectl get podsshows them as Pending. - The scheduler sees unscheduled Pods, filters nodes that can fit 50m of CPU and 64Mi of memory, scores the rest and writes a node name into each Pod.
- The kubelet on each chosen node sees a Pod assigned to it, asks the container runtime to pull the image and start the container (ContainerCreating), then reports Running.
- Once the readiness probe passes, the EndpointSlice controller adds the Pod's IP to the Service's endpoints, and kube-proxy or the network plugin updates node rules. Only now does traffic to
webreach it.
No component calls another directly. Each watches the API server and writes results back, which is why errors show up as statuses and events on objects, read with kubectl describe, rather than as a failed command.
What can a beginner safely ignore?
A lot. For your first few months, I would skip:
- Writing operators and CRDs. You will use CRDs (Gateway API is one), but building controllers can wait.
- Service meshes. Istio, Linkerd and friends solve problems you do not have with three Services.
- StatefulSets for databases. Use a managed database while you learn. Running Postgres on Kubernetes is fine later, with an operator.
- Building your own cluster with kubeadm. Worth doing once to learn, not for running things. Use kind locally and a managed service in the cloud.
- Helm chart authoring. Install charts, sure. Write plain YAML first so you understand what the chart templates.
Do not skip resource requests, readiness probes, labels, namespaces, and reading kubectl describe and kubectl get events. When something breaks, it is almost always one of three states, and each has its own playbook: Pending, ImagePullBackOff and CrashLoopBackOff.
This is also where ordinary DevOps discipline earns its keep. Applying YAML by hand is how clusters drift into states nobody can reproduce, so keep manifests in Git, pin image tags and review changes. A coding agent can write a Deployment in seconds; it is the review, the version pinning and the rollback plan that keep it from paging you.
FAQ
What is the difference between a Pod and a Deployment?
A Pod is one running instance of your containers, with its own IP, and it is not replaced if it dies on its own. A Deployment is a controller that keeps a desired number of Pods running through a ReplicaSet and handles rolling updates and rollback. You write the Deployment and let it manage Pods.
Is a Kubernetes Service a load balancer?
A ClusterIP Service is an internal virtual IP that spreads connections across ready Pods using node-level rules, so it does basic layer 4 load balancing inside the cluster. For HTTP routing by host or path you need Gateway API or an Ingress controller on top.
Are Kubernetes Secrets encrypted?
Not by default. The docs state that Secrets are stored unencrypted in etcd, and base64 is only an encoding. Enable encryption at rest (managed services usually offer a KMS option), limit access with RBAC, and consider an external secret store.
Should I learn Ingress or Gateway API in 2026?
Gateway API. Ingress is frozen, still supported and not going away, so you will meet it in existing clusters, but new features land in Gateway API, and the best-known Ingress controller, ingress-nginx, stopped receiving fixes in March 2026.
If I were starting from zero this quarter, I would install kind, apply the two objects above, break them on purpose (wrong image tag, wrong selector, failing probe) and read what kubectl describe says each time. One afternoon of that teaches more than a week of diagrams. The kind and kubectl guide walks through exactly that, version-pinned, with a troubleshooting table for the errors you will hit. After that, I would move one real service to a managed cluster with its manifests in Git from the first commit.
Related: Is Kubernetes Still Worth It in 2026? v1.37, 82% in Production, Real Costs, Kubernetes Requests and Limits Explained: 8% CPU Used, Resize GA in 1.35 and Ingress NGINX Is Retired: What Replaces It and How to Choose in 2026.
Spot an error or something out of date? Email me and I will fix it and log it on the corrections page.
I'm Ajay Kumar — I build and operate PandaStack, an open-source Firecracker microVM cloud for AI agents, and write about the infrastructure and tooling around it.
Need this kind of infrastructure work? See what I do or email hello@ajayk.sh.
Related
Homelab for DevOps in 2026: Mini PC vs Raspberry Pi, k3s vs Talos
How to build a homelab to learn DevOps in 2026: mini PCs vs a $385 Raspberry Pi 5 vs old laptops, Proxmox VE 9.2, k3s 1.37 vs Talos 1.14 vs MicroK8s, what a watt costs at 18.16 cents per kWh, what to practise, and when cloud free tiers win.
11 minOct 20, 2026Terraform vs Pulumi vs Crossplane in 2026: Which to Choose
Terraform, OpenTofu, Pulumi and Crossplane compared as of October 2026: how each handles state and drift, what it costs, and which team fits which tool.
12 minOct 5, 2026Kubernetes as the Agent Control Plane in 2026: Agent Sandbox Hit v1.0, 300 Claims a Second, and DRA in Every Supported Release
What shipped for running AI agents on Kubernetes by October 2026: the kubernetes-sigs Agent Sandbox project from a KubeCon preview in November 2025 to v1.0.0 in August, its four CRDs and gVisor, Kata and Firecracker runtime classes, Google's 300 claims per second and 16x growth figures, a density benchmark of 61 Kata agents versus 88, 133 and 274 per node, DRA going GA in 1.34 and locked on through 1.37, kagent, Dapr Agents 1.0, agentgateway, the Inference Extension's move into llm-d, the CNCF survey's 66 percent, and the Gartner 80 percent platform-team prediction nobody has measured.
13 min