Page 1 of 2
Imagine you have an app running in a container, and you need to run several copies of it across several servers. If one crashes, something needs to notice and start a new one. If you add more traffic, something needs to add more copies. Doing this by hand, or with your own scripts, gets messy fast. Kubernetes is the tool that does this job for you.
Here's the core idea, and it's the single most important thing to understand: you tell Kubernetes what you want ("I want 3 copies of this app running, always"), and Kubernetes continuously checks reality against that request and fixes any difference. If a copy crashes, Kubernetes starts a new one. You never say "restart this" - you just describe the end result you want, and Kubernetes keeps making it true. This is called the desired state model, and pretty much everything else in Kubernetes builds on it.
A Kubernetes cluster is made of computers working together, split into two roles:
You talk to the whole cluster using one command-line tool called kubectl. Almost everything you do starts with kubectl.
A namespace is just a way to split a cluster into separate areas - for example, one for your "production" apps and one for "testing" apps, so they don't get mixed up.
Labels are simple tags you stick on things, like app: checkout. Kubernetes uses these tags constantly to figure out which things belong together - for example, "send traffic to anything tagged app: checkout." This matters because it lets Kubernetes swap out individual copies of your app (after a crash, or an update) without anything else needing to know or care.
kubectl get pods -n production # list what's running in the "production" area
kubectl get pods -A # list what's running everywhere
kubectl get pods -l app=checkout # only show things tagged app=checkout
kubectl describe pod my-pod # show full details - the first thing to check when something's wrong
A Pod is the smallest thing Kubernetes runs. Most of the time, a Pod is just one container - your app, wrapped up. Occasionally a Pod holds two or three containers that truly need to run side by side and share the same network address, but that's the exception, not the rule.
You'll almost never create a Pod by hand. Instead, you'll use a Deployment (see below), which creates and manages Pods for you.
Every Pod goes through a lifecycle:
One thing worth knowing early: every Pod gets its own internal address (an IP), but that address changes every time the Pod is replaced. So you should never rely on a Pod's specific address directly - that's exactly the problem a Service solves next.
kubectl get pods # see what's running and how many times each has restarted
kubectl describe pod my-pod # see why a Pod is stuck or broken
kubectl logs my-pod # see what the app has printed out
kubectl logs my-pod --previous # see the logs from BEFORE its last crash - very useful for debugging
kubectl exec -it my-pod -- /bin/sh # open a shell inside the container, to poke around
A Deployment is how you actually tell Kubernetes to run your app. You say: "keep 3 copies of this container running, always," and the Deployment takes care of the rest - creating copies, replacing crashed ones, and keeping the count correct.
When you want to update your app (say, a new version of your container image), the Deployment doesn't shut everything down and start over. It replaces copies gradually - a few at a time - so your app stays available the whole time. This gradual replacement is called a rolling update, and it's the default behavior.
If an update goes wrong, you can undo it:
kubectl create deployment web --image=nginx:1.25 --replicas=3
kubectl get deployments # how many copies you want vs. how many are actually running
kubectl scale deployment web --replicas=5 # change how many copies you want
kubectl set image deployment/web nginx=nginx:1.26 # start a rolling update to a new image
kubectl rollout status deployment/web # watch the update happen
kubectl rollout undo deployment/web # go back to how it was before the last update
Since a Pod's address keeps changing every time it's replaced, you need something with a permanent address that always points to whichever copies are currently running. That's exactly what a Service is.
Other things inside the cluster talk to your app through the Service's name, never through an individual Pod's address. The Service automatically spreads traffic across whichever healthy copies exist right now - and if one gets replaced, the Service just quietly starts sending traffic to the new one instead.
kubectl expose deployment web --port=80 --target-port=8080
kubectl get services
Real scenario-based DevOps questions, hands-on practice, and clear explanations for every answer.