Learn / Kubernetes survival kit / Pods, Deployments, and Services

Lesson 1 of 5 8 min

Pods, Deployments, and Services

The three objects almost everything else in Kubernetes builds on, and how they relate to each other.

Pod: the smallest deployable unit

A Pod wraps one or more containers that are scheduled together on the same node, sharing a network namespace (they can reach each other on localhost) and optionally storage volumes. Most Pods run exactly one container; a second “sidecar” container (a log shipper, a proxy) is the common reason for more than one.

apiVersion: v1
kind: Pod
metadata:
  name: hello-pod
  labels:
    app: hello
spec:
  containers:
    - name: hello
      image: myregistry/hello:1.4
      ports:
        - containerPort: 8080

Pods are ephemeral by design - if a Pod’s container crashes past its restart policy, or its node fails, or you delete it, it’s gone. Nothing brings it back on its own. That’s on purpose: Kubernetes expects a higher-level controller to manage replacement, which is exactly what a Deployment does.

Deployment: managing a set of identical Pods

A Deployment declares “I want N replicas of this Pod spec running, always.” It creates and owns a ReplicaSet, which in turn creates and watches the actual Pods, replacing any that disappear.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello
  template:            # the Pod spec - identical to the bare Pod above, minus metadata.name
    metadata:
      labels:
        app: hello
    spec:
      containers:
        - name: hello
          image: myregistry/hello:1.4
          ports:
            - containerPort: 8080

This is also what makes rolling updates possible (lesson 2) - the Deployment controller is what orchestrates replacing old Pods with new ones gradually instead of all at once.

Service: a stable address for a moving target

Pods get replaced constantly (crashes, rollouts, rescheduling), and each replacement gets a new internal IP. Nothing that depends on a specific Pod’s IP would survive that churn. A Service solves this by giving a stable DNS name and virtual IP to whichever Pods currently match its label selector:

apiVersion: v1
kind: Service
metadata:
  name: hello
spec:
  selector:
    app: hello          # matches the label on the Deployment's Pods
  ports:
    - port: 80
      targetPort: 8080

Other Pods in the cluster can now reach this set of Pods at hello (or hello.<namespace>.svc.cluster.local), and Kubernetes keeps that name routed to the current, ready Pods automatically - no code anywhere has to track individual Pod IPs.

The chain, end to end

Deployment (desired state: 3 replicas of this Pod spec)
    |
    v  creates/manages
ReplicaSet --> Pod, Pod, Pod   (each gets its own IP, all carrying label app=hello)
    ^
    |  selects by label
Service (app=hello)  <-- stable name/IP other things connect to

Everything from here (rollouts, autoscaling, config injection) is really about how these three objects get updated or extended - see the rest of this track, and the kubectl cheatsheet for the commands to inspect and manage them day to day.

Key takeaways

  • A Pod is the smallest deployable unit - one or more containers that share network and storage, scheduled together on the same node.
  • You almost never create a Pod directly in production - a Deployment manages a set of identical Pods, handling replicas, rollouts, and self-healing.
  • A Service gives a stable network identity (a DNS name and virtual IP) to a set of Pods, because individual Pods are ephemeral and their IPs change as they're replaced.
  • The chain is: Deployment creates/manages Pods -> Service routes traffic to whichever Pods are currently ready, by label selector, not by tracking individual Pod IPs.

Quick check

3 questions - see how much stuck.

1. Why don't you usually create a bare Pod directly in production?
2. Why does Kubernetes need a separate Service object instead of just letting other Pods connect to a Pod's IP directly?
3. How does a Service know which Pods to send traffic to?