This guide contains hands-on exercises to help you practice implementing and troubleshooting Kubernetes container health probes. These exercises are designed to reinforce the concepts covered in the main documentation.
kubectl installed and configured to connect to your clusterCreate a web application pod with appropriate HTTP probes for all three probe types.
exercise1.yaml with the following content:apiVersion: v1
kind: Pod
metadata:
name: exercise1-web
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
kubectl apply -f exercise1.yaml
kubectl get pods exercise1-web
apiVersion: v1
kind: Pod
metadata:
name: exercise1-web
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
# Add your probe definitions here
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 3
kubectl replace --force -f exercise1.yaml
kubectl describe pod exercise1-web
# Create a file that can be used to modify nginx configuration to return 500 errors
kubectl exec -it exercise1-web -- bash -c 'echo "server { listen 80; location / { return 500; } }" > /etc/nginx/conf.d/default.conf'
# Reload nginx
kubectl exec -it exercise1-web -- nginx -s reload
kubectl get pods exercise1-web
kubectl exec -it exercise1-web -- bash -c 'echo "server { listen 80; location / { return 200; } }" > /etc/nginx/conf.d/default.conf'
kubectl exec -it exercise1-web -- nginx -s reload
Create a pod that uses exec probes to check the application’s health by executing commands inside the container.
exercise2.yaml with the following content:apiVersion: v1
kind: Pod
metadata:
name: exercise2-backend
spec:
containers:
- name: backend
image: busybox:latest
command: ["/bin/sh", "-c", "touch /tmp/healthy; sleep infinity"]
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
readinessProbe:
exec:
command:
- ls
- /tmp/ready
initialDelaySeconds: 5
periodSeconds: 5
kubectl apply -f exercise2.yaml
kubectl get pods exercise2-backend
# Expected output shows 0/1 ready
# NAME READY STATUS RESTARTS AGE
# exercise2-backend 0/1 Running 0 30s
kubectl exec exercise2-backend -- touch /tmp/ready
kubectl get pods exercise2-backend
kubectl exec exercise2-backend -- rm /tmp/healthy
kubectl get pods exercise2-backend
# Watch the RESTARTS column increment
kubectl describe pod exercise2-backend
# Look for events indicating liveness probe failures and container restarts
Create a pod with a startup probe to handle a slow-starting application.
exercise3.yaml with the following content:apiVersion: v1
kind: Pod
metadata:
name: exercise3-slow-start
spec:
containers:
- name: slow-app
image: busybox:latest
command: ["/bin/sh", "-c", "echo 'App starting...'; sleep 30; touch /tmp/ready; echo 'App started!'; sleep infinity"]
startupProbe:
exec:
command:
- cat
- /tmp/ready
failureThreshold: 10
periodSeconds: 5
livenessProbe:
exec:
command:
- cat
- /tmp/ready
periodSeconds: 5
kubectl apply -f exercise3.yaml
kubectl get pods exercise3-slow-start -w
Note how the pod remains in a non-ready state until the startup probe succeeds, after which the liveness probe becomes active.
Check the events to see the probe activity:
kubectl describe pod exercise3-slow-start
Create a MySQL database pod with TCP socket probes to verify connectivity.
exercise4.yaml with the following content:apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
data:
password: cGFzc3dvcmQ= # "password" in base64
---
apiVersion: v1
kind: Pod
metadata:
name: exercise4-mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
ports:
- containerPort: 3306
startupProbe:
tcpSocket:
port: 3306
failureThreshold: 30
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 20
periodSeconds: 5
kubectl apply -f exercise4.yaml
kubectl get pods exercise4-mysql -w
kubectl describe pod exercise4-mysql
# Create a temporary pod to test connectivity
kubectl run netcat --rm -it --image=busybox -- sh
# From within the netcat pod, test the MySQL TCP connection
nc -zv exercise4-mysql.default.svc.cluster.local 3306
# Or using the pod IP directly
nc -zv $(kubectl get pod exercise4-mysql -o jsonpath='{.status.podIP}') 3306
Create a deployment with all three types of probes configured properly.
exercise5.yaml with the following content:apiVersion: apps/v1
kind: Deployment
metadata:
name: exercise5-app
labels:
app: exercise5
spec:
replicas: 3
selector:
matchLabels:
app: exercise5
template:
metadata:
labels:
app: exercise5
spec:
containers:
- name: app
image: nginx:latest
ports:
- containerPort: 80
startupProbe:
httpGet:
path: /
port: 80
failureThreshold: 30
periodSeconds: 2
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 5
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 3
---
apiVersion: v1
kind: Service
metadata:
name: exercise5-service
spec:
selector:
app: exercise5
ports:
- port: 80
targetPort: 80
type: ClusterIP
kubectl apply -f exercise5.yaml
kubectl get deployment exercise5-app
kubectl get pods -l app=exercise5
# Get the first pod name
POD_NAME=$(kubectl get pods -l app=exercise5 -o jsonpath='{.items[0].metadata.name}')
# Make the readiness probe fail
kubectl exec $POD_NAME -- bash -c 'echo "server { listen 80; location / { return 500; } }" > /etc/nginx/conf.d/default.conf'
kubectl exec $POD_NAME -- nginx -s reload
# Check pod readiness
kubectl get pods -l app=exercise5
# Check service endpoints
kubectl describe service exercise5-service
kubectl exec $POD_NAME -- bash -c 'echo "server { listen 80; location / { return 200; } }" > /etc/nginx/conf.d/default.conf'
kubectl exec $POD_NAME -- nginx -s reload
kubectl describe service exercise5-service
Create a pod with a custom readiness gate and observe its behavior.
exercise6.yaml with the following content:apiVersion: v1
kind: Pod
metadata:
name: exercise6-readiness-gate
spec:
readinessGates:
- conditionType: "example.com/custom-condition"
containers:
- name: app
image: nginx:latest
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 3
kubectl apply -f exercise6.yaml
kubectl get pod exercise6-readiness-gate -o wide
kubectl get pod exercise6-readiness-gate -o jsonpath='{.status.conditions}' | jq
kubectl describe pod exercise6-readiness-gate
kubectl delete pod exercise6-readiness-gate
These exercises have given you hands-on experience with implementing and testing Kubernetes container health probes. Practice these concepts to become proficient in using probes to improve application reliability in Kubernetes.
Remember these key points: