mirror of
https://github.com/stefanprodan/podinfo.git
synced 2026-08-18 19:58:57 +00:00
deploy: Add warm-cache CronJob
- Introduced a new `warm-cache` CronJob to periodically preload the cache. - Added supporting scripts (`warm-cache.sh`, `warm-cache-init.sh`) to manage the cache warm-up process. - Configured `ServiceAccount` for the frontend deployment to enhance security. - Adjusted HPA minimum replicas from 1 to 2 for better availability. - Set frontend deployment to use debug log level. Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: warm-cache
|
||||
spec:
|
||||
# Runs every 5 minutes
|
||||
schedule: "*/5 * * * *"
|
||||
concurrencyPolicy: Forbid
|
||||
successfulJobsHistoryLimit: 1
|
||||
failedJobsHistoryLimit: 1
|
||||
jobTemplate:
|
||||
spec:
|
||||
# Cleanup after 1 hour
|
||||
ttlSecondsAfterFinished: 3600
|
||||
backoffLimit: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: warm-cache
|
||||
app.kubernetes.io/part-of: frontend
|
||||
spec:
|
||||
serviceAccountName: frontend
|
||||
restartPolicy: OnFailure
|
||||
initContainers:
|
||||
- name: warm-cache-init
|
||||
image: ghcr.io/stefanprodan/podinfo:6.13.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/sh
|
||||
- /scripts/warm-cache-init.sh
|
||||
env:
|
||||
- name: FRONTEND_URL
|
||||
value: "http://frontend"
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 32Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 16Mi
|
||||
volumeMounts:
|
||||
- name: scripts
|
||||
mountPath: /scripts
|
||||
containers:
|
||||
- name: warm-cache
|
||||
image: ghcr.io/stefanprodan/podinfo:6.13.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- /bin/sh
|
||||
- /scripts/warm-cache.sh
|
||||
env:
|
||||
- name: FRONTEND_URL
|
||||
value: "http://frontend"
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 32Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 16Mi
|
||||
volumeMounts:
|
||||
- name: scripts
|
||||
mountPath: /scripts
|
||||
volumes:
|
||||
- name: scripts
|
||||
configMap:
|
||||
name: warm-cache-script
|
||||
defaultMode: 0755
|
||||
@@ -21,6 +21,7 @@ spec:
|
||||
labels:
|
||||
app.kubernetes.io/name: frontend
|
||||
spec:
|
||||
serviceAccountName: frontend
|
||||
containers:
|
||||
- name: frontend
|
||||
image: ghcr.io/stefanprodan/podinfo:6.13.0
|
||||
@@ -39,7 +40,7 @@ spec:
|
||||
- ./podinfo
|
||||
- --port=9898
|
||||
- --port-metrics=9797
|
||||
- --level=info
|
||||
- --level=debug
|
||||
- --backend-url=http://backend:9898/echo
|
||||
- --cache-server=tcp://cache:6379
|
||||
env:
|
||||
|
||||
@@ -7,7 +7,7 @@ spec:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: frontend
|
||||
minReplicas: 1
|
||||
minReplicas: 2
|
||||
maxReplicas: 4
|
||||
metrics:
|
||||
- type: Resource
|
||||
|
||||
@@ -1,7 +1,15 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
- serviceaccount.yaml
|
||||
- service.yaml
|
||||
- deployment.yaml
|
||||
- hpa.yaml
|
||||
|
||||
- cronjob-warm-cache.yaml
|
||||
configMapGenerator:
|
||||
- name: warm-cache-script
|
||||
files:
|
||||
- scripts/warm-cache.sh
|
||||
- scripts/warm-cache-init.sh
|
||||
options:
|
||||
disableNameSuffixHash: true
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Init step for the warm-cache job.
|
||||
# Calls the frontend in verbose mode so the full connection, request and
|
||||
# response debug data (DNS, TCP, headers, timings) is dumped to the logs.
|
||||
|
||||
FRONTEND="${FRONTEND_URL:-http://frontend}"
|
||||
|
||||
echo "Dumping debug data for ${FRONTEND}/api/info"
|
||||
# -v writes the verbose debug data to stderr, redirect it to stdout so it
|
||||
# lands in the container logs together with the response body.
|
||||
curl -v "${FRONTEND}/api/info" 2>&1
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# This is a simulation of a cache warming process.
|
||||
# It fetches the frontend info, stores it in the cache under the job pod
|
||||
# hostname and reads it back to verify the round-trip.
|
||||
#
|
||||
# Log lines mimic the Log4j 2 default PatternLayout:
|
||||
# %d{yyyy-MM-dd HH:mm:ss,SSS} [%thread] %-5level %logger{36} - %msg
|
||||
|
||||
LOGGER="com.stefanprodan.podinfo.WarmCache"
|
||||
THREAD="main"
|
||||
|
||||
log() {
|
||||
level="$1"
|
||||
shift
|
||||
# millisecond precision timestamp; fall back gracefully if %N is unsupported
|
||||
ts="$(date '+%Y-%m-%d %H:%M:%S,%N' 2>/dev/null)"
|
||||
case "$ts" in
|
||||
*%N|*,) ts="$(date '+%Y-%m-%d %H:%M:%S'),000" ;;
|
||||
*) ts="$(echo "$ts" | cut -c1-23)" ;;
|
||||
esac
|
||||
printf '%s [%s] %-5s %s - %s\n' "$ts" "$THREAD" "$level" "$LOGGER" "$*"
|
||||
}
|
||||
|
||||
FRONTEND="${FRONTEND_URL:-http://frontend}"
|
||||
KEY="$(hostname)"
|
||||
START="$(date +%s)"
|
||||
|
||||
log INFO "Fetching info from ${FRONTEND}/api/info"
|
||||
# Compact the (pretty-printed) JSON onto a single line so each log event
|
||||
# stays on one line, as Log4j renders them.
|
||||
INFO="$(curl -fsS "${FRONTEND}/api/info" | tr -d '\n' | sed 's/ */ /g')"
|
||||
log INFO "Info: ${INFO}"
|
||||
|
||||
# Log each field of the info response on its own line. The /api/info payload
|
||||
# is a flat JSON object of string values, so we can split it without jq.
|
||||
echo "$INFO" | sed 's/^{//; s/}$//' | tr ',' '\n' | while IFS= read -r field; do
|
||||
field="$(echo "$field" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//; s/"//g')"
|
||||
if [ -n "$field" ]; then
|
||||
log DEBUG "info ${field}"
|
||||
fi
|
||||
done
|
||||
|
||||
log INFO "Writing info to cache key ${KEY}"
|
||||
curl -fsS -X POST -H "Content-Type: application/json" -d "${INFO}" "${FRONTEND}/cache/${KEY}"
|
||||
|
||||
# Verify the cached value for 1 minute, polling every 10 seconds.
|
||||
attempt=1
|
||||
while [ "$attempt" -le 6 ]; do
|
||||
log INFO "Reading cache key ${KEY} (attempt ${attempt}/6)"
|
||||
CACHED="$(curl -fsS "${FRONTEND}/cache/${KEY}")"
|
||||
|
||||
if [ "${INFO}" = "${CACHED}" ]; then
|
||||
log INFO "Cache warm verified: cached value matches info"
|
||||
else
|
||||
log ERROR "Cache warm failed: cached value does not match info"
|
||||
log ERROR "Expected: ${INFO}"
|
||||
log ERROR "Got: ${CACHED}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
attempt=$((attempt + 1))
|
||||
if [ "$attempt" -le 6 ]; then
|
||||
sleep 10
|
||||
fi
|
||||
done
|
||||
|
||||
log INFO "Cache warm finished in $(( $(date +%s) - START ))s"
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: frontend
|
||||
Reference in New Issue
Block a user