Pods — The Basic Unit

Kubernetes Fundamentals

Chapter 3 · Pods — The Basic Unit

Chapter 2 covered the architecture that schedules and runs workloads. This chapter covers the actual thing that architecture schedules: the Pod, Kubernetes' smallest deployable unit.

Why Not Just Containers Directly?

Kubernetes doesn't schedule or manage individual containers directly — it schedules Pods, which wrap one or more containers. This extra layer exists because some workloads genuinely need multiple tightly-coupled containers that must always be scheduled together, share network and storage, and live and die together — a Pod provides exactly that grouping boundary. A Pod is the smallest unit Kubernetes can create, schedule, or scale — there's no such thing as scheduling "half a pod."

What a Pod Actually Provides

  • Shared network namespace — every container in a pod shares the same IP address and port space, and can reach each other via localhost, unlike separate containers needing a real network call to find each other.
  • Shared storage volumes — containers in a pod can mount the same Volume and share files directly.
  • Pods are generally ephemeral — not meant to be durable, long-lived entities managed by hand. A pod is created, and if something goes wrong, it's typically replaced entirely, not repaired — directly foreshadowing Chapter 5's Deployment material.

Single-Container Pods — The Common Case

The vast majority of real pods run exactly one container — the simplest, most common pattern. "One container per pod" is the default mental model; multi-container pods are the exception for specific reasons, not the norm — worth stating plainly to avoid the misconception that pods are usually complex, multi-container arrangements.

Multi-Container Pods & the Sidecar Pattern

When multiple containers do belong in one pod, the most common reason is the sidecar pattern — a secondary "helper" container supporting the main application container. Genuinely common real examples: a logging/log-shipping sidecar reading logs from a shared volume and forwarding them elsewhere, or a service mesh proxy sidecar (Course 2's own k8s2-5 covers service meshes properly) intercepting network traffic for the main container.

An init container is a related but distinct concept: it runs to completion before the main containers start at all — used for setup or prerequisite tasks — rather than running alongside the main container the way a sidecar does.

The Pod Lifecycle

PhaseMeaning
PendingAccepted by the API server, but not yet fully scheduled/running
RunningAt least one container is running
Succeeded / FailedTerminal states for pods meant to run to completion, not indefinitely (relevant to Course 2's Jobs material)

A pod's overall phase doesn't tell the whole story — individual containers within it also have their own states worth checking separately, especially useful for troubleshooting (Course 2's k8s2-8 builds directly on this).

Pods Are Disposable — A Genuinely Important Mental Model Shift

Revisiting Chapter 2's reconciliation loop directly: when a pod fails or its node dies, Kubernetes generally doesn't try to repair the existing pod — it creates a brand new one to replace it, typically with a new name and often a new IP address.

Pets vs. cattle
A well-known phrase in this space, worth carrying through the rest of the course: shift from a "pet" mental model (a server carefully maintained, patched, and kept running for a long time) to a "cattle" mental model (an instance you don't get attached to, replaceable at any time). Never rely on a specific pod's identity staying stable — Chapter 6's Services exist specifically to solve exactly this problem.
Never hardcode a pod's IP address
A pod's IP address can change the moment it's replaced — which can happen at any time, for reasons entirely outside your control. An application that hardcodes a specific pod IP will break the first time that pod is recreated, which is exactly the failure this course's Services chapter (Chapter 6) is built to prevent.

Why You Rarely Create Pods Directly

Despite pods being the fundamental unit, you'll rarely create bare Pods directly in real usage — almost always through a higher-level controller like a Deployment (Chapter 5) that manages a pod's full lifecycle, replacement, and scaling for you. This chapter deliberately focused on understanding what a pod is and how it behaves; Chapters 4 and 5 build directly on this foundation to show how you'd actually create and manage them in practice.

Hands-On Exercises

Exercise 1

Explain why Kubernetes schedules Pods rather than individual containers directly, and give a concrete example of when a multi-container pod (the sidecar pattern) would make sense.

📄 View solution
Exercise 2

Explain the difference between an init container and a sidecar container — specifically how their timing relative to the main container differs.

📄 View solution
Exercise 3

Explain the "pets vs. cattle" mental model shift in your own words, and explain specifically why an application that hardcodes a pod's IP address is likely to break in a real Kubernetes environment.

📄 View solution

Chapter 3 Quick Reference

  • Kubernetes schedules Pods, not containers directly — the smallest unit it can create/schedule/scale
  • A pod gives its containers a shared network namespace (localhost) and shared storage volumes
  • One container per pod is the default; multi-container pods (sidecar pattern) are the deliberate exception
  • Init containers run to completion before the main container starts; sidecars run alongside it
  • Pod phases: Pending → Running → Succeeded/Failed; individual containers also have their own states
  • Pets vs. cattle — pods are disposable and replaceable, never repaired in place; never hardcode a pod IP
  • Bare pods are rarely created directly — Chapter 5's Deployments manage their full lifecycle instead
  • Next chapter: kubectl & Your First Deployment — CLI basics, imperative vs. declarative, YAML manifests, namespaces