Add kubernetes-deployment: probes, shutdown, JVM ergonomics, HPA
Companion code for "Deploying Spring Boot 4 on Kubernetes: Probes, Graceful Shutdown, Limits and JVM Ergonomics". A dependency outage under three probe-group setups, a rolling restart under load four ways (three runs each), the JVM's ergonomic choices for nine pod shapes, one GC-heavy load under five CPU limits with throttling counters, and an HPA driven by a Micrometer gauge through prometheus-adapter. Measured on k3s v1.36.4. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01C3TETMrqVUWeFkNtz3Jbo3
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
# An application that needs ~45 s to start, with and without a startupProbe. 1 replica; each
|
||||
# phase is ONE patch, so there is one new ReplicaSet per phase. -> docs/output/startup-probe.txt
|
||||
set -uo pipefail
|
||||
source "$(dirname "$0")/env.sh"
|
||||
D="deploy/orders"
|
||||
observe() {
|
||||
local label="$1"
|
||||
echo "## $label"
|
||||
local start; start=$(date +%s)
|
||||
for _ in $(seq 1 20); do
|
||||
local t=$(( $(date +%s) - start ))
|
||||
printf 't=%3ds ' "$t"
|
||||
kubectl -n "$NS" get pods -l app=orders --no-headers \
|
||||
-o custom-columns=N:.metadata.name,H:.metadata.labels.pod-template-hash,R:.status.containerStatuses[0].ready,C:.status.containerStatuses[0].restartCount,W:.status.containerStatuses[0].state.waiting.reason,X:.metadata.deletionTimestamp \
|
||||
| awk '{ if ($6 != "<none>") next; printf "[%s ready=%s restarts=%s%s] ", substr($1,length($1)-4), $3, $4, ($5=="<none>"?"":" "$5)}'
|
||||
echo
|
||||
sleep 6
|
||||
done
|
||||
echo
|
||||
}
|
||||
kubectl -n "$NS" scale "$D" --replicas=1 > /dev/null
|
||||
kubectl -n "$NS" rollout status "$D" --timeout=120s > /dev/null
|
||||
kubectl -n "$NS" delete events --all > /dev/null 2>&1
|
||||
{
|
||||
echo "# DEMO_STARTUP_DELAY=40s: the context takes ~45 s to refresh, and Tomcat only listens after that."
|
||||
echo "# 1 replica, rolling update (maxSurge 1, maxUnavailable 0). Liveness: period 5 s, failureThreshold 3."
|
||||
echo "# Pods being deleted are not listed. The old pod keeps serving while the new one is not ready."
|
||||
echo
|
||||
kubectl -n "$NS" patch "$D" --type=json -p '[
|
||||
{"op":"remove","path":"/spec/template/spec/containers/0/startupProbe"},
|
||||
{"op":"add","path":"/spec/template/spec/containers/0/env/-","value":{"name":"DEMO_STARTUP_DELAY","value":"40s"}}]' > /dev/null
|
||||
observe "no startupProbe"
|
||||
echo "# Events so far:"
|
||||
kubectl -n "$NS" get events --sort-by=.lastTimestamp | grep -E 'Unhealthy|Killing|BackOff' | awk '{$1=""; $4=""; print}' | sed 's/^ *//' | sort | uniq -c | head -6
|
||||
echo
|
||||
kubectl -n "$NS" delete events --all > /dev/null 2>&1
|
||||
kubectl -n "$NS" patch "$D" --type=json -p '[{"op":"add","path":"/spec/template/spec/containers/0/startupProbe","value":{"httpGet":{"path":"/actuator/health/liveness","port":"http"},"periodSeconds":2,"failureThreshold":60}}]' > /dev/null
|
||||
observe "startupProbe: /actuator/health/liveness every 2 s, failureThreshold 60 (a 120 s budget)"
|
||||
echo "# Events during the startupProbe run:"
|
||||
kubectl -n "$NS" get events --sort-by=.lastTimestamp | grep -E 'Unhealthy|Killing|BackOff' | awk '{$1=""; $4=""; print}' | sed 's/^ *//' | sort | uniq -c | head -6
|
||||
} | tee "$OUT/startup-probe.txt"
|
||||
kubectl -n "$NS" set env "$D" DEMO_STARTUP_DELAY- > /dev/null
|
||||
kubectl -n "$NS" scale "$D" --replicas=2 > /dev/null
|
||||
Reference in New Issue
Block a user