3.1 Pod Lifecycle, Multi-Container Patterns & Init Containers

Key Takeaways

  • Pods transition through five distinct phases: Pending, Running, Succeeded, Failed, and Unknown, reflected in status conditions such as PodScheduled, Initialized, ContainersReady, and Ready.
  • Init containers execute sequentially to completion before any application containers start; a failed regular init container is retried according to the Pod restartPolicy and prevents app containers from starting.
  • Native sidecar containers (stable since Kubernetes v1.33) are defined in initContainers with restartPolicy: Always, starting before app containers and terminating after them.
  • Three specialized multi-container design patterns—Sidecar (supporting task), Adapter (output standardization), and Ambassador (network proxy)—enable separation of operational concerns.
  • Container health is governed by startupProbe, livenessProbe, and readinessProbe across exec, httpGet, tcpSocket, and gRPC mechanisms, while graceful termination follows a strict sequence governed by terminationGracePeriodSeconds.
Last updated: August 2026

Pod Lifecycle, Multi-Container Patterns & Init Containers

The Pod is the atomic execution unit in Kubernetes. While a Pod can encapsulate a single container, enterprise workloads frequently employ multi-container architectures and complex startup workflows. Mastering the internal phases of a Pod, the sequencing of Init Containers, the implementation of Sidecar, Adapter, and Ambassador patterns, and the tuning of Probes and Lifecycle Hooks is essential for designing resilient applications and acing the Certified Kubernetes Administrator (CKA) exam.


1. Pod Lifecycle Phases and Status Conditions

A Pod's lifecycle is represented by high-level Phases (status.phase) and granular Conditions (status.conditions).

+-----------------------------------------------------------------------------------------+
|                                 POD LIFECYCLE PHASES                                    |
|                                                                                         |
|   +-----------+      +-----------+      +-----------+      +-------------+              |
|   |  Pending  | ---> |  Running  | ---> | Succeeded |  OR  |   Failed    |              |
|   +-----------+      +-----------+      +-----------+      +-------------+              |
|         |                  |                                                            |
|         v                  v                                                            |
|   (Scheduling /      (At least one                                                      |
|    Image Pull /       app container                                                     |
|    Init Containers)   executing)                                                        |
|                                                                                         |
|   * Unknown: Pod state cannot be obtained (typically kubelet communication loss)        |
+-----------------------------------------------------------------------------------------+

The Five Pod Phases

  1. Pending: The Pod manifest has been accepted by the API server and stored in etcd, but one or more containers have not been created. This includes time spent waiting to be scheduled by kube-scheduler, downloading container images over the network, and running initContainers.
  2. Running: The Pod has been bound to a node, all init containers have completed successfully, and at least one application container is running, starting, or restarting.
  3. Succeeded: All containers in the Pod have terminated successfully (exit code 0) and will not restart. This is typical for completed batch Jobs.
  4. Failed: All containers in the Pod have terminated, and at least one container terminated in failure (non-zero exit code) or was stopped by the system (e.g., OOMKilled).
  5. Unknown: The state of the Pod cannot be obtained, typically due to network partitions between the control plane and the node's kubelet.

Detailed Pod Conditions

Conditions provide granular insight into the Pod's progression:

  • PodScheduled: The Pod has been assigned to a target node.
  • Initialized: All init containers have completed successfully.
  • ContainersReady: All containers in the Pod have passed their readiness checks.
  • Ready: The Pod is ready to serve traffic and should be included in the matching Service's Endpoints or EndpointSlices.

Container States & Exit Codes

Within status.containerStatuses, individual containers exist in one of three states:

  • Waiting: Container is blocked from running. Common reasons include:
    • ImagePullBackOff / ErrImagePull: Invalid image name, missing tag, or unauthenticated private registry.
    • CrashLoopBackOff: Application starts but crashes repeatedly; kubelet applies exponential backoff delays (10s, 20s, 40s, up to 5 minutes).
    • CreateContainerConfigError: Missing ConfigMap or Secret referenced by valueFrom without optional: true.
  • Running: Executing without errors.
  • Terminated: Container finished execution. Key exit codes:
    • 0: Clean exit / success.
    • 1 / 2: Application runtime error or unhandled exception.
    • 137 (128 + 9): Killed by SIGKILL—frequently caused by the Linux OOM (Out Of Memory) Killer when memory limit is breached (OOMKilled: true).
    • 143 (128 + 15): Terminated gracefully via SIGTERM.

2. Init Containers & Native Sidecars

Init containers run before application containers and are designed to perform setup tasks, database migrations, configuration seeding, or dependency waiting.

+-----------------------------------------------------------------------------------------+
|                          INIT CONTAINER EXECUTION FLOW                                  |
|                                                                                         |
|   +---------------------+      +---------------------+      +-----------------------+   |
|   | Init Container 1    | ---> | Init Container 2    | ---> | App Containers        |   |
|   | (e.g., wait for DB) |      | (e.g., run schema)  |      | (Start in Parallel)   |   |
|   +---------------------+      +---------------------+      +-----------------------+   |
|        Exit Code 0                  Exit Code 0                  Running / Ready        |
+-----------------------------------------------------------------------------------------+

Execution Rules for Init Containers

  • Sequential Execution: Init containers always run one after another in the exact order defined in the spec.initContainers array.
  • Blocking Nature: Each init container must exit with return code 0 before the next one starts. If an init container fails, kubelet restarts the Pod according to spec.restartPolicy (Always, OnFailure, Never).
  • Resource Allocation: The highest request/limit among init containers is compared against the sum of app container requests/limits; the effective Pod request is the maximum of the two.

Native Sidecar Containers (Stable in Kubernetes v1.33+)

Historically, sidecar containers had to run inside spec.containers, creating race conditions where app containers started before logging or proxy sidecars were ready, and batch jobs hung because sidecars never terminated.

Kubernetes resolved this by introducing Native Sidecars within spec.initContainers by specifying restartPolicy: Always:

apiVersion: v1
kind: Pod
metadata:
  name: native-sidecar-demo
spec:
  initContainers:
    - name: vault-agent-sidecar
      image: hashicorp/vault:1.15.0
      restartPolicy: Always
      command: ["vault", "agent", "-config=/etc/vault/vault-agent-config.hcl"]
      volumeMounts:
        - name: vault-config
          mountPath: /etc/vault
        - name: shared-secrets
          mountPath: /vault/secrets
  containers:
    - name: primary-app
      image: nginx:1.25
      volumeMounts:
        - name: shared-secrets
          mountPath: /etc/secrets
  volumes:
    - name: vault-config
      configMap:
        name: vault-agent-config
    - name: shared-secrets
      emptyDir: {}

[!NOTE] Native sidecars in initContainers start before application containers, keep running throughout the Pod's lifecycle, and do not block Pod termination when application containers finish in batch workloads.


3. Multi-Container Design Patterns

Multi-container Pods share the same network namespace (localhost), IPC namespace, and storage volumes (emptyDir, PVCs).

+-----------------------------------------------------------------------------------------+
|                         MULTI-CONTAINER ARCHITECTURE PATTERNS                           |
|                                                                                         |
|   1. SIDECAR PATTERN             2. ADAPTER PATTERN            3. AMBASSADOR PATTERN    |
|   +-----------------------+      +-----------------------+     +---------------------+  |
|   | [Primary Web App]     |      | [Legacy App]          |     | [Local App]         |  |
|   |         |             |      |         | (raw logs)  |     |         |           |  |
|   |         v (shared log)|      |         v             |     |         v (localhost|  |
|   | [Logging Sidecar]     |      | [Adapter (JSON / Prom)|     | [Ambassador Proxy]  |  |
|   |   (Ship to Fluentd)   |      |   (Expose Metrics)    |     |   (Route DB/Cloud)  |  |
|   +-----------------------+      +-----------------------+     +---------------------+  |
+-----------------------------------------------------------------------------------------+
PatternPrimary PurposeReal-World Example
SidecarEnhances or extends the primary container without modifying its code.Fluentbit log tailer shipping access.log to an Elasticsearch cluster.
AdapterStandardizes and normalizes output or interfaces across heterogeneous applications.Prometheus exporter scraping an app's custom text metrics and converting them to OpenMetrics format.
AmbassadorActs as an out-of-process network proxy, abstracting external connections.Envoy proxy routing traffic to database read-replicas based on write/read query types.

4. Container Health Probes

kubelet monitors container health using three distinct probe types:

+-----------------------------------------------------------------------------------------+
|                                PROBE LIFECYCLE TIMELINE                                 |
|                                                                                         |
|   Container Start                                                                       |
|         |                                                                               |
|         v                                                                               |
|   [startupProbe] ------------------> Holds liveness & readiness probes in check         |
|         |                            until startupProbe succeeds.                       |
|         | (Success)                                                                     |
|         +-------------------+                                                           |
|         |                   |                                                           |
|         v                   v                                                           |
|   [livenessProbe]     [readinessProbe]                                                  |
|         |                   |                                                           |
|   Failure: Kills &    Failure: Removes Pod from Service Endpoints /                     |
|   Restarts Container  EndpointSlices (traffic stops routed to Pod)                      |
+-----------------------------------------------------------------------------------------+

Probe Types and Behavioral Differences

  1. startupProbe: Determines if the application within the container has initialized. All other probes are disabled until startupProbe succeeds. If it fails, the container is killed and restarted. Ideal for legacy applications with slow boot times.
  2. livenessProbe: Determines if the container needs to be restarted. If the liveness probe fails failureThreshold times, kubelet terminates the container and initiates a restart according to restartPolicy. It does not protect against slow database queries—misconfigured liveness probes can cause cascading restart loops.
  3. readinessProbe: Determines if a container is ready to accept incoming network traffic. If it fails, the Pod's IP address is immediately removed from the Endpoints / EndpointSlice of all matching Services. The container is not killed or restarted.

Probe Mechanisms

  • httpGet: Sends an HTTP GET request to a specified port and path. Returns success if HTTP status code is >= 200 and $< 400$.
  • tcpSocket: Attempts to open a TCP connection to the specified container port. Success if socket opens.
  • exec: Runs a command inside the container. Success if command exits with status code 0.
  • grpc: Issues a standard gRPC Health Checking Protocol request (grpc.health.v1.HealthCheckRequest).
spec:
  containers:
    - name: api-server
      image: registry.example.com/api:v2.1
      ports:
        - containerPort: 8080
      startupProbe:
        httpGet:
          path: /healthz/startup
          port: 8080
        failureThreshold: 30
        periodSeconds: 10
      livenessProbe:
        httpGet:
          path: /healthz/liveness
          port: 8080
        initialDelaySeconds: 15
        periodSeconds: 10
        timeoutSeconds: 3
        failureThreshold: 3
      readinessProbe:
        httpGet:
          path: /healthz/readiness
          port: 8080
        periodSeconds: 5
        successThreshold: 1
        failureThreshold: 2

[!IMPORTANT] Probe Tuning Parameters:

  • initialDelaySeconds: Seconds to wait after container start before probing.
  • periodSeconds: Frequency of the probe in seconds (default: 10).
  • timeoutSeconds: Timeout before the probe is considered failed (default: 1).
  • failureThreshold: Consecutive failures required to trigger action (default: 3).
  • successThreshold: Consecutive successes required to regain healthy state (default: 1; must be 1 for liveness and startup).

5. Lifecycle Hooks and Graceful Termination

Kubernetes provides two container lifecycle hooks executed by kubelet:

  1. postStart: Executes immediately after the container is created. It runs asynchronously with the container's entrypoint; however, the container status will not be marked as Running until postStart completes.
  2. preStop: Executes synchronously before the container is sent a SIGTERM signal. If preStop hangs, it runs until the terminationGracePeriodSeconds expires.
spec:
  terminationGracePeriodSeconds: 60
  containers:
    - name: web
      image: nginx:alpine
      lifecycle:
        preStop:
          exec:
            command: ["/bin/sh", "-c", "nginx -s quit; sleep 15"]

The Pod Graceful Termination Sequence

When a Pod is deleted (kubectl delete pod <name>):

  1. API Server updates Pod state: Deletion timestamp is recorded; Pod enters Terminating state.
  2. EndpointSlice controller deregisters Pod: The Pod's IP is removed from Service endpoints; kube-proxy updates iptables/IPVS rules to stop sending new traffic.
  3. preStop hook executes: Container runs the defined cleanup command.
  4. SIGTERM sent: kubelet sends SIGTERM (signal 15) to PID 1 inside each container.
  5. Grace period countdown: kubelet waits for terminationGracePeriodSeconds (default: 30s).
  6. SIGKILL sent: If containers are still running after the grace period expires, kubelet immediately sends SIGKILL (signal 9) to terminate all processes.
Loading diagram...
Pod Startup, Probe Evaluation & Termination Lifecycle
Test Your Knowledge

A production backend Pod running an e-commerce API is frequently restarting with exit code 137. Inspection via 'kubectl describe pod' indicates Last State: Terminated with Reason: OOMKilled. What is the root cause and the appropriate administrative remediation?

A
B
C
D
Test Your Knowledge

An administrator configures a multi-container Pod with an init container designed to perform database migrations and an application container. The init container script encounters a syntax error and exits with code 1. If the Pod has restartPolicy: OnFailure, what will happen?

A
B
C
D
Test Your Knowledge

Which of the following scenarios describes the precise difference between a failed livenessProbe and a failed readinessProbe?

A
B
C
D