Skip to content

Kubernetes Pods, Deployments & Services Explained

The three objects you'll touch in almost every Kubernetes task — what each one actually does, and how they compose into a running app.

KuberneteskubectlDocker
2 min readIntermediate
Lab time: 30-45 min
RR

Ranjith R

Linux SysAdmin & Cloud Engineer

Published July 1, 2026Updated July 6, 2026
Share
Section 01

Prerequisites

  • A Kubernetes cluster — minikube or kind is enough for this lab
  • kubectl installed and configured to point at that cluster
Section 02

What You'll Learn

  • Explain why Pods, not containers, are Kubernetes's atomic schedulable unit
  • Use a Deployment to manage replica count and perform a rolling update / rollback
  • Choose between ClusterIP, NodePort, and LoadBalancer Service types
  • Debug a Pod stuck in CrashLoopBackOff or Pending
Section 03

Theory

A Podis the smallest deployable unit in Kubernetes — one or more containers that always share the same network namespace (same IP, can reach each other via localhost) and can share storage volumes. Most Pods run a single container; a second "sidecar" container is added only when it must share that Pod's network/storage (a log shipper, a service mesh proxy).

Why not just run containers directly?

A Deployment doesn't manage Pods directly — it manages a ReplicaSet, which ensures a specified number of Pod replicas are running at all times, replacing any that die. The Deployment sits on top of that to manage rolling updates: when you change the Pod template (a new image tag, say), the Deployment creates a new ReplicaSet and gradually shifts traffic from old Pods to new ones, keeping a rollback point (the previous ReplicaSet) intact.

Service types

TypeReachable fromTypical use
ClusterIPInside the cluster onlyInternal service-to-service traffic
NodePortAny node's IP, on a static high portSimple external access, dev/test
LoadBalancerAn external IP via the cloud provider's LBProduction external access

Whichever type, a Service finds its target Pods by label selector — not by Pod name or IP, both of which change every time a Pod is recreated. This is why consistent labeling is foundational, not optional, in Kubernetes.

Section 04

Architecture

A Deployment manages a ReplicaSet's Pod count; a Service load-balances across whichever Pods currently match its label selector

Section 05

Hands-On Lab

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels: { app: web }
  template:
    metadata:
      labels: { app: web }
    spec:
      containers:
        - name: web
          image: nginx:1.27
          ports: [{ containerPort: 80 }]
---
apiVersion: v1
kind: Service
metadata:
  name: web
spec:
  type: ClusterIP
  selector: { app: web }
  ports: [{ port: 80, targetPort: 80 }]
kubectl apply -f deployment.yaml
kubectl get pods -l app=web              # confirm 3 pods are Running
kubectl get deployment web
kubectl get svc web

# Trigger a rolling update to a new image tag
kubectl set image deployment/web web=nginx:1.27-alpine
kubectl rollout status deployment/web    # watch the rollout progress

# Something wrong with the new version? Roll back instantly:
kubectl rollout undo deployment/web
kubectl rollout history deployment/web
Section 07

Best Practices

Always set resource requests and limits

Without resources.requests/limits, the scheduler can't make sensible placement decisions and a single runaway Pod can starve every other Pod on its node.

Set readiness and liveness probes, not just a container that starts

A Pod reporting "Running" doesn't mean the application inside is actually ready to serve traffic — a readiness probe keeps it out of a Service's endpoint list until it genuinely is.
Section 08

Common Mistakes

Editing a running Pod directly instead of its Deployment

A Pod created by a Deployment is disposable by design — any direct kubectl edit podchange is lost the next time that Pod is replaced. Always change the Deployment's template instead.

Mismatched labels between Deployment template and Service selector

If the Service's selector doesn't exactly match the Pod template's labels, the Service silently has zero endpoints — `kubectl get endpoints web` showing empty is the tell.
Section 09

Troubleshooting

Pod stuck in CrashLoopBackOff: kubectl logs pod-name --previousshows the crashed container's output from before the restart (plain logs shows the new, possibly-empty attempt). kubectl describe pod pod-name shows the exit code and recent events — an exit code of 137 usually means the container was OOM-killed for exceeding its memory limit.

Pod stuck in Pending: kubectl describe pod pod-name's Events section explains why the scheduler can't place it — most commonly insufficient CPU/memory on any node, or an unsatisfiable node affinity/taint rule.

FAQ

Frequently Asked Questions

Pod IPs are ephemeral by design — a replaced Pod is a genuinely new object with a new IP. This is exactly why Services exist: they provide a stable virtual IP and DNS name in front of a constantly-changing set of Pod IPs.
Section 12

Summary

Pods are the atomic unit, Deployments manage ReplicaSets to handle replica count and rolling updates/rollbacks, and Services provide a stable address in front of Pods that are constantly being replaced — all three composed together, matched by label selectors, is the core pattern behind almost every Kubernetes workload.