Table of Contents
- 1. Deployments Overview
- 2. Updates, Rollouts and Rollbacks
- 3. Horizontal Pod Autoscaling (HPA)
- 4. kubectl Quick Reference Commands
- 5. Reference Tables
- 6. Key Concepts Summary
1. Deployments Overview
1.1 Definition and Desired States
A Deployment is a Kubernetes resource that manages the lifecycle of Pods and guarantees that the correct number of replicas is running at all times. It provides a declarative approach to deploying, updating, and scaling applications, while automatically managing failures through self-healing.
The main objectives of a Deployment are:
- Expose containerized workloads to users in a reliable, efficient, and secure manner
- Define everything in a manifest (
deployment.yaml) - Manage rolling updates (gradual transition between versions)
- Manage rollbacks (return to a previous version on failure)
Self-healing: if a Pod fails, the Deployment automatically recreates it to maintain the desired state (
replicas).
1.2 Architecture: Deployment → ReplicaSet → Pod
graph TD
User["User / kubectl"] -->|"kubectl apply -f deployment.yaml"| D
subgraph "Kubernetes Control Plane"
D["Deployment\n(my-app)"]
RS["ReplicaSet\n(my-app-abc123)"]
end
subgraph "Worker Node(s)"
P1["Pod 1\n(my-app-abc123-xxx)"]
P2["Pod 2\n(my-app-abc123-yyy)"]
P3["Pod 3\n(my-app-abc123-zzz)"]
P1 --> C1["Container\n(nginx:1.27)"]
P2 --> C2["Container\n(nginx:1.27)"]
P3 --> C3["Container\n(nginx:1.27)"]
end
D -->|"manages"| RS
RS -->|"maintains replicas: 3"| P1
RS -->|"maintains replicas: 3"| P2
RS -->|"maintains replicas: 3"| P3
Responsibility hierarchy:
| Resource | Responsibility |
|---|---|
| Deployment | Manages update strategy, revision history, rollbacks |
| ReplicaSet | Maintains desired number of identical Pods (auto-created by Deployment) |
| Pod | Execution unit containing one or more containers |
| Container | Application image running inside the Pod |
1.3 Deployment Manifest Structure
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 3 # Desired number of Pods
selector:
matchLabels:
app: my-app # Selects Pods managed by this Deployment
template:
metadata:
labels:
app: my-app # Labels of created Pods
spec:
containers:
- name: my-container
image: nginx:latest # Docker image to use
ports:
- containerPort: 8080 # Port exposed by the container
env:
- name: APP_ENV
value: "production"
- name: LOG_LEVEL
value: "info"
Essential fields:
| Field | Description |
|---|---|
apiVersion: apps/v1 | API version for Deployments |
kind: Deployment | Resource type |
spec.replicas | Number of Pods to maintain |
spec.selector.matchLabels | Link between Deployment and its Pods (must match template labels) |
spec.template | Pod template used to create each replica |
spec.template.spec.containers | Container definitions (image, ports, env vars) |
1.4 Applying and Verifying
# Create or update the Deployment
kubectl apply -f dep1.yaml
# Check Deployment status
kubectl get deployments
# See created Pods
kubectl get pods
# Port-forwarding for local testing
kubectl port-forward pod/<pod-name> 8080:80
# Test from another session
curl localhost:8080
Example kubectl get deployments output:
NAME READY UP-TO-DATE AVAILABLE AGE
my-app 3/3 3 3 2m
| Column | Meaning |
|---|---|
READY | Ready Pods / Desired Pods |
UP-TO-DATE | Pods updated to the latest revision |
AVAILABLE | Pods available to serve traffic |
1.5 When to Use Deployment vs StatefulSet
| Criterion | Deployment | StatefulSet |
|---|---|---|
| Pod identity | Anonymous — all identical | Stable and unique (pod-0, pod-1, pod-2) |
| Storage | Ephemeral / shared | Dedicated Persistent Volume per Pod |
| Use cases | Stateless apps (web APIs, frontends) | Databases, Kafka, Elasticsearch |
| Start order | Random | Sequential and guaranteed |
| Self-healing | Yes | Yes, but preserves identity |
2. Updates, Rollouts and Rollbacks
2.1 Readiness, Liveness and Startup Probes
Probes are health mechanisms Kubernetes uses to automatically monitor each Pod’s state.
Probe Types
| Probe | Trigger | Objective | Action on Failure |
|---|---|---|---|
| startupProbe | Only at startup | Give app time to start before other probes | Kills the container (restart) |
| readinessProbe | Continuously | Check if Pod is ready to receive traffic | Removes Pod from Service (no traffic) |
| livenessProbe | Continuously | Check if app is still alive | Restarts the container |
Verification Methods
# HTTP GET (most common)
httpGet:
path: /health
port: 5000
# TCP Socket
tcpSocket:
port: 8080
# Shell command
exec:
command:
- cat
- /tmp/healthy
Complete Manifest with All 3 Probes
apiVersion: apps/v1
kind: Deployment
metadata:
name: flask-app
spec:
replicas: 3
selector:
matchLabels:
app: flask
template:
metadata:
labels:
app: flask
spec:
containers:
- name: flask-container
image: myrepo/flask-app:latest
ports:
- containerPort: 5000
# Startup probe — active only at boot
startupProbe:
httpGet:
path: /health
port: 5000
failureThreshold: 6 # Allows up to 60s (6 × 10s) to start
periodSeconds: 10
# Readiness probe — controls whether Pod receives traffic
readinessProbe:
httpGet:
path: /health
port: 5000
initialDelaySeconds: 3
periodSeconds: 5
failureThreshold: 2
# Liveness probe — restarts if app is stuck
livenessProbe:
httpGet:
path: /health
port: 5000
initialDelaySeconds: 35 # Waits until recovery is possible
periodSeconds: 10
failureThreshold: 3
Startup Flow with Probes
sequenceDiagram
participant K as Kubernetes
participant P as Pod / Container
participant S as Service (traffic)
K->>P: Start the container
activate P
Note over P: startupProbe active
loop Check every 10s (max 60s)
K->>P: GET /health
P-->>K: 500 Unhealthy (less than 30s)
end
K->>P: GET /health
P-->>K: 200 OK (after 30s)
Note over P: startupProbe succeeds
Note over P: readinessProbe + livenessProbe start
K->>S: Add Pod to Service
activate S
S->>P: User traffic
deactivate S
deactivate P
2.2 Rolling Updates
A Rolling Update progressively replaces old Pods with new ones, ensuring continuous availability. There is no service interruption for users.
Manifest with RollingUpdate Strategy
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Maximum surplus Pods during update
maxUnavailable: 1 # Maximum unavailable Pods during update
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.26 # Change to 1.27 to trigger an update
ports:
- containerPort: 80
Rolling Update Flow (nginx:1.26 to nginx:1.27)
graph LR
subgraph "Step 1 - Initial state"
A1["Pod nginx:1.26"]
A2["Pod nginx:1.26"]
A3["Pod nginx:1.26"]
end
subgraph "Step 2 - Transition (maxSurge=1, maxUnavailable=1)"
B1["Pod nginx:1.26"]
B2["Pod nginx:1.26"]
B3["Pod nginx:1.27 (new)"]
B4["Pod terminating"]
end
subgraph "Step 3 - Final state"
C1["Pod nginx:1.27"]
C2["Pod nginx:1.27"]
C3["Pod nginx:1.27"]
end
A1 --> B1
A2 --> B4
A3 --> B2
B3 -.-> C3
Rollout Management Commands
# Apply the update (change image in YAML, then)
kubectl apply -f deployment.yaml
# Track rollout progress
kubectl rollout status deployment/nginx-deployment
# View revision history
kubectl rollout history deployment/nginx-deployment
# Update image directly via CLI
kubectl set image deployment/nginx-deployment nginx=nginx:1.27
2.3 Rollbacks
If an update fails or causes problems, Kubernetes allows instant return to a previous revision.
graph TD
A["kubectl apply (nginx:1.27)"] --> B["Rolling Update starts"]
B --> C{Are new version Pods healthy?}
C -->|Yes| D["Update complete - Revision 2 active"]
C -->|No - Issue detected| E["kubectl rollout undo"]
E --> F["Kubernetes returns to previous revision (nginx:1.26)"]
F --> G["Revision 1 active - Service restored"]
# Rollback to previous revision
kubectl rollout undo deployment/nginx-deployment
# Rollback to a specific revision
kubectl rollout undo deployment/nginx-deployment --to-revision=1
# View detailed history
kubectl rollout history deployment/nginx-deployment --revision=2
# Annotate a deployment to keep a trace
kubectl annotate deployment/nginx-deployment kubernetes.io/change-cause="Update to nginx 1.27"
Note: Kubernetes retains the last 10 revisions by default (
revisionHistoryLimit: 10). This can be adjusted in the Deployment manifest.
2.4 Deployment Strategies: RollingUpdate vs Recreate
graph LR
subgraph "RollingUpdate"
RU1["v1 active"] --> RU2["v1 + v2 in transition"] --> RU3["v2 active"]
end
subgraph "Recreate"
RC1["v1 active"] --> RC2["Full stop (downtime)"] --> RC3["v2 active"]
end
# Recreate strategy
spec:
strategy:
type: Recreate
# RollingUpdate strategy with percentages
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
| Parameter | Description | Example |
|---|---|---|
maxSurge | Max Pods above replicas count | 1 or 25% |
maxUnavailable | Max unavailable Pods during update | 1 or 25% |
| Criterion | RollingUpdate | Recreate |
|---|---|---|
| Availability | Continuous (zero downtime) | Complete interruption |
| Version coexistence | Yes (transient) | No |
| DB migration | Complex (compatibility required) | Simple |
| Rollback | Automatic and fast | Full redeploy |
| Use case | Production, stateless APIs | Apps with DB schema changes |
3. Horizontal Pod Autoscaling (HPA)
3.1 HPA Principle
The HPA (Horizontal Pod Autoscaler) automatically adjusts the number of Pods in a Deployment, ReplicaSet, or StatefulSet based on observed metrics (CPU, memory, custom metrics).
- Scale up: Adds Pods when resource utilization exceeds the threshold
- Scale down: Removes Pods when demand decreases
3.2 Metrics Server
The HPA depends on the Metrics Server to collect CPU/memory metrics.
# Install Metrics Server (from official GitHub manifest)
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# Verify Metrics Server is active
kubectl get deployment metrics-server -n kube-system
# View Pod metrics
kubectl top pods
kubectl top nodes
3.3 HPA Manifest
Step 1 — Deployment with resource requests/limits:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "50m" # Guaranteed minimum (50 millicores)
memory: "64Mi"
limits:
cpu: "200m" # Maximum allowed
memory: "128Mi"
ports:
- containerPort: 80
Step 2 — Service to expose the Deployment:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: ClusterIP
Step 3 — HPA (autoscaling/v2):
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 2 # Minimum Pods (even at zero load)
maxReplicas: 10 # Maximum allowed Pods
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50 # Scale up if CPU > 50% of request
3.4 HPA Flow
graph TD
MS["Metrics Server\n(collects CPU/memory)"] -->|"metrics every 15s"| HPA
subgraph "HPA Controller"
HPA["HorizontalPodAutoscaler\n(nginx-hpa)\nmin:2 / max:10\ntarget: CPU 50%"]
end
HPA -->|"CPU > 50% - Scale UP"| D
subgraph "Deployment"
D["nginx-deployment"]
D --> RS["ReplicaSet"]
RS --> P1["Pod 1"]
RS --> P2["Pod 2"]
RS -.->|"new Pods created"| P3["Pod 3"]
RS -.-> P4["Pod 4"]
end
LB["Load\n(HTTP requests)"] -->|"high load"| P1
LB --> P2
HPA -->|"CPU below 50% for 5min - Scale DOWN"| D
# Check HPA status
kubectl get hpa
# Full HPA details
kubectl describe hpa nginx-hpa
# View scaling events
kubectl get events --field-selector reason=SuccessfulRescale
Example kubectl get hpa output:
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx-hpa Deployment/nginx-deployment 23%/50% 2 10 2 5m
| Column | Meaning |
|---|---|
TARGETS | Current utilization / target threshold |
MINPODS | Minimum replicas |
MAXPODS | Maximum replicas |
REPLICAS | Current Pod count |
4. kubectl Quick Reference Commands
# --- Deployments ---
kubectl apply -f deployment.yaml # Create/update
kubectl get deployments # List deployments
kubectl describe deployment <name> # Details
kubectl delete deployment <name> # Delete
# --- Rollouts ---
kubectl rollout status deployment/<name> # Track rollout
kubectl rollout history deployment/<name> # View revisions
kubectl rollout undo deployment/<name> # Rollback
kubectl rollout undo deployment/<name> --to-revision=1 # Specific revision
kubectl set image deployment/<name> <container>=<image> # Update image
# --- Scaling ---
kubectl scale deployment/<name> --replicas=5 # Manual scaling
# --- HPA ---
kubectl get hpa # List HPAs
kubectl describe hpa <name> # HPA details
kubectl top pods # Pod resource usage
kubectl top nodes # Node resource usage
# --- Debugging ---
kubectl logs <pod-name> # Pod logs
kubectl exec -it <pod-name> -- bash # Connect to container
kubectl describe pod <pod-name> # Pod details
kubectl get events # Cluster events
5. Reference Tables
Probe Configuration Parameters
| Parameter | Description | Default |
|---|---|---|
initialDelaySeconds | Wait time before first check | 0 |
periodSeconds | Interval between checks | 10 |
timeoutSeconds | Check timeout | 1 |
failureThreshold | Failures before action | 3 |
successThreshold | Successes to consider healthy | 1 |
RollingUpdate Configuration
| Parameter | Description | Default |
|---|---|---|
maxSurge | Max Pods above replicas (int or %) | 25% |
maxUnavailable | Max unavailable Pods (int or %) | 25% |
Common Kubernetes Resources
| Resource | apiVersion | Description |
|---|---|---|
Deployment | apps/v1 | Stateless workload management |
StatefulSet | apps/v1 | Stateful workload with stable identity |
ReplicaSet | apps/v1 | Pod count maintenance (auto-managed by Deployment) |
DaemonSet | apps/v1 | One Pod per Node |
HorizontalPodAutoscaler | autoscaling/v2 | Metrics-based autoscaling |
Pod | v1 (core) | Basic execution unit |
Service | v1 (core) | Network exposure of Pods |
6. Key Concepts Summary
mindmap
root((Kubernetes Deployments))
Desired State
replicas
self-healing
ReplicaSet
YAML Manifest
apiVersion apps/v1
kind Deployment
spec.selector
spec.template
Probes
startupProbe
readinessProbe
livenessProbe
Updates
RollingUpdate
maxSurge
maxUnavailable
Recreate
Rollback
rollout undo
revisionHistoryLimit
Autoscaling HPA
Metrics Server
minReplicas
maxReplicas
CPU Memory target
Essential Points to Remember
-
A Deployment doesn’t manage Pods directly — it creates a ReplicaSet, which manages the Pods. Each update creates a new ReplicaSet.
-
Labels are fundamental — the
spec.selector.matchLabelsmust exactly match thespec.template.metadata.labelsfor the Deployment to find its Pods. -
The RollingUpdate strategy is the default and guarantees zero downtime. The
maxSurgeandmaxUnavailableparameters control the speed and safety of the transition. -
Probes work as a team:
startupProbe: give time at startupreadinessProbe: don’t send traffic until the app is readylivenessProbe: automatically restart if app is stuck
-
HPA requires
resources.requestsdefined in the container to work. Withoutrequests, the Metrics Server cannot calculate the utilization percentage. -
kubectl rollout undois the immediate rollback tool — Kubernetes reactivates the previous ReplicaSet without creating a new revision.
Search Terms
deployments · kubernetes · containers · deployment · hpa · manifest · flow · probes · rollingupdate · commands · configuration · pod · probe · reference · rollbacks · rolling · startup · updates