Kubernetes Pods and Workloads
Supported Versions: Kubernetes 1.32, 1.33, 1.34 Last Updated: February 23, 2026
This document provides a detailed explanation of Pods, the basic execution unit in Kubernetes, and the various workload resources that manage them. Starting from the concept of Pods, we'll cover the characteristics and use cases of various workload resources including Deployments, StatefulSets, DaemonSets, and more.
Lab Environment Setup
To follow the examples in this document, you'll need the following tools and environment:
Required Tools
- kubectl v1.34 or higher
- A working Kubernetes cluster (EKS, minikube, kind, etc.)
Deploy Example Application
# Create namespace
kubectl create namespace workloads-demo
# Create a simple deployment
kubectl -n workloads-demo apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "200m"
EOF
# Check deployment status
kubectl -n workloads-demo get deployments,podsTable of Contents
- Pod Concepts
- Pod Lifecycle
- Pod Design Patterns
- Workload Resources Overview
- ReplicaSet
- Deployment
- StatefulSet
- DaemonSet
- Jobs and CronJobs
- Resource Management
- Pod Disruption Budget
- Horizontal Pod Autoscaling
- Vertical Pod Autoscaling
- Workload Best Practices
- Amazon EKS Workload Considerations
Pod Concepts
Key Concept: A Pod is the smallest deployable computing unit in Kubernetes, consisting of one or more container groups that share storage and network.
A Pod is the smallest deployable computing unit in Kubernetes. A Pod is a group of one or more containers that share storage and network and are scheduled together.
Pod Characteristics
- Shared Context: All containers within a Pod share the same network namespace, IPC namespace, and UTS namespace.
- Same Node: All containers in a Pod always run on the same node.
- Unique IP Address: Each Pod has a unique IP address within the cluster.
- Ephemeral: Pods are fundamentally ephemeral and can be replaced by new Pods in case of failure.
- Atomic Unit: Pods are the atomic unit of deployment, scheduling, and replication.
Pod Structure
A Pod consists of the following components:
- Containers: One or more containers running within the Pod
- Volumes: Storage shared by containers within the Pod
- Network: IP address and ports assigned to the Pod
- Container Spec: Container image, environment variables, resource requirements, etc.
Pod Example
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.21
ports:
- containerPort: 80
volumeMounts:
- name: shared-data
mountPath: /usr/share/nginx/html
- name: content-updater
image: alpine
command: ["/bin/sh", "-c"]
args:
- while true; do
echo "Current time: $(date)" > /content/index.html;
sleep 10;
done
volumeMounts:
- name: shared-data
mountPath: /content
volumes:
- name: shared-data
emptyDir: {}Practical Example: Web Application Pod
The following is an example of a Pod containing a web application and sidecar container:
apiVersion: v1
kind: Pod
metadata:
name: web-app
labels:
app: web
environment: production
spec:
containers:
- name: web-application
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
- name: log-collector
image: fluentd:v1.14
volumeMounts:
- name: log-volume
mountPath: /var/log/nginx
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
volumes:
- name: log-volume
emptyDir: {}This example demonstrates the following real-world scenario:
- Running Nginx web server as the main container
- Running Fluentd log collector as a sidecar container
- Sharing log volume between two containers
- Setting resource requests and limits for each container
This configuration is suitable for running closely connected containers while separating functionality such as logging, monitoring, and proxying in microservice architectures. classDef k8sComponent fill:#326CE5,stroke:#333,stroke-width:1px,color:white; classDef userApp fill:#00C7B7,stroke:#333,stroke-width:1px,color:white; classDef dataStore fill:#3B48CC,stroke:#333,stroke-width:1px,color:white; classDef default fill:#f9f9f9,stroke:#333,stroke-width:1px,color:black;
%% Apply classes
class Pod default;
class Container1,Container2 userApp;
class Volume dataStore;
class IP default;
### Pod Definition
Pods are defined using manifest files in YAML or JSON format. Here's a basic Pod definition example:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"Single Container vs Multi-Container Pods
Single Container Pods:
- Most common use case
- Contains only one application container
- Simple and intuitive structure
Multi-Container Pods:
- Contains multiple tightly coupled containers
- Local communication between containers possible (localhost)
- Data sharing through shared volumes
- Scaled and placed together
Multi-Container Pod Patterns
- Sidecar Pattern: Auxiliary container that extends the functionality of the main container
- Examples: log collector, file synchronization, proxy
apiVersion: v1
kind: Pod
metadata:
name: web-with-sidecar
spec:
containers:
- name: web
image: nginx:1.21
- name: log-collector
image: fluentd:v1.14
volumeMounts:
- name: logs
mountPath: /var/log/nginx
volumes:
- name: logs
emptyDir: {}- Ambassador Pattern: Container that acts as a proxy to external services
- Examples: database proxy, service mesh sidecar
apiVersion: v1
kind: Pod
metadata:
name: app-with-ambassador
spec:
containers:
- name: app
image: myapp:1.0
- name: ambassador
image: envoy:v1.20
ports:
- containerPort: 9901- Adapter Pattern: Container that standardizes the output of the main container
- Examples: log format conversion, metrics conversion
apiVersion: v1
kind: Pod
metadata:
name: app-with-adapter
spec:
containers:
- name: app
image: myapp:1.0
- name: adapter
image: adapter:1.0
volumeMounts:
- name: app-logs
mountPath: /var/log/app
volumes:
- name: app-logs
emptyDir: {}- Init Container Pattern: Container that runs before the main container starts
- Examples: configuration file creation, database migration, permission setup
apiVersion: v1
kind: Pod
metadata:
name: app-with-init
spec:
initContainers:
- name: init-db
image: busybox:1.34
command: ['sh', '-c', 'until nslookup db; do echo waiting for db; sleep 2; done;']
containers:
- name: app
image: myapp:1.0Pod Networking
Containers within a Pod have the following networking characteristics:
- Same IP Address: All containers within a Pod share the same IP address.
- Port Sharing: Containers within a Pod share the port space, so they cannot use the same port.
- Localhost Communication: Containers within a Pod can communicate with each other via localhost.
- Inter-Pod Communication: Each Pod has a unique IP address and can communicate directly with other Pods.
Pod Storage
Pods can use various types of volumes to store and share data:
- emptyDir: Temporary volume created when the Pod is created and deleted when the Pod is deleted
- hostPath: Volume mounted from the host node's file system to the Pod
- persistentVolumeClaim: Volume requesting persistent storage
- configMap: ConfigMap mounted as a volume
- secret: Secret mounted as a volume
- projected: Multiple volume sources mapped to the same directory
apiVersion: v1
kind: Pod
metadata:
name: pod-with-volumes
spec:
containers:
- name: app
image: myapp:1.0
volumeMounts:
- name: data
mountPath: /data
- name: config
mountPath: /etc/config
volumes:
- name: data
emptyDir: {}
- name: config
configMap:
name: app-configPod Lifecycle
Pods go through various lifecycle stages from creation to termination. Understanding this lifecycle is important for ensuring application stability and availability.
Pod Phases
Pods go through the following phases:
- Pending: The Pod has been accepted by the cluster, but one or more containers have not yet been set up
- Running: The Pod has been bound to a node, all containers have been created, and at least one container is running or starting/restarting
- Succeeded: All containers in the Pod have terminated successfully and will not be restarted
- Failed: All containers in the Pod have terminated, and at least one container has terminated in failure
- Unknown: The state of the Pod could not be obtained for some reason
Container States
Each container within a Pod can have the following states:
- Waiting: State before the container is running (downloading image, waiting for dependencies, etc.)
- Running: Container is running without issues
- Terminated: Container has completed execution or failed for some reason
Pod Conditions
Pods indicate their state more specifically through the following conditions:
- PodScheduled: Whether the Pod has been scheduled to a node
- ContainersReady: Whether all containers in the Pod are ready
- Initialized: Whether all init containers have successfully completed
- Ready: Whether the Pod can handle requests and can be added to the load balancing pool of services
Container Probes
Kubernetes provides the following probes to check container status:
- livenessProbe: Checks if the container is alive; restarts the container on failure
- readinessProbe: Checks if the container is ready to handle requests; excludes from service traffic on failure
- startupProbe: Checks if the application within the container has started; disables other probes until successful
apiVersion: v1
kind: Pod
metadata:
name: pod-with-probes
spec:
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
startupProbe:
httpGet:
path: /startup
port: 8080
failureThreshold: 30
periodSeconds: 10Pod Termination Process
When a Pod is terminated, the following process occurs:
- Deletion Request to API Server: User or controller requests Pod deletion
- Termination Period Starts: Default termination period (30 seconds) is set
- API Update: API server updates the Pod's deletion timestamp
- Removal from Service: Endpoint controller removes the Pod from service endpoints
- SIGTERM Signal: kubelet sends SIGTERM signal to containers
- Graceful Shutdown Wait: Time is provided for applications to shut down gracefully
- SIGKILL Signal: If containers don't terminate after the termination period, SIGKILL signal is sent
- Resource Cleanup: kubelet cleans up Pod resources
Init Containers
Init containers are special containers that run before the app containers in a Pod start:
- Sequential Execution: Init containers run one at a time in the order they are defined
- Prerequisite: Each init container starts only after the previous container has successfully completed
- Restart on Failure: If an init container fails, it restarts according to the Pod's restart policy
- Purpose: Setup before app container starts, dependency verification, permission setup, etc.
apiVersion: v1
kind: Pod
metadata:
name: init-pod
spec:
initContainers:
- name: init-myservice
image: busybox:1.34
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
- name: init-mydb
image: busybox:1.34
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
containers:
- name: app
image: myapp:1.0Pod Disruption
Pod disruptions can be divided into voluntary or involuntary disruptions:
Voluntary Disruptions: Disruptions by cluster administrators or automation tools
- Node draining
- Deployment updates
- Pod deletion
Involuntary Disruptions: Disruptions due to hardware failures, kernel panics, network partitions, etc.
PodDisruptionBudget can ensure minimum availability during voluntary disruptions.
Pod Design Patterns
There are several patterns and best practices to consider when designing Pods. Understanding and applying these patterns can improve application stability, scalability, and maintainability.
Single Responsibility Principle
Pods should follow the Single Responsibility Principle:
- One Primary Function: Each Pod should be responsible for one primary function or process
- Independent Scaling: Design so that each function can scale independently
- Separate Lifecycle: Design so that each function can have its own lifecycle
Pod Templates
Pod templates are specifications used to create Pods in workload resources (Deployments, StatefulSets, etc.):
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template: # Pod template starts
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
# Pod template endsPod Affinity and Anti-Affinity
Pod affinity and anti-affinity are rules that control which nodes Pods are scheduled on:
- Pod Affinity: Schedule on the same node or topology domain as specific Pods
- Pod Anti-Affinity: Schedule on a different node or topology domain than specific Pods
apiVersion: v1
kind: Pod
metadata:
name: web-pod
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- cache
topologyKey: "kubernetes.io/hostname"
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- web
topologyKey: "kubernetes.io/hostname"
containers:
- name: web
image: nginx:1.21Node Affinity
Node affinity is a rule that restricts Pods to be scheduled on specific nodes:
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: gpu
operator: In
values:
- "true"
containers:
- name: gpu-container
image: gpu-app:1.0Taints and Tolerations
Taints are applied to nodes to prevent certain Pods from being scheduled, and tolerations are applied to Pods to allow scheduling on nodes with taints:
# Apply taint to node
kubectl taint nodes node1 key=value:NoSchedule
# Apply toleration to Pod
apiVersion: v1
kind: Pod
metadata:
name: tolerant-pod
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
containers:
- name: app
image: myapp:1.0Resource Requests and Limits
Setting resource requests and limits for containers in Pods is important for efficient cluster resource usage and ensuring stability:
apiVersion: v1
kind: Pod
metadata:
name: resource-pod
spec:
containers:
- name: app
image: myapp:1.0
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"Pod Security Context
Security context defines security settings at the Pod or container level:
apiVersion: v1
kind: Pod
metadata:
name: security-pod
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: app
image: myapp:1.0
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALLPod Priority and Preemption
Pod priority and preemption determine which Pods are scheduled and which are preempted when cluster resources are insufficient:
# Priority class definition
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for critical pods only."
# Pod using priority class
apiVersion: v1
kind: Pod
metadata:
name: high-priority-pod
spec:
priorityClassName: high-priority
containers:
- name: app
image: myapp:1.0Workload Resources Overview
Kubernetes provides various workload resources to manage Pods. Each workload resource is designed for specific use cases and requirements.
Workload Resource Types
The main workload resources in Kubernetes are:
- ReplicaSet: Maintains a specified number of Pod replicas
- Deployment: Manages ReplicaSets to provide declarative updates
- StatefulSet: Resource for applications requiring state persistence
- DaemonSet: Runs a copy of a Pod on all nodes
- Job: One-time tasks that terminate after completion
- CronJob: Runs Jobs periodically on a schedule
Workload Resource Selection Criteria
Criteria for selecting the appropriate workload resource:
- State Persistence: Whether the application needs to maintain state
- Execution Pattern: Whether it runs continuously, one-time, or periodically
- Deployment Requirements: Requirements for rolling updates, blue/green deployments, etc.
- Node Coverage: Whether it needs to run on all nodes
- Scalability Requirements: Whether horizontal scaling is needed
ReplicaSet
A ReplicaSet ensures that a specified number of Pod replicas are always running. If Pods fail or are deleted, the ReplicaSet automatically creates replacement Pods.
Main Features of ReplicaSet
- Maintain Pod Replicas: Maintains the specified number of Pod replicas
- Pod Selection: Identifies Pods to manage through label selectors
- Pod Creation: Creates new Pods when necessary
- Pod Deletion: Deletes excess Pods
ReplicaSet Definition
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 80ReplicaSet Operation
- Label Selector Matching: ReplicaSet identifies Pods matching the label selector
- Check Current State: Verifies the number of currently running Pods
- Compare with Desired State: Compares current Pod count with desired replica count
- Adjustment Actions: Creates or deletes Pods as needed
ReplicaSet vs Replication Controller
ReplicaSet is the successor to Replication Controller and provides more powerful label selectors:
- Replication Controller: Supports only equality-based selectors (e.g., app=nginx)
- ReplicaSet: Supports set-based selectors (e.g., app in (nginx, apache))
ReplicaSet Use Cases
ReplicaSets are generally used indirectly through Deployments rather than directly. However, they can be used directly in the following cases:
- Simple Replication: When simply maintaining Pod replicas
- Custom Updates: When custom update mechanisms are needed
- Legacy Support: Supporting legacy applications
Deployment
A Deployment manages ReplicaSets to provide declarative updates for Pods. Deployments manage rolling updates, rollbacks, scaling, and more for applications.
Main Features of Deployment
- Declarative Updates: Declare the desired state and Deployment changes current state to desired state
- Rolling Updates: Update applications without downtime
- Rollback: Easy rollback to previous versions
- Scaling: Adjust the number of application replicas
- Deployment History: Maintain records of previous deployment versions
Deployment Definition
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 100Mi
limits:
cpu: 200m
memory: 200Mi
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5Deployment Update Strategies
Deployments provide two update strategies:
RollingUpdate: Gradually updates Pods for deployment without downtime (default)
- maxSurge: Maximum number of Pods that can be created above the desired Pod count
- maxUnavailable: Maximum number of Pods unavailable during update
Recreate: Deletes all existing Pods before creating new Pods (causes temporary downtime)
Deployment Rollback
Deployments support rollback to previous versions:
# Check deployment history
kubectl rollout history deployment/nginx-deployment
# Check details of specific version
kubectl rollout history deployment/nginx-deployment --revision=2
# Rollback to previous version
kubectl rollout undo deployment/nginx-deployment
# Rollback to specific version
kubectl rollout undo deployment/nginx-deployment --to-revision=2Deployment Scaling
Deployments can be easily scaled:
# Imperative scaling
kubectl scale deployment/nginx-deployment --replicas=5
# Declarative scaling (after modifying YAML file)
kubectl apply -f deployment.yamlDeployment Pause and Resume
Deployment rollouts can be paused and resumed:
# Pause rollout
kubectl rollout pause deployment/nginx-deployment
# Apply multiple changes
kubectl set image deployment/nginx-deployment nginx=nginx:1.22
kubectl set resources deployment/nginx-deployment -c=nginx --limits=cpu=200m,memory=256Mi
# Resume rollout
kubectl rollout resume deployment/nginx-deploymentDeployment Status
Deployments can have the following statuses:
- Progressing: New ReplicaSet is being created or scaling up/down
- Complete: All replicas have been updated and are available
- Failed: Error occurred during deployment (e.g., image pull failure, insufficient resources)
StatefulSet
StatefulSet is a workload resource for applications that require state persistence. It assigns unique identifiers to each Pod and provides stable network identifiers and persistent storage.
Main Features of StatefulSet
- Stable and Unique Network Identifiers: Pod names and hostnames are maintained even after restarts
- Stable and Persistent Storage: Access to the same storage even when Pods are rescheduled
- Sequential Deployment and Scaling: Pods are created, updated, and deleted in order
- Sequential Automatic Rolling Updates: Pods are updated in order
StatefulSet Definition
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 3
updateStrategy:
type: RollingUpdate
podManagementPolicy: OrderedReady
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "standard"
resources:
requests:
storage: 1GiStatefulSet Pod Identifiers
StatefulSet assigns unique identifiers to Pods in the following format:
<StatefulSet name>-<ordinal index>For example, a web StatefulSet creates Pods like web-0, web-1, web-2.
StatefulSet Headless Service
StatefulSets are typically used with a headless service (clusterIP: None). This creates DNS records for each Pod:
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginxWith this, each Pod has a DNS name in the following format:
<Pod name>.<service name>.<namespace>.svc.cluster.localExample: web-0.nginx.default.svc.cluster.local
StatefulSet Storage
StatefulSets use volumeClaimTemplates to automatically create Persistent Volume Claims (PVCs) for each Pod. These PVCs are maintained even when Pods are rescheduled.
StatefulSet Update Strategies
StatefulSets provide two update strategies:
- RollingUpdate: Updates Pods in order (default)
- OnDelete: Updates only when Pods are deleted
Pod Management Policy
StatefulSets provide two Pod management policies:
- OrderedReady: Creates and terminates Pods in order (default)
- Parallel: Creates and terminates Pods in parallel
StatefulSet Use Cases
StatefulSets are suitable for the following applications:
- Databases: MySQL, PostgreSQL, MongoDB, etc.
- Distributed Systems: Kafka, ZooKeeper, Elasticsearch, etc.
- Message Queues: RabbitMQ, etc.
- Other Stateful Applications: File servers, session stores, etc.
StatefulSet Example: MySQL Replication
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
ports:
- port: 3306
name: mysql
clusterIP: None
selector:
app: mysql
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
serviceName: mysql
replicas: 3
template:
metadata:
labels:
app: mysql
spec:
initContainers:
- name: init-mysql
image: mysql:5.7
command:
- bash
- "-c"
- |
set -ex
# Generate server ID based on Pod index
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
echo [mysqld] > /mnt/conf.d/server-id.cnf
echo server-id=$((100 + $ordinal)) >> /mnt/conf.d/server-id.cnf
# Master or slave configuration
if [[ $ordinal -eq 0 ]]; then
echo [mysqld] > /mnt/conf.d/master.cnf
echo log-bin=mysql-bin >> /mnt/conf.d/master.cnf
else
echo [mysqld] > /mnt/conf.d/slave.cnf
echo super-read-only >> /mnt/conf.d/slave.cnf
fi
volumeMounts:
- name: conf
mountPath: /mnt/conf.d
- name: clone-mysql
image: gcr.io/google-samples/xtrabackup:1.0
command:
- bash
- "-c"
- |
set -ex
# Only perform replication if not the first Pod
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
if [[ $ordinal -eq 0 ]]; then
exit 0
fi
# Replicate data from previous Pod
ncat --recv-only mysql-$(($ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
# Prepare backup
xtrabackup --prepare --target-dir=/var/lib/mysql
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
ports:
- name: mysql
containerPort: 3306
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
resources:
requests:
cpu: 500m
memory: 1Gi
livenessProbe:
exec:
command: ["mysqladmin", "ping"]
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
exec:
command: ["mysql", "-h", "127.0.0.1", "-e", "SELECT 1"]
initialDelaySeconds: 5
periodSeconds: 2
timeoutSeconds: 1
- name: xtrabackup
image: gcr.io/google-samples/xtrabackup:1.0
ports:
- name: xtrabackup
containerPort: 3307
command:
- bash
- "-c"
- |
set -ex
cd /var/lib/mysql
# Start slave
if [[ -f xtrabackup_slave_info ]]; then
cat xtrabackup_slave_info | sed -E 's/;$//g' > change_master_to.sql
mysql -h 127.0.0.1 -e "$(cat change_master_to.sql); RESET SLAVE; START SLAVE;"
# If replicated from master
elif [[ -f xtrabackup_binlog_info ]]; then
[[ `hostname` =~ -([0-9]+)$ ]] || exit 1
ordinal=${BASH_REMATCH[1]}
[[ $ordinal -eq 0 ]] && exit 0
master_host=mysql-0.mysql
master_log_file=$(cat xtrabackup_binlog_info | awk '{print $1}')
master_log_pos=$(cat xtrabackup_binlog_info | awk '{print $2}')
mysql -h 127.0.0.1 -e "CHANGE MASTER TO MASTER_HOST='$master_host', MASTER_USER='root', MASTER_PASSWORD='$MYSQL_ROOT_PASSWORD', MASTER_LOG_FILE='$master_log_file', MASTER_LOG_POS=$master_log_pos; RESET SLAVE; START SLAVE;"
fi
# Start backup server
exec ncat --listen --keep-open --send-only --max-conns=1 3307 -c "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1"
volumeMounts:
- name: data
mountPath: /var/lib/mysql
subPath: mysql
- name: conf
mountPath: /etc/mysql/conf.d
resources:
requests:
cpu: 100m
memory: 100Mi
volumes:
- name: conf
emptyDir: {}
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: standard
resources:
requests:
storage: 10GiDaemonSet
A DaemonSet ensures that a copy of a Pod runs on all nodes (or specific nodes). When a node is added to the cluster, Pods are automatically added, and when a node is removed, Pods are also removed.
Main Features of DaemonSet
- Run on All Nodes: Run Pods on all nodes in the cluster
- Node Selection: Can run only on specific nodes through node selectors
- Automatic Deployment: Automatically deploy Pods when new nodes are added
- Automatic Cleanup: Automatically clean up Pods when nodes are removed
DaemonSet Definition
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containersDaemonSet Update Strategies
DaemonSets provide two update strategies:
RollingUpdate: Updates Pods sequentially (default)
- maxUnavailable: Maximum number of Pods unavailable during update
OnDelete: Updates only when Pods are deleted
DaemonSet Node Selection
DaemonSets can be configured to run only on specific nodes:
spec:
template:
spec:
nodeSelector:
disk: ssdDaemonSet Taint Tolerations
DaemonSets can set tolerations to run on nodes with taints:
spec:
template:
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoScheduleDaemonSet Use Cases
DaemonSets are used for the following purposes:
- Log Collectors: Fluentd, Logstash, etc.
- Monitoring Agents: Prometheus Node Exporter, Datadog Agent, etc.
- Network Plugins: Calico, Cilium, Weave Net, etc.
- Storage Daemons: Ceph, GlusterFS, etc.
- Security Agents: Falco, Sysdig, etc.
DaemonSet Example: Prometheus Node Exporter
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
namespace: monitoring
labels:
app: node-exporter
spec:
selector:
matchLabels:
app: node-exporter
template:
metadata:
labels:
app: node-exporter
spec:
hostNetwork: true
hostPID: true
containers:
- name: node-exporter
image: prom/node-exporter:v1.3.1
args:
- --path.procfs=/host/proc
- --path.sysfs=/host/sys
- --path.rootfs=/host/root
- --web.listen-address=:9100
ports:
- containerPort: 9100
protocol: TCP
name: http
resources:
limits:
cpu: 250m
memory: 180Mi
requests:
cpu: 102m
memory: 180Mi
volumeMounts:
- name: proc
mountPath: /host/proc
readOnly: true
- name: sys
mountPath: /host/sys
readOnly: true
- name: root
mountPath: /host/root
readOnly: true
tolerations:
- operator: "Exists"
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
- name: root
hostPath:
path: /Jobs and CronJobs
Jobs and CronJobs are workload resources for running one-time or periodic tasks.
Job
A Job creates one or more Pods and continues execution until a specified number of Pods successfully terminate.
Main Features of Job
- Completion Guarantee: Runs until specified number of Pods complete successfully
- Parallel Execution: Can run multiple Pods in parallel
- Retry: Automatic retry of failed Pods
- Cleanup After Completion: Optional cleanup of Pods after job completion
Job Definition
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
completions: 5 # Number of Pods that must successfully complete
parallelism: 2 # Number of Pods to run in parallel
backoffLimit: 4 # Number of retries on failure
activeDeadlineSeconds: 100 # Job time limit (seconds)
ttlSecondsAfterFinished: 100 # Deletion time after completion (seconds)
template:
spec:
containers:
- name: pi
image: perl:5.34
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
resources:
requests:
cpu: 100m
memory: 50Mi
limits:
cpu: 100m
memory: 100Mi
restartPolicy: Never # or OnFailureJob Completion Modes
Jobs provide two completion modes:
- NonIndexed: Standard job mode where the job completes when the specified number of Pods successfully complete
- Indexed: Each Pod is assigned an index starting from 0, performing tasks for specific index ranges
apiVersion: batch/v1
kind: Job
metadata:
name: indexed-job
spec:
completions: 5
parallelism: 3
completionMode: Indexed # Enable Indexed mode
template:
spec:
containers:
- name: worker
image: busybox:1.34
command: ["sh", "-c", "echo Processing item ${JOB_COMPLETION_INDEX}"]
restartPolicy: NeverJob Use Cases
Jobs are used for the following purposes:
- Batch Processing: Data processing, ETL tasks
- Computation Tasks: Scientific calculations, rendering
- Database Migrations: Schema updates
- One-time Administrative Tasks: Backups, cleanup tasks
CronJob
CronJobs run Jobs periodically according to a specified schedule. They work similarly to Linux cron jobs.
Main Features of CronJob
- Scheduled Execution: Specify execution schedule using cron expressions
- Job Management: Create Jobs according to schedule
- Concurrency Policy: Define behavior when previous job is still running
- History Limit: Limit history of completed jobs
CronJob Definition
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *" # Run every minute
timeZone: "America/New_York" # Timezone (Kubernetes 1.24+)
concurrencyPolicy: Forbid # Allow, Forbid, Replace
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
startingDeadlineSeconds: 60
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox:1.34
command:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailureCron Expression
Cron expressions have the following format:
+------------------- minute (0 - 59)
| +----------------- hour (0 - 23)
| | +--------------- day of month (1 - 31)
| | | +------------- month (1 - 12)
| | | | +----------- day of week (0 - 6) (Sunday to Saturday; 7 is also Sunday)
| | | | |
| | | | |
* * * * *Common cron expression examples:
*/5 * * * *: Every 5 minutes0 * * * *: Every hour at the top of the hour0 0 * * *: Every day at midnight0 0 * * 0: Every Sunday at midnight0 0 1 * *: 1st of every month at midnight0 0 1 1 *: January 1st at midnight every year
Concurrency Policy
CronJobs provide three concurrency policies:
- Allow: Multiple Jobs can run simultaneously (default)
- Forbid: Skip new Job if previous Job is still running
- Replace: Replace previous Job with new Job if still running
CronJob Use Cases
CronJobs are used for the following purposes:
- Regular Backups: Database backups, snapshot creation
- Data Synchronization: Periodic data synchronization
- Report Generation: Daily/weekly/monthly report generation
- Cleanup Tasks: Temporary file cleanup, log rotation
- Notifications and Monitoring: Status checks, alert sending
CronJob Example: Database Backup
apiVersion: batch/v1
kind: CronJob
metadata:
name: database-backup
spec:
schedule: "0 2 * * *" # Run daily at 02:00
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: postgres:14
env:
- name: PGHOST
value: postgres-service
- name: PGUSER
valueFrom:
secretKeyRef:
name: postgres-secret
key: username
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: password
command:
- /bin/sh
- -c
- |
pg_dump -Fc > /backup/db-$(date +%Y%m%d-%H%M%S).dump
find /backup -type f -mtime +7 -delete # Delete backups older than 7 days
volumeMounts:
- name: backup-volume
mountPath: /backup
restartPolicy: OnFailure
volumes:
- name: backup-volume
persistentVolumeClaim:
claimName: backup-pvcConclusion
This document covered Pods, the basic building block of Kubernetes, and various workload resources. Starting from the concept of Pods, we explored the characteristics and use cases of various workload resources including Deployments, StatefulSets, DaemonSets, Jobs, and CronJobs. Each of these resources has unique purposes and features, and using them appropriately enables efficient application deployment and management.
Quiz
To test what you learned in this chapter, try the Pods and Workloads Quiz.