Learn Kubernetes in 10 DaysDay 3: Understanding Pods

Day 3: Understanding Pods

What You'll Learn Today

  • What Pods are and why Kubernetes uses Pods instead of bare containers
  • Pod lifecycle and state transitions
  • Multi-container Pod patterns
  • Probes for health checking

What is a Pod?

A Pod is the smallest deployable unit in Kubernetes. It wraps one or more containers that share the same network namespace and storage volumes.

In Docker, individual containers were the management unit. In Kubernetes, you never manage containers directly β€” they are always wrapped in a Pod.

flowchart TB
    subgraph Pod["Pod"]
        C1["Container A"]
        C2["Container B"]
        NET["Shared Network\n(localhost)"]
        VOL["Shared Volume"]
    end
    C1 --- NET
    C2 --- NET
    C1 --- VOL
    C2 --- VOL
    style Pod fill:#3b82f6,color:#fff

Pods vs. Docker Containers

Property Docker Container Kubernetes Pod
Unit Single container One or more containers
Network Independent per container Shared within Pod (localhost)
Storage Explicit volume sharing Shared within Pod
IP Address Per container Per Pod
Scaling Per container Per Pod

Pod Lifecycle

Pods go through the following phases.

flowchart LR
    A["Pending"] --> B["Running"]
    B --> C["Succeeded"]
    B --> D["Failed"]
    A --> D
    style A fill:#f59e0b,color:#fff
    style B fill:#22c55e,color:#fff
    style C fill:#3b82f6,color:#fff
    style D fill:#ef4444,color:#fff
Phase Description
Pending Pod created but containers not yet running
Running At least one container is running
Succeeded All containers exited successfully
Failed At least one container exited with an error
Unknown Pod status cannot be determined (node failure)

Container States

State Description
Waiting Waiting to start (image pull, etc.)
Running Container is executing
Terminated Container has exited (success or failure)
# Check Pod state in detail
kubectl describe pod my-nginx

Detailed Pod Definition

A more practical Pod definition.

apiVersion: v1
kind: Pod
metadata:
  name: web-app
  labels:
    app: web
    environment: development
  annotations:
    description: "Sample web application pod"
spec:
  containers:
    - name: web
      image: nginx:1.27
      ports:
        - containerPort: 80
          protocol: TCP
      resources:
        requests:
          cpu: "100m"
          memory: "128Mi"
        limits:
          cpu: "250m"
          memory: "256Mi"
      env:
        - name: APP_ENV
          value: "development"
  restartPolicy: Always

Labels

Labels are key-value pairs for identifying resources. Many Kubernetes features depend on labels.

metadata:
  labels:
    app: web
    environment: prod
    version: v1.0
# Filter by label
kubectl get pods -l app=web
kubectl get pods -l 'app=web,environment=prod'

# Add a label
kubectl label pod web-app tier=frontend

# Show labels
kubectl get pods --show-labels

Resources

Just like Docker resource limits, Kubernetes controls container resources with requests and limits.

Setting Description
requests Guaranteed resources for the container. Used for scheduling
limits Maximum resources the container can use
resources:
  requests:
    cpu: "100m"       # 0.1 CPU core
    memory: "128Mi"   # 128 MiB
  limits:
    cpu: "250m"       # 0.25 CPU core
    memory: "256Mi"   # 256 MiB

CPU is specified in "millicores" (m). 1000m = 1 CPU.

Restart Policy

Policy Description
Always Always restart on exit (default)
OnFailure Restart only on failure
Never Never restart

Multi-Container Pods

A Pod can contain multiple containers that work closely together.

Sidecar Pattern

An auxiliary container that supports the main container.

flowchart LR
    subgraph Pod["Pod"]
        MAIN["Main Container\n(Web App)"]
        SIDE["Sidecar\n(Log Collector)"]
        VOL["Shared Volume\n(/var/log)"]
    end
    MAIN --> VOL
    SIDE --> VOL
    SIDE --> EXT["External Log\nSystem"]
    style Pod fill:#3b82f6,color:#fff
    style EXT fill:#8b5cf6,color:#fff
apiVersion: v1
kind: Pod
metadata:
  name: web-with-sidecar
spec:
  containers:
    - name: web
      image: nginx:1.27
      volumeMounts:
        - name: logs
          mountPath: /var/log/nginx
    - name: log-collector
      image: busybox:1.37
      command: ["sh", "-c", "tail -f /var/log/nginx/access.log"]
      volumeMounts:
        - name: logs
          mountPath: /var/log/nginx
  volumes:
    - name: logs
      emptyDir: {}

Multi-Container Patterns

Pattern Description Example
Sidecar Supports the main container Log collection, proxy
Ambassador Mediates external communication DB connection proxy
Adapter Transforms output formats Metrics conversion

Init Containers

Special containers that run before the main containers start. Used for initialization tasks like waiting for dependencies or running database migrations.

apiVersion: v1
kind: Pod
metadata:
  name: app-with-init
spec:
  initContainers:
    - name: wait-for-db
      image: busybox:1.37
      command: ['sh', '-c', 'until nc -z db-service 5432; do echo waiting for db; sleep 2; done']
  containers:
    - name: app
      image: my-app:1.0
flowchart LR
    I1["Init Container 1\n(Wait for DB)"] --> I2["Init Container 2\n(Fetch Config)"]
    I2 --> M["Main Container\n(App Start)"]
    style I1 fill:#f59e0b,color:#fff
    style I2 fill:#f59e0b,color:#fff
    style M fill:#22c55e,color:#fff

Init Container characteristics:

  • Run sequentially, one at a time
  • All Init Containers must succeed before main containers start
  • Retried on failure according to the restartPolicy

Probes (Health Checks)

Kubernetes monitors container health with three types of probes β€” an evolution of Docker's HEALTHCHECK.

Probe Purpose On Failure
livenessProbe Is the container alive? Restart container
readinessProbe Can it receive traffic? Remove from Service
startupProbe Has startup completed? Disable other probes until done
apiVersion: v1
kind: Pod
metadata:
  name: web-with-probes
spec:
  containers:
    - name: web
      image: nginx:1.27
      ports:
        - containerPort: 80
      livenessProbe:
        httpGet:
          path: /
          port: 80
        initialDelaySeconds: 5
        periodSeconds: 10
      readinessProbe:
        httpGet:
          path: /
          port: 80
        initialDelaySeconds: 3
        periodSeconds: 5
      startupProbe:
        httpGet:
          path: /
          port: 80
        failureThreshold: 30
        periodSeconds: 10

Probe Methods

Method Description Use Case
httpGet Expects 200-399 from an HTTP endpoint Web servers
tcpSocket Attempts TCP connection Databases
exec Runs a command, expects exit code 0 Custom checks
grpc gRPC health check protocol gRPC services

Working with Pods

Accessing Containers

# Shell access
kubectl exec -it web-app -- /bin/bash

# Specify container in multi-container Pod
kubectl exec -it web-with-sidecar -c log-collector -- /bin/sh

# Copy files from container
kubectl cp web-app:/etc/nginx/nginx.conf ./nginx.conf

# Copy files to container
kubectl cp ./index.html web-app:/usr/share/nginx/html/

Debugging Pods

# Detailed info and events
kubectl describe pod web-app

# Logs
kubectl logs web-app
kubectl logs web-app -f              # Stream logs
kubectl logs web-app --previous      # Previous container's logs
kubectl logs web-app -c log-collector # Specific container's logs

# Resource usage
kubectl top pod web-app

Summary

Concept Description
Pod Smallest deployable unit wrapping one or more containers
Labels Key-value pairs for identifying resources
Resources Manage with requests (guaranteed) and limits (maximum)
Multi-container Pod Sidecar, ambassador, and adapter patterns
Init Container Runs before main containers for initialization
Probes Three types: liveness, readiness, and startup

Key Takeaways

  1. Kubernetes manages Pods, not individual containers. Containers in a Pod share network and storage
  2. Labels are foundational to many Kubernetes features. Design them carefully
  3. Properly configured probes let Kubernetes automatically maintain application health

Practice Exercises

Exercise 1: Basics

Write a YAML manifest for a Pod with:

  • Name: my-app
  • Image: httpd:2.4
  • CPU requests: 50m, limits: 100m
  • Memory requests: 64Mi, limits: 128Mi
  • livenessProbe and readinessProbe (httpGet, port 80)

Exercise 2: Multi-container

Create a Pod with a web server (nginx) and a log-forwarding sidecar (busybox) using a shared volume.

Challenge

Design a Pod with an Init Container that creates a "welcome.html" file before the main nginx container starts, serving that file to visitors.


References


Next up: In Day 4, you'll learn about "ReplicaSets and Deployments." Instead of creating Pods directly, you'll manage them through Deployments.