3.1 Core Workload Objects (Pods, Deployments & ReplicaSets)
Key Takeaways
- A Pod is the smallest execution unit in Kubernetes, wrapping one or more containers that share network namespaces (IP address and port space) and storage volumes.
- Multi-container Pod patterns include Sidecar containers (auxiliary tasks like logging or proxying) and Init containers (run sequentially to completion before app containers start).
- ReplicaSets maintain a specified replica count of identical Pods using declarative label selectors (matchLabels and matchExpressions) to ensure high availability and self-healing.
- Deployments provide declarative state management over ReplicaSets, enabling automated rolling updates (maxSurge, maxUnavailable), zero-downtime upgrades, revision tracking, and rollbacks.
- kubectl rollout undo allows reverting a Deployment to a previous revision, leveraging underlying ReplicaSet revision history preserved by Kubernetes.
3.1 Core Workload Objects (Pods, Deployments & ReplicaSets)
In Kubernetes, applications are rarely deployed as bare, standalone containers. Instead, Kubernetes abstracts containerized software into structured workload API objects. Understanding the fundamental workload primitives—Pods, ReplicaSets, and Deployments—is central to mastering Kubernetes architecture and passing the KCNA exam.
1. Pod Anatomy & Shared Namespaces
A Pod is the basic building block of Kubernetes—the smallest and simplest deployable object in the Kubernetes object model. A Pod represents a single instance of a running process in your cluster and wraps one or more containers (such as Docker or containerd containers).
The Single-Container vs. Multi-Container Pod
In the vast majority of cloud-native use cases, Pods follow a single-container pattern, where one Pod encapsulates a single application process (e.g., a Python web server or a Go microservice). However, Kubernetes explicitly supports multi-container Pods, where two or more tightly coupled containers share resources and lifetime.
When containers are co-located within the same Pod, Kubernetes configures them to share critical Linux kernel namespaces:
- Shared Network Namespace: All containers in a Pod share the same network stack, IP address, network interface, and port space. Containers within the same Pod can communicate with each other over
localhost(using IPC or loopback networking). - Shared Storage Volumes: Pods can define shared storage volumes mounted into the filesystem of each container, enabling high-speed local file sharing between containers.
- Shared Lifecycle: All containers in a Pod are scheduled onto the same worker node, started together, and terminated together.
[!NOTE] Because containers inside a single Pod share the same network namespace, two containers in the same Pod cannot bind to the same network port (e.g., both trying to listen on port
8080), or a port conflict will occur.
2. Multi-Container Pod Patterns
When building complex container workloads, multi-container Pods utilize standardized design patterns to extend application functionality without mutating the primary application container image.
The Sidecar Pattern
A Sidecar container runs alongside the primary application container within the same Pod. Its purpose is to enhance, protect, or extend the primary container without changing its core source code. Common sidecar examples include:
- Log Collectors: A sidecar tailing local log files generated by the app container and streaming them to centralized storage (e.g., Fluentd or Vector).
- Service Mesh Proxies: A sidecar proxying network traffic for security and telemetry (e.g., Envoy in an Istio service mesh).
- Configuration Refreshers: A sidecar monitoring external secrets vaults and updating local config files.
Init Containers
Init containers are specialized containers that run to completion before standard application containers are started. A Pod can have multiple init containers, which execute sequentially in the exact order defined in the YAML manifest.
Key characteristics of Init containers include:
- They always run to completion before the next init container or application container starts.
- If an init container fails, Kubernetes restarts the Pod repeatedly until the init container succeeds (governed by the Pod's
restartPolicy). - They are commonly used for setup tasks, such as populating database schemas, generating cryptographic certificates, or waiting for a dependency service to become reachable over the network.
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app.kubernetes.io/name: myapp
spec:
initContainers:
- name: init-myservice
image: busybox:1.36
command: ['sh', '-c', 'until nc -z -w 2 myservice 6379; do echo waiting for redis; sleep 2; done']
containers:
- name: myapp-container
image: nginx:1.25
ports:
- containerPort: 80
- name: log-sidecar
image: busybox:1.36
command: ['sh', '-c', 'tail -n+1 -F /var/log/nginx/access.log']
3. ReplicaSets: Ensuring Pod Replication
While you can create individual Pods directly in Kubernetes, doing so creates naked Pods. If the underlying worker node fails, naked Pods are not rescheduled or recovered. To ensure resilience and scalability, Kubernetes uses controllers to manage Pod lifecycles.
A ReplicaSet is a controller whose primary purpose is to maintain a stable set of identical, running Pod replicas at any given time. It guarantees the availability of a specified number of Pods.
Label Selectors
ReplicaSets locate the Pods they are responsible for managing through Label Selectors. Rather than tracking Pods by direct name, a ReplicaSet queries Pod labels in the cluster using two selector forms:
- matchLabels: Simple key-value equality matching (e.g.,
app: frontend). - matchExpressions: Advanced set-based filtering (e.g.,
environment in (production, staging)).
If a Pod managed by a ReplicaSet crashes or its node dies, the ReplicaSet controller detects that the current count of matching Pods is below the desired replicas count and automatically provisions a new Pod from its embedded template spec.
4. Deployments: Declarative Updates & Rollbacks
In modern production environments, operators rarely manage ReplicaSets directly. Instead, they use Deployments. A Deployment is a higher-level declarative object that manages ReplicaSets underneath, providing declarative updates for Pods and ReplicaSets.
+-------------------------------------------------------+
| Deployment |
+-------------------------------------------------------+
|
v
+-------------------------------------------------------+
| ReplicaSet (Revision 2) |
+-------------------------------------------------------+
| | |
v v v
+---------+ +---------+ +---------+
| Pod | | Pod | | Pod |
+---------+ +---------+ +---------+
Rolling Updates & Rollback Mechanics
When you modify a Deployment's Pod template (e.g., updating the container image version), the Deployment controller creates a new ReplicaSet and performs a Rolling Update. It gradually scales up the new ReplicaSet while scaling down the old ReplicaSet, ensuring zero application downtime.
Rolling updates are controlled by two key parameters under spec.strategy.rollingUpdate:
- maxSurge: The maximum number (or percentage) of Pods that can be created above the desired replica count during an update (e.g.,
25%). - maxUnavailable: The maximum number (or percentage) of Pods that can be unavailable during the update process (e.g.,
25%).
Revision History & Rollbacks
Kubernetes tracks Deployment updates by saving past ReplicaSets as revision history. If a new deployment fails (e.g., due to a broken image tag or crash-looping code), you can instantly revert to a previous working state:
# Check rollout history
kubectl rollout history deployment/web-app
# Rollback to the immediate previous revision
kubectl rollout undo deployment/web-app
# Rollback to a specific historical revision
kubectl rollout undo deployment/web-app --to-revision=2
5. Workload Comparison Summary
| Feature | Pod | ReplicaSet | Deployment |
|---|---|---|---|
| Abstraction Level | Low (Basic unit) | Medium (Replication) | High (Workload lifecycle) |
| Self-Healing | No (Naked Pod) | Yes (Maintains count) | Yes (Via ReplicaSets) |
| Rolling Updates | No | No | Yes (Automated zero-downtime) |
| Revision History | No | No | Yes (Undo/rollback supported) |
| Direct Usage | Testing / One-off | Rare (Managed by Deployment) | Primary production pattern |
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend-deployment
labels:
app: frontend
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: nginx
image: nginx:1.25.3
ports:
- containerPort: 80
A ReplicaSet is managing three Pods when one of its worker nodes fails. What does the ReplicaSet controller do?
Which multi-container Pod pattern involves a secondary container that runs to completion before application containers start?
How does a Deployment controller execute a rolling update without causing downtime?