diff --git a/README.md b/README.md index 99c9769..081dcb8 100644 --- a/README.md +++ b/README.md @@ -680,13 +680,13 @@ kubectl get pods,svc -n default # service: cluster-utils-api-svc:8080 ``` -Sample manifest probes: +Sample manifest probes (near kube defaults; timeout 1s so delay demos trip easily): -- **startupProbe** → `/startupz` (timeout 1s, period 2s) -- **livenessProbe** → `/livez` (timeout 1s) -- **readinessProbe** → `/readyz` (timeout 1s) +- **startupProbe** → `/startupz` (period 2s × failureThreshold 30 ≈ 60s cold start) +- **livenessProbe** → `/livez` (period 10s, failureThreshold 3) +- **readinessProbe** → `/readyz` (period 10s, failureThreshold 3) -Uncomment the env examples in the yaml to break things on purpose, or flip live via `/a/control/probes` after you grab the token from pod logs (or set `AUTH_TOKEN`). +Image is pinned to a version tag so default pull is **IfNotPresent** (bare `:latest` still forces Always in kube). Uncomment env examples to break probes, or flip via `/a/control/probes`. ```bash kubectl -n default port-forward svc/cluster-utils-api-svc 8080:8080 diff --git a/k8s-cluster-util-apis.yml b/k8s-cluster-util-apis.yml index b1542de..0de1b4b 100644 --- a/k8s-cluster-util-apis.yml +++ b/k8s-cluster-util-apis.yml @@ -19,13 +19,19 @@ spec: spec: containers: - name: cluster-utils-api - image: donkeyx/cluster-utils-api:latest - imagePullPolicy: Always + # GHCR primary (Hub still works as mirror). Version tag → default pull IfNotPresent. + # :latest still forces Always in kube even without imagePullPolicy. + image: ghcr.io/donkeyx/cluster-utils-api:2.5.0 + # Alternative: docker.io/donkeyx/cluster-utils-api:2.5.0 ports: - name: http containerPort: 8080 - # Short timeouts so LIVE/READY/STARTUP delaySeconds are easy to trip. - # startup runs until first success, then kube moves on to live+ready. + # Probes — close to kube defaults; short timeout so app delaySeconds demos work. + # Defaults if omitted: periodSeconds=10, timeoutSeconds=1, successThreshold=1, + # failureThreshold=3, initialDelaySeconds=0. + # + # startup: only until first success, then live+ready take over. + # period 2 × failureThreshold 30 ≈ 60s max cold-start window. startupProbe: httpGet: path: /startupz @@ -33,6 +39,8 @@ spec: periodSeconds: 2 timeoutSeconds: 1 failureThreshold: 30 + successThreshold: 1 + # liveness: restart if process is wedged (defaults are fine for this app) livenessProbe: httpGet: path: /livez @@ -40,13 +48,16 @@ spec: periodSeconds: 10 timeoutSeconds: 1 failureThreshold: 3 + successThreshold: 1 + # readiness: leave Service endpoints if not ready (~30s of fails with defaults) readinessProbe: httpGet: path: /readyz port: http - periodSeconds: 5 + periodSeconds: 10 timeoutSeconds: 1 - failureThreshold: 2 + failureThreshold: 3 + successThreshold: 1 env: - name: PORT value: "8080" @@ -89,13 +100,15 @@ spec: # include kube probe paths in traces (off by default — noisy) # - name: OTEL_TRACE_PROBES # value: "true" + # Sized from podman run of :2.5.0 (cgroup ~15–16Mi, process_resident ~40–43Mi, + # CPU ~0.1–1% under light load). requests ≈ 90% of process RSS; limits headroom. resources: requests: - cpu: "0.1" - memory: "50Mi" + cpu: "10m" + memory: "40Mi" limits: - cpu: "0.5" - memory: 100Mi + cpu: "100m" + memory: "80Mi" --- apiVersion: v1