7.8 Deployment Status Conditions and Health Checks

Right, so your Deployment is up and running. You’ve run kubectl get deployments and it proudly reports 3/3 pods are available. Fantastic. You high-five the intern and call it a day. But what if I told you that “Available” is a filthy, rotten liar? Well, maybe not a liar, but it’s certainly not telling you the whole story. It’s the highlight reel, not the grueling practice session where things actually go wrong.

7.7 Scaling: Manual and with HPA

Right, so you’ve got your Pods running. They’re beautiful, they’re perfect, and they’re currently a single point of failure. You and I both know that’s not going to fly. This is where we graduate from just keeping things alive to actually managing how many of them are alive. We’re going to talk about scaling, and we’ll do it in two ways: the way you tell it what to do (manual), and the way it figures things out for itself (with the Horizontal Pod Autoscaler, or HPA). This is where your deployment starts to feel like a real, robust system instead of a fancy demo.

7.6 Rolling Back a Deployment: rollout undo

Right, so you’ve done it. You’ve issued a kubectl apply -f deployment.yaml with the serene confidence of a master engineer, only to watch your application immediately catch fire and start screaming in a language you don’t understand. The new container image you just deployed is a complete dud. Maybe it’s a bug. Maybe you forgot to build the binary. Maybe it’s Maybelline. It doesn’t matter. What matters is that you need to get back to the last known good state, and you need to do it now. This is where kubectl rollout undo earns its place in the hall of fame of indispensable commands.

7.5 Pausing and Resuming a Deployment Rollout

Right, so you’ve told your Deployment to roll out a new version of your app. It’s happily chugging along, Pod by Pod, and then… oh. You just remembered the new container image you told it to use has a nasty bug in its health check endpoint. The rollout is actively deploying broken software. Your stomach sinks. Do you panic? No. You do the smart thing: you hit the pause button.

7.4 Recreate Strategy: Full Restart

Alright, let’s talk about the Recreate strategy. You’re going to use this when you absolutely, positively cannot have two versions of your application running at the same time. Think of it as the “scorched earth” or “turn it off and on again” method of deployment. It’s brutally simple: we completely terminate all the old Pods first. Only after they’re all dead and gone do we spin up the new ones.

7.3 Rolling Update Strategy: maxSurge and maxUnavailable

Right, so you’ve got your app deployed, it’s running smoothly, and now you need to push a new version. You’re not going to just kubectl delete --all and pray, are you? Of course not. You’re going to do a rolling update, the civilized way to upgrade your software without causing a full-blown production incident (or at least, a smaller, more manageable one). The magic—and the control—of a rolling update is managed by two knobs in your Deployment spec: maxSurge and maxUnavailable. These two parameters are the yin and yang of your update strategy, controlling the trade-off between speed and availability. They’re the reason your users don’t get a 502 Bad Gateway error while you’re deploying.

7.2 Deployment: Declarative Updates and Rollout History

Right, so you’ve got your app running in a Pod. It’s a beautiful thing. But Pods are mortal; they get sick, they die, they get scheduled onto different nodes. You can’t just kubectl create pod and call it a day. You need a ReplicaSet to keep a desired number of clones running. But even that’s not enough. What happens when you need to update your app from my-app:v1.0 to my-app:v1.1? With a ReplicaSet, your strategy is basically to turn everything off and then turn everything back on again. That’s not an update, that’s an outage. Enter the Deployment. This is where we stop being cowboys and start being engineers.

7.1 ReplicaSet: Maintaining a Stable Set of Pod Replicas

Right, so you’ve got a Pod. It’s running your app. It’s beautiful. And then, it dies. A node explodes, a config error causes a crash loop, you get a frantic call at 3 AM—you know, the usual. Your single Pod was a single point of failure, and it failed. Spectacularly. This is why we don’t just run Pods. We run ReplicaSets. Think of a ReplicaSet as your application’s overly anxious, but brilliant, stage manager. Its entire job is to constantly look at the stage, count the actors (Pods), and if the number doesn’t match the script, it frantically hires new ones or fires extras. It maintains a stable set of Pod replicas. That’s the whole show. It ensures that a specified number of identical Pods are running at any given time. It’s the bedrock of reliability in Kubernetes, and it’s almost criminally simple to use.

5.9 Ephemeral Containers: Debugging Running Pods

Right, so your pod is running. Or, more accurately, it’s doing something that is not “working correctly.” It’s crashing, it’s slow, it’s returning 500s for reasons known only to the eldritch gods of distributed systems. The classic, knee-jerk reaction is to kubectl exec into it and start poking around with top, curl, or your favorite debugging tool. But what if the pod’s container is a stripped-down, distroless nightmare that doesn’t even have a shell? No /bin/bash. No /bin/sh. Not even ls. It’s just your application, sitting in a bare-bones runtime, mocking you. Or worse, what if the application has crashed and the container is now in a CrashLoopBackOff, meaning you can’t exec into it at all because there’s no running process to latch onto?

5.8 Resource Requests and Limits on Pods

Right, let’s talk about money. Not your money, but the money of your cluster. In Kubernetes, money is CPU and memory. And just like in real life, if you don’t budget properly, you’re going to have a bad time. This is where requests and limits come in. They are the financial planning department for your Pods, and if you ignore them, you’re going to get a call from the bank at 3 AM.

5.7 Pod Networking: Shared Network Namespace and localhost

Alright, let’s get our hands dirty with Pod networking. This is where the rubber meets the road, and frankly, it’s one of the most elegant and simultaneously confusing parts of the Pod model. You see, a Pod isn’t just a wrapper for a container; it’s a shared execution environment. And the most critical thing it shares? Its network namespace. Think of a network namespace as an isolated, complete TCP/IP stack: its own IP address, its own set of ports, its own routing tables, iptables rules, the works. When Kubernetes creates a Pod, it first creates a special “infrastructure container” (often called the pause container) whose sole, noble job is to hold open this network namespace. All the other containers in your Pod then join this namespace. This is the magic. This is why when your app container and your log-shipping sidecar container both start up, they see the exact same network interface with the exact same IP address.

5.6 Restart Policies: Always, OnFailure, Never

Alright, let’s talk about what happens when your Pod’s main process decides to take a nap, gets stage fright, or just flat-out dies. This is where the restartPolicy comes in. It’s the instruction manual you leave for the kubelet (the node agent) on what to do when the container(s) inside your Pod exit. Think of it as your contingency plan. Do you want it to always try again, like an optimistic friend who believes the third time’s the charm? Or only if it fails spectacularly? Or maybe you want it to just lie there and not move, like a teenager on a Saturday morning? Kubernetes gives you three choices for this: Always, OnFailure, and Never.

5.5 Pod Lifecycle: Pending, Running, Succeeded, Failed, Unknown

Alright, let’s get down to brass tacks. You can’t talk about Pods without understanding their lifecycle. It’s the story of their existence, from a hopeful idea in the scheduler’s mind to their glorious—or more often, tragically brief—demise. Think of it like a play with five possible acts: Pending, Running, Succeeded, Failed, and the enigmatic Unknown. Your job is to be the stage manager, not just the audience. The Five Fates of a Pod Kubernetes doesn’t deal in vagueness. A Pod’s status is a first-class citizen, and it will be slotted into one of these five phases. You can see it yourself with a classic kubectl get pods:

5.4 Init Containers: Setup Before the Main Container Starts

Right, so you’ve got your main container all set to do its job, but it has some diva-level demands before it can start. Maybe it needs a database schema loaded, a configuration file pulled from a secure vault, or it needs to wait for some external service to become healthy. You could just jam all that startup logic into your main container’s entrypoint script, but then you’re building a Frankenstein’s monster of a container that’s hard to maintain and violates the whole “do one thing” principle.

5.3 Sidecar, Ambassador, and Adapter Patterns

Alright, let’s talk about the three patterns that make Pods the Swiss Army knives of Kubernetes. You’ve got your container, your little isolated process. Cute. But the real magic happens when you start lashing them together inside a Pod to do a single, more complex job. This isn’t just “running two things together”; it’s a formalized way to extend, proxy, or adapt your main application without changing a single line of its code. Think of it less like a roommate situation and more like a symbiote situation.

5.2 Single-Container vs Multi-Container Pods

Alright, let’s get this straight: a Pod is the smallest deployable unit in Kubernetes, but it’s not always a single container. Think of a Pod not as a container, but as a logical host for one or more containers. It’s a shared execution environment where these containers cohabitate, sharing things like network namespace and storage volumes. They’re roommates, not neighbors in separate apartments. The single-container Pod is the easy one. It’s the default, the “hello world” of Kubernetes. You ask for an nginx Pod, and Kubernetes gives you a Pod with a single nginx container inside it. It’s simple, it’s clean, and for 90% of your applications, it’s all you’ll ever need. The Pod is essentially just a wrapper around your container, giving it the superpowers of being a Kubernetes object—things like health checks, lifecycle management, and a stable IP address.

5.1 Pod Anatomy: Spec, Status, and Metadata

Alright, let’s get our hands dirty. If a Pod is the atom of your Kubernetes universe, then we need to pull out our metaphorical electron microscope and look at its constituent parts. Don’t worry, it’s less “quantum physics” and more “well-labeled lunchbox.” Every Pod you define is essentially a request slip you hand to the Kubernetes API server. This request is embodied in a YAML or JSON manifest. And that manifest is built on three fundamental pillars: the metadata, the spec, and the status. You control the first two. Kubernetes controls the last one, and it will very loudly tell you when you’ve screwed up the first two.

— joke —

...