Understanding Kubernetes Pod Lifecycle
A deep dive into the Kubernetes pod lifecycle - from pending to running to termination. Learn how to handle graceful shutdowns and lifecycle hooks.
Table of Contents
Pods are the smallest deployable units in Kubernetes. Understanding their lifecycle is crucial for building reliable applications.
Pod Phases #
A pod goes through several phases during its lifetime:
Pending #
The pod has been accepted by the cluster but one or more containers haven’t been created yet. This includes time spent waiting for scheduling and downloading images.
status:
phase: Pending
conditions:
- type: PodScheduled
status: "True"
Running #
The pod has been bound to a node, and all containers have been created. At least one container is still running or starting.
Succeeded #
All containers in the pod have terminated successfully and won’t be restarted.
Failed #
All containers have terminated, and at least one container terminated in failure.
Container Lifecycle Hooks #
Kubernetes provides two hooks for container lifecycle management:
PostStart #
Executed immediately after a container is created. There’s no guarantee it runs before the container’s ENTRYPOINT.
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo 'Container started' >> /var/log/startup.log"]
PreStop #
Called immediately before a container is terminated. It’s blocking - the container won’t be killed until the hook completes.
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "nginx -s quit; while killall -0 nginx; do sleep 1; done"]
Graceful Shutdown Pattern #
Here’s a pattern I use for graceful shutdowns in Go applications:
func main() {
srv := &http.Server{Addr: ":8080"}
go func() {
if err := srv.ListenAndServe(); err != http.ErrServerClosed {
log.Fatalf("HTTP server error: %v", err)
}
}()
// Wait for SIGTERM
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGTERM, syscall.SIGINT)
<-quit
// Graceful shutdown with timeout
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := srv.Shutdown(ctx); err != nil {
log.Fatalf("Server shutdown error: %v", err)
}
}
Configuring Termination Grace Period #
By default, Kubernetes waits 30 seconds before forcefully killing a pod. You can adjust this:
spec:
terminationGracePeriodSeconds: 60
containers:
- name: app
image: myapp:latest
Liveness vs Readiness Probes #
Understanding the difference is essential:
- Liveness Probe: Is the container healthy? If not, kill it and restart.
- Readiness Probe: Is the container ready to serve traffic? If not, remove from service endpoints.
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
Key Takeaways #
- Always implement graceful shutdown in your applications
- Use preStop hooks for cleanup that must complete before termination
- Set appropriate
terminationGracePeriodSecondsbased on your app’s needs - Implement both liveness and readiness probes
Understanding pod lifecycle helps you build applications that handle deployments, scaling, and failures gracefully.