Kubernetes provides multiple workload objects, each designed for a specific type of application. Choosing the right workload type is one of the first decisions you make when deploying to Kubernetes.
Pods
A Pod is the smallest and most basic unit in Kubernetes. It represents one or more containers that:
- Are always co-located on the same node
- Share the same network namespace (same IP, same ports)
- Share the same storage volumes
Most Pods contain a single container. Multi-container Pods are used for sidecar patterns (logging agent, proxy).
apiVersion: v1
kind: Pod
metadata:
name: my-app
labels:
app: my-app
spec:
containers:
- name: app
image: nginx:alpine
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Pods are ephemeral — they are not restarted if deleted. For persistent workloads, use higher-level controllers.
ReplicaSet
A ReplicaSet ensures a specified number of identical Pod replicas are running at all times. If a Pod fails, the ReplicaSet creates a replacement. In practice, you rarely create ReplicaSets directly — Deployments manage them for you.
Deployment
A Deployment is the standard way to run stateless applications. It manages a ReplicaSet and adds:
- Rolling updates: Replace old Pods with new ones gradually (zero downtime by default)
- Rollback:
kubectl rollout undoto revert to the previous version - Scaling:
kubectl scaleto adjust replica count
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:v2
ports:
- containerPort: 3000
kubectl apply -f deployment.yaml
kubectl rollout status deployment/my-app
kubectl rollout undo deployment/my-app
kubectl scale deployment/my-app --replicas=5
StatefulSet
StatefulSets are for stateful applications — primarily databases. Unlike Deployments, StatefulSets provide:
- Stable, unique Pod names (
mysql-0,mysql-1) - Stable network identities (DNS:
mysql-0.mysql) - Ordered, graceful deployment and scaling
- Persistent volumes that survive Pod rescheduling
Use StatefulSets for: MySQL, PostgreSQL, Cassandra, Kafka, Elasticsearch, ZooKeeper.
DaemonSet
A DaemonSet ensures that one Pod runs on every node in the cluster (or a subset of nodes). When a new node joins the cluster, the DaemonSet Pod is automatically scheduled there.
Use DaemonSets for: log collectors (Fluentd, Filebeat), monitoring agents (Prometheus Node Exporter, Datadog), CNI plugins.
Job and CronJob
A Job creates one or more Pods that run until a task completes successfully:
apiVersion: batch/v1
kind: Job
metadata:
name: db-migration
spec:
template:
spec:
containers:
- name: migrate
image: my-app:v2
command: ["npm", "run", "migrate"]
restartPolicy: OnFailure
A CronJob creates Jobs on a schedule (cron syntax):
apiVersion: batch/v1
kind: CronJob
metadata:
name: cleanup
spec:
schedule: "0 2 * * *" # 2am daily
jobTemplate:
spec:
template:
spec:
containers:
- name: cleanup
image: my-app:latest
command: ["node", "cleanup.js"]
restartPolicy: OnFailure
Horizontal Pod Autoscaler (HPA)
HPA automatically scales the number of Pod replicas based on CPU utilisation (or custom metrics):
kubectl autoscale deployment my-app --cpu-percent=70 --min=2 --max=10
Next: how Pods communicate with each other and with the outside world through Services and Ingress.