Kubernetes Lifecycle
Introduction
Understanding the lifecycle of Kubernetes objects is fundamental to working effectively with Kubernetes. The lifecycle encompasses how resources are created, managed, scaled, updated, and eventually terminated within a Kubernetes cluster. This knowledge helps you troubleshoot issues, optimize deployments, and build resilient applications.
In this guide, we'll explore the various stages that Kubernetes objects go through and how you can interact with them at each stage of their existence.
The Basic Kubernetes Object Lifecycle
At its core, every Kubernetes object follows a similar pattern throughout its lifecycle:
- Creation - Object is defined and submitted to the Kubernetes API
- Validation - API server validates the object specification
- Scheduling (for applicable resources) - Resources are allocated
- Running/Active - Object performs its designated function
- Termination - Object is deleted or replaced
Let's break down each of these phases in more detail.
Pod Lifecycle Phases
Pods, the smallest deployable units in Kubernetes, have a well-defined lifecycle with distinct phases. Let's explore each phase:
1. Pending
When a Pod is first created, it enters the Pending phase. During this phase:
- The API server has accepted the Pod
- The Pod has been saved to etcd
- The Pod has not yet been scheduled to a node
- Container images may be downloading
This phase can last from seconds to minutes depending on resource availability, image size, and network conditions.
2. Running
The Pod reaches the Running phase when:
- The Pod has been bound to a node
- All containers have been created
- At least one container is running or in the process of starting/restarting
Let's look at how to check Pod status:
kubectl get pod nginx-pod -o wide
Output:
NAME READY STATUS RESTARTS AGE IP NODE
nginx-pod 1/1 Running 0 1m 10.244.2.3 worker-1
3. Succeeded
A Pod enters the Succeeded phase when:
- All containers in the Pod have terminated successfully
- None of the containers will be restarted
This is common for one-time jobs or batch processes.
4. Failed
A Pod reaches the Failed phase when:
- At least one container has terminated with failure
- The container exited with a non-zero status code
5. Unknown
Sometimes a Pod may show an Unknown status, which means:
- The state of the Pod couldn't be determined
- Communication with the node hosting the Pod has failed
Container States Within Pods
Containers within Pods have their own lifecycle states:
1. Waiting
The container is waiting to start, possibly due to:
- Image pulling
- Secret creation
- Dependencies not ready
2. Running
The container is executing normally without issues.
3. Terminated
The container has completed execution or failed:
- Either successfully exited with status code 0
- Or failed with a non-zero exit code
You can inspect detailed container states with:
kubectl describe pod nginx-pod
Output excerpt:
Containers:
nginx:
Container ID: docker://7c6a0354g8e1...
State:
Running:
Started: Mon, 10 Jan 2022 12:30:55 +0000
Ready: True
Deployment Lifecycle
Deployments, which manage ReplicaSets and Pods, have their own lifecycle:
1. Creation
When a Deployment is created:
kubectl create -f nginx-deployment.yaml
The Deployment controller creates a ReplicaSet, which then creates Pods.
2. Rolling Updates
When updating a Deployment, Kubernetes follows a controlled process:
kubectl set image deployment/nginx-deployment nginx=nginx:1.19
Here's what happens:
- A new ReplicaSet is created
- The new ReplicaSet is gradually scaled up
- The old ReplicaSet is gradually scaled down
- Once the new ReplicaSet reaches the desired state, the old one is kept but scaled to 0
You can observe this process:
kubectl rollout status deployment/nginx-deployment
Output:
Waiting for deployment "nginx-deployment" rollout to finish: 2 out of 3 new replicas have been updated...
deployment "nginx-deployment" successfully rolled out
3. Rollbacks
If an update fails or causes issues, you can rollback:
kubectl rollout undo deployment/nginx-deployment
Kubernetes will:
- Scale up the previous ReplicaSet
- Scale down the problematic ReplicaSet
Service Lifecycle
Services provide stable networking for dynamic Pods:
1. Creation
When a Service is created:
kubectl create -f nginx-service.yaml
Kubernetes:
- Assigns a ClusterIP (for internal services)
- Updates kube-proxy on all nodes
- Creates required network rules
2. Endpoint Updates
As Pods come and go, Service endpoints update automatically:
kubectl get endpoints nginx-service
Output:
NAME ENDPOINTS AGE
nginx-service 10.244.1.4:80,10.244.2.5:80,10.244.3.3:80 1h
3. Termination
When a Service is deleted:
kubectl delete service nginx-service
Kubernetes:
- Removes associated network rules
- Releases the assigned ClusterIP
- Updates kube-proxy on all nodes
PersistentVolume Lifecycle
PersistentVolumes (PVs) and PersistentVolumeClaims (PVCs) follow a more complex lifecycle:
1. Provisioning
PVs can be provisioned:
- Static: Admin creates PVs in advance
- Dynamic: Created on-demand when PVCs request them
2. Binding
When a PVC claims a PV:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Kubernetes binds the PVC to a suitable PV.
3. Using
Pods can use the PVC:
apiVersion: v1
kind: Pod
metadata:
name: database-pod
spec:
containers:
- name: postgres
image: postgres:13
volumeMounts:
- mountPath: "/var/lib/postgresql/data"
name: data-volume
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: data-claim
4. Reclaiming
When a PVC is deleted, the PV enters a reclaim phase based on its policy:
- Retain: PV remains with its data, but becomes unavailable
- Delete: PV and its associated storage are deleted
- Recycle: Data is removed, and PV becomes available again
ConfigMap and Secret Lifecycle
ConfigMaps and Secrets are created, consumed, and updated in a cycle:
1. Creation
Create a ConfigMap:
kubectl create configmap app-config --from-literal=APP_COLOR=blue --from-literal=APP_MODE=prod
2. Consumption
Pods consume them as:
- Environment variables
- Volume mounts
apiVersion: v1
kind: Pod
metadata:
name: webapp
spec:
containers:
- name: webapp
image: nginx
env:
- name: APP_COLOR
valueFrom:
configMapKeyRef:
name: app-config
key: APP_COLOR
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
3. Updates
When ConfigMaps are updated, the behavior depends on how they're consumed:
- Environment variables: Require Pod restart
- Volume mounts: Update automatically (with some delay)
Practical Example: Full Application Lifecycle
Let's walk through a complete example of deploying a simple web application:
1. Create a ConfigMap for Application Configuration
kubectl create configmap webapp-config --from-literal=APP_COLOR=blue --from-literal=APP_ENV=production
2. Create a Secret for Database Credentials
kubectl create secret generic db-creds --from-literal=username=admin --from-literal=password=secretpassword
3. Deploy the Database
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-creds
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumes:
- name: mysql-data
persistentVolumeClaim:
claimName: mysql-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
4. Deploy the Web Application
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: mywebapp:1.0
ports:
- containerPort: 8080
env:
- name: APP_COLOR
valueFrom:
configMapKeyRef:
name: webapp-config
key: APP_COLOR
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-creds
key: password
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: webapp
5. Observe the Deployment
kubectl get all
Output:
NAME READY STATUS RESTARTS AGE
pod/mysql-6f5b47d44b-qvxpx 1/1 Running 0 2m
pod/webapp-689d8d9c7c-f4xp9 1/1 Running 0 1m
pod/webapp-689d8d9c7c-g8svb 1/1 Running 0 1m
pod/webapp-689d8d9c7c-mz7wf 1/1 Running 0 1m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d
service/mysql ClusterIP 10.102.190.128 <none> 3306/TCP 2m
service/webapp-service LoadBalancer 10.106.103.209 34.123.45.67 80:30523/TCP 1m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/mysql 1/1 1 1 2m
deployment.apps/webapp 3/3 3 3 1m
NAME DESIRED CURRENT READY AGE
replicaset.apps/mysql-6f5b47d44b 1 1 1 2m
replicaset.apps/webapp-689d8d9c7c 3 3 3 1m
6. Update the Application
kubectl set image deployment/webapp webapp=mywebapp:1.1
Watch the rolling update:
kubectl rollout status deployment/webapp
7. Scale Based on Demand
kubectl scale deployment webapp --replicas=5
8. Clean Up When Finished
kubectl delete -f webapp.yaml
kubectl delete -f mysql.yaml
kubectl delete configmap webapp-config
kubectl delete secret db-creds
Kubernetes Component Lifecycle
Beyond just resources, Kubernetes components themselves have lifecycles:
Control Plane Components
- kube-apiserver: The front-end for the Kubernetes control plane
- etcd: Consistent and highly-available key-value store
- kube-scheduler: Assigns Pods to Nodes
- kube-controller-manager: Runs controller processes
Node Components
- kubelet: Ensures containers are running in a Pod
- kube-proxy: Maintains network rules
- Container runtime: Software responsible for running containers
Each component is managed differently depending on the installation method (kubeadm, managed service, etc.).
Advanced Lifecycle Concepts
Hooks
Kubernetes provides lifecycle hooks to run code at specific points:
Pod Lifecycle Hooks:
- PostStart: Executes immediately after a container is created
- PreStop: Executes just before a container is terminated
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
preStop:
exec:
command: ["/bin/sh","-c","nginx -s quit; while killall -0 nginx; do sleep 1; done"]
Finalizers
Finalizers protect resources from being deleted until specific conditions are met:
metadata:
finalizers:
- kubernetes.io/pv-protection
When you try to delete a resource with finalizers, it enters a "Terminating" state but isn't removed until the finalizers are cleared.
Troubleshooting Lifecycle Issues
Common Issues and Resolutions
Pods Stuck in Pending State
Possible causes:
- Insufficient cluster resources
- PVC binding issues
- Node selector constraints not met
Check with:
kubectl describe pod stuck-pod
Failed Deployments
Possible causes:
- Image pull errors
- Application startup failures
- Resource constraint issues
Check with:
kubectl rollout status deployment/my-deployment
kubectl describe deployment my-deployment
Termination Delays
Possible causes:
- Long-running processes not responding to SIGTERM
- Finalizers preventing deletion
Check with:
kubectl describe pod terminating-pod
Summary
The Kubernetes lifecycle involves multiple interconnected processes:
- Object Creation: Resources are defined, validated, and created
- Resource Management: Pods are scheduled and monitored
- Updates and Scaling: Changes propagate through controlled processes
- Termination: Resources are removed with proper cleanup
Understanding these lifecycle phases helps you:
- Deploy applications effectively
- Troubleshoot issues when they arise
- Optimize resource usage
- Implement resilient, self-healing architectures
Exercises
- Deploy a simple web application with 3 replicas and observe all lifecycle phases.
- Perform a rolling update on your deployment and monitor the process.
- Implement Pod lifecycle hooks for graceful startup and shutdown.
- Create a deployment that uses ConfigMaps and Secrets, then update them and observe the behavior.
- Intentionally cause a deployment to fail and practice troubleshooting and rollback procedures.
Additional Resources
- Kubernetes Documentation: Pod Lifecycle
- Kubernetes Documentation: Deployments
- Kubernetes Documentation: Container Lifecycle Hooks
- Official Kubernetes GitHub repository
- Kubernetes community forums and Slack channels
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)