Kubernetes runs containers across a cluster of machines and keeps them in the state you describe. Its vocabulary can feel overwhelming, but you can deploy a real application once you understand three objects: Pods, Deployments and Services.
Practise locally with a single-node cluster such as kind, minikube or the Kubernetes option in Docker Desktop. You do not need a cloud account to learn the basics.
Declarative, not imperative
With Kubernetes you do not say “start three containers”. You submit a description — “there should be three replicas of this container” — and controllers continuously work to make reality match. If a node dies, pods are recreated elsewhere. This desired state model is the key idea behind everything else.
Pods: the smallest unit
A Pod wraps one or more containers that share networking and storage. Most pods run a single application container. Pods are ephemeral: they can be killed, rescheduled or replaced at any time, and each new pod gets a new IP address. That is why you rarely create pods directly.
Deployments: keeping pods running
A Deployment manages a set of identical pods. It handles replicas, self-healing and rolling updates.
apiVersion: apps/v1
kind: Deployment
metadata:
name: articles-api
spec:
replicas: 3
selector:
matchLabels:
app: articles-api
template:
metadata:
labels:
app: articles-api
spec:
containers:
- name: api
image: ghcr.io/example/articles-api:1.4.0
ports:
- containerPort: 3000
resources:
requests: { cpu: "100m", memory: "128Mi" }
limits: { memory: "256Mi" }
readinessProbe:
httpGet: { path: /healthz, port: 3000 }
initialDelaySeconds: 5
livenessProbe:
httpGet: { path: /healthz, port: 3000 }
initialDelaySeconds: 15
A few fields deserve attention:
- labels / selector connect the Deployment to its pods.
- resources.requests tell the scheduler how much capacity to reserve; limits cap usage.
- readinessProbe decides when a pod may receive traffic; livenessProbe restarts a pod that is stuck.
When you change the image tag and apply the file again, the Deployment performs a rolling update: new pods start and become ready before old ones are removed.
Services: a stable address
Because pod IPs change, other components need a stable way to reach them. A Service selects pods by label and gives them a single virtual IP and DNS name.
apiVersion: v1
kind: Service
metadata:
name: articles-api
spec:
selector:
app: articles-api
ports:
- port: 80
targetPort: 3000
type: ClusterIP
Inside the cluster, other workloads can now call http://articles-api. Service types:
| Type | Reachable from | Typical use |
|---|---|---|
| ClusterIP | Inside the cluster | Internal APIs, databases |
| NodePort | A port on every node | Local testing |
| LoadBalancer | The internet via a cloud load balancer | Simple public services |
For HTTP routing by hostname or path, you usually add an Ingress (or the newer Gateway API) in front of ClusterIP services.
Try it
kubectl apply -f deployment.yaml -f service.yaml
kubectl get pods -l app=articles-api
kubectl rollout status deployment/articles-api
kubectl port-forward service/articles-api 8080:80
Delete one pod with kubectl delete pod <name> and watch the Deployment replace it within seconds.
Configuration and secrets
Keep configuration out of images. Use ConfigMaps for non-sensitive settings and Secrets for credentials, and reference them as environment variables or mounted files. Note that Secrets are only base64-encoded by default; in production, enable encryption at rest and restrict who can read them.
Scaling and updates in practice
Once the Deployment is running, two commands cover a lot of day-to-day work:
kubectl scale deployment/articles-api --replicas=5
kubectl set image deployment/articles-api api=ghcr.io/example/articles-api:1.4.1
kubectl rollout undo deployment/articles-api # roll back if the new version misbehaves
In real teams you rarely type these by hand. Manifests live in Git, and a CI/CD pipeline (or a GitOps tool) applies changes after review. For automatic scaling, a HorizontalPodAutoscaler adjusts replicas based on CPU or custom metrics — which only works well if you set realistic resource requests.
Readiness probes matter most during rollouts: without them, Kubernetes may send traffic to pods that have started but are not yet ready, and users see errors during every deploy.
When Kubernetes is (and is not) worth it
- Worth it: many services, several teams, need for consistent deployment and scaling.
- Worth it: you already use a managed Kubernetes offering and have platform support.
- Probably not yet: a single app with modest traffic — a managed container platform may be simpler.
Master Pods, Deployments and Services first. Everything else in Kubernetes builds on the same pattern: describe the desired state, and let controllers make it true.
Comments