Bash + Kubernetes
Scripting Kubernetes operations with kubectl and Bash — deployment waits, rollout automation, log aggregation, and cluster audit scripts.
kubectl Output Formats for Scripting
kubectl get pods -o json # full JSON, parse with jq
kubectl get pods -o jsonpath='{.items[*].metadata.name}' # built-in JSONPath, no jq required
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase
kubectl get pods --no-headers # plain text, no header row — easier to pipe into awk
-o jsonpath avoids an external jq dependency for simple extractions; -o json | jq is more powerful for complex filtering.
Waiting for a Rollout to Complete
#!/usr/bin/env bash
set -euo pipefail
kubectl apply -f deployment.yaml
kubectl rollout status deployment/myapp --timeout=120s # built-in wait, blocks until rollout finishes or times out
echo "Rollout complete"
kubectl rollout status is the correct tool here — it already implements proper waiting/polling logic; don’t hand-roll a while loop checking pod status when this exists.
Waiting for Pods to Be Ready (Custom Conditions)
kubectl wait --for=condition=Ready pod -l app=myapp --timeout=90s
kubectl wait --for=condition=Available deployment/myapp --timeout=90s
A Real Deployment Script
#!/usr/bin/env bash
set -euo pipefail
NAMESPACE="production"
DEPLOYMENT="myapp"
IMAGE_TAG="${1:?Usage: $0 <image_tag>}"
echo "Deploying $DEPLOYMENT:$IMAGE_TAG to $NAMESPACE..."
kubectl set image "deployment/$DEPLOYMENT" "myapp=myrepo/myapp:$IMAGE_TAG" -n "$NAMESPACE"
if ! kubectl rollout status "deployment/$DEPLOYMENT" -n "$NAMESPACE" --timeout=180s; then
echo "Rollout failed — rolling back" >&2
kubectl rollout undo "deployment/$DEPLOYMENT" -n "$NAMESPACE"
exit 1
fi
echo "Deployment succeeded"
Finding and Diagnosing Problem Pods
# All pods NOT in Running state, across all namespaces
kubectl get pods --all-namespaces --field-selector=status.phase!=Running
# Pods that are CrashLoopBackOff specifically
kubectl get pods --all-namespaces | grep CrashLoopBackOff
# Loop through failing pods and grab their last logs automatically
kubectl get pods -n production --field-selector=status.phase!=Running -o jsonpath='{.items[*].metadata.name}' | \
tr ' ' '\n' | while read -r pod; do
echo "=== $pod ==="
kubectl logs "$pod" -n production --tail=20 --previous 2>/dev/null || \
kubectl logs "$pod" -n production --tail=20
done
Aggregating Logs Across Multiple Pods
# Tail logs from every pod matching a label, prefixed with pod name
kubectl logs -l app=myapp -n production --all-containers --prefix -f
# Or loop manually for more control
for pod in $(kubectl get pods -n production -l app=myapp -o jsonpath='{.items[*].metadata.name}'); do
echo "=== $pod ==="
kubectl logs "$pod" -n production --tail=50
done
Cluster Audit Script
#!/usr/bin/env bash
set -euo pipefail
echo "=== Pods without resource limits ==="
kubectl get pods --all-namespaces -o json | \
jq -r '.items[] | select(.spec.containers[].resources.limits == null) | "\(.metadata.namespace)/\(.metadata.name)"'
echo "=== Deployments with 0 replicas ==="
kubectl get deployments --all-namespaces -o json | \
jq -r '.items[] | select(.spec.replicas == 0) | "\(.metadata.namespace)/\(.metadata.name)"'
echo "=== Nodes not Ready ==="
kubectl get nodes --no-headers | awk '$2 != "Ready" {print $1}'
Running a Command Inside a Pod From a Script
kubectl exec -n production deploy/myapp -- printenv NODE_ENV
RESULT=$(kubectl exec -n production deploy/myapp -- curl -sf http://localhost:8080/health)
echo "Health check: $RESULT"
Production Considerations
- Prefer
kubectl rollout status/kubectl waitover hand-rolled polling loops — they correctly handle the actual completion conditions Kubernetes defines, rather than an approximation. - Wrap deploy scripts with an automatic rollback (
kubectl rollout undo) on rollout failure — a script that deploys but doesn’t handle failure gracefully leaves a cluster in a half-broken state. - Use
-o jsonpath/-o json | jqrather than parsing the default human-readable table output — column widths and formatting inkubectl getoutput are not a stable contract for scripts to depend on.
Quick Interview Answer
“kubectl scripting relies on structured output (
-o jsonpathor-o jsonpiped tojq) rather than parsing the human-readable table format, which isn’t stable across versions.kubectl rollout statusandkubectl wait --for=condition=...are the correct built-in tools for waiting on deployment/pod state, and should be preferred over hand-rolled polling. A solid deploy script pattern: apply the change, wait for rollout status, and automaticallykubectl rollout undoon failure rather than leaving the cluster in a partially-deployed state.”
Common Mistakes
- Parsing
kubectl get pods’s default table output with awk/cut instead of-o jsonpath/-o json, breaking when column formatting changes. - Hand-rolling a polling loop for rollout completion instead of using
kubectl rollout status. - Deploying without an automatic rollback path, leaving a failed rollout to be discovered and fixed manually later.
Add More Questions to This Guide
Know a question that should be here? Share it and help the community!
Open Google Form