Skip to content

fix(openclaw): tune probe timeouts and rollback admins to beta.1 - #55

Merged
mashkovd merged 1 commit into
mainfrom
fix/openclaw-probe-timeout-and-admins-rollback
Apr 28, 2026
Merged

mashkovd merged 1 commit into
mainfrom
fix/openclaw-probe-timeout-and-admins-rollback

Conversation

@mashkovd

Copy link
Copy Markdown
Member

Summary

  • admins-openclaw on 2026.4.28-beta.2 crash-looped (9 restarts in 35 min). Startup probe was failing on /healthz with context deadline exceeded — k8s default timeoutSeconds=1 is too tight for openclaw's plugin install + Node event-loop blocking on model-pricing fetch.
  • helm-charts/base-service/templates/deployment.yaml never rendered timeoutSeconds for any probe, so all three openclaw tenants are vulnerable (admins/labs/ovk share probe config).
  • This PR (a) extends the chart template to render timeoutSeconds (and failureThreshold for liveness/readiness, with k8s-default defaults so no behaviour change for other charts), (b) sets explicit roomier values in all three openclaw tenants, and (c) rolls admins back to 2026.4.26-beta.1 (the tag labs/ovk run) until we understand if beta.2 added a startup-time regression on top.

Root cause (from kubectl describe pod)

Last State:    Terminated
  Reason:      Error
  Exit Code:   137
Liveness:   http-get http://:http/healthz delay=30s timeout=1s period=20s #failure=3
Startup:    http-get http://:http/healthz delay=5s  timeoutSeconds=1 period=5s #failure=24
…
Warning  Unhealthy  …  Startup probe failed: Get "http://10.42.6.174:18789/healthz": context deadline exceeded (Client.Timeout exceeded while awaiting headers)

Two failure modes during the ~78s startup:

  1. connection refused while plugins install (HTTP server not yet up)
  2. context deadline exceeded once HTTP is up but /healthz response > 1s due to event-loop stall

Changes

File Change
platform-gitops/helm-charts/base-service/templates/deployment.yaml Render timeoutSeconds for startup/liveness/readiness + failureThreshold for liveness/readiness. Defaults preserve k8s defaults (1s, 3) — non-breaking for other charts.
platform-gitops/services/admins/openclaw/values.yaml Image rollback 2026.4.28-beta.2 → 2026.4.26-beta.1 (incl. setup init container hardcode + OPENCLAW_VERSION). New probe values (see below).
platform-gitops/services/labs/openclaw/values.yaml New probe values only.
platform-gitops/services/ovk/openclaw/values.yaml New probe values only.

New probe config (synced across admins/labs/ovk):

  • startup: timeoutSeconds: 3, failureThreshold: 36 (5 + 36×5 = 185s, ≈2.4× current ~78s startup)
  • readiness: timeoutSeconds: 3, failureThreshold: 3
  • liveness: initialDelaySeconds: 60, periodSeconds: 30, timeoutSeconds: 5, failureThreshold: 5 (150s tolerance for transient event-loop stalls)

Test plan

  • helm template for all three tenants — confirmed probes render with new fields and only :2026.4.26-beta.1 image references for admins
  • After merge, ArgoCD auto-syncs the three apps
  • kubectl -n admins get pod -l app.kubernetes.io/instance=admins-openclaw -w → 2/3 → 3/3, RestartCount stays 0 after warm-up
  • kubectl -n admins describe pod ... | grep -E 'Startup|Liveness|Readiness' → new timeouts visible
  • mctl_get_service_status team=admins service=openclaw → Healthy
  • mctl_get_service_logs team=admins service=openclaw since=15m → only one gateway ready event in window (no restart cycle)
  • curl -I https://admins-openclaw.mctl.ai/ → 200/302 (not "no available server")
  • Repeat last 3 checks for labs and ovk

Follow-ups (separate PRs)

  • Investigate mctl-openclaw diff 2026.4.26-beta.1..2026.4.28-beta.2 to decide whether to re-roll admins.
  • The # CLAUDE_CODE_OAUTH_TOKEN — required by the bundled claude-cli backend comment in all three values files is stale (per memory feedback_openclaw_claude_cli_unfit.md, claude-cli was abandoned for openclaw — agent model: openai-codex/gpt-5.4 is the active backend). Drop the secret import.

admins-openclaw on 2026.4.28-beta.2 crash-looped (9 restarts in 35min).
kubectl describe surfaced "Startup probe failed: context deadline exceeded
on /healthz" — k8s default timeoutSeconds=1 is too tight for the openclaw
gateway: plugin install + first response can stall the Node event loop
past 1s, especially while model-pricing fetch (30s) is running. base-service
chart template never rendered timeoutSeconds for any probe, so all three
tenants were vulnerable.

Why these changes:
- helm-charts/base-service: render timeoutSeconds for startup/liveness/
  readiness, plus failureThreshold for liveness/readiness. Defaults match
  k8s defaults (1s / 3 failures), so no behaviour change for other charts.
- services/{admins,labs,ovk}/openclaw: explicit timeoutSeconds (3s startup
  & readiness, 5s liveness) and roomier failureThresholds. Liveness period
  raised 20→30s with 60s initialDelay so the gateway has 150s slack on
  transient stalls before kubelet kills it.
- services/admins/openclaw: pin image back to 2026.4.26-beta.1 (the tag
  labs/ovk run) until we understand whether beta.2 introduced an extra
  startup-time regression on top of the probe issue. Also fixes the
  hardcoded beta.2 reference in the setup init container.
@mashkovd

Copy link
Copy Markdown
Member Author

@codex review

@mashkovd
mashkovd requested a review from Copilot April 28, 2026 21:00
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@mashkovd
mashkovd merged commit 6c54809 into main Apr 28, 2026
@mashkovd
mashkovd deleted the fix/openclaw-probe-timeout-and-admins-rollback branch April 28, 2026 21:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses OpenClaw crash-looping caused by overly tight Kubernetes probe defaults by extending the shared base-service Helm chart to support probe timeout configuration, then tuning probe settings for the three OpenClaw tenants and rolling admins back to a known-good image tag.

Changes:

  • Render timeoutSeconds for startup/liveness/readiness probes (and failureThreshold for liveness/readiness) in the base-service Deployment template.
  • Tune startup/readiness/liveness probe settings in admins/labs/ovk OpenClaw tenant values.
  • Roll admins OpenClaw image + OPENCLAW_VERSION (and a setup initContainer image reference) back to 2026.4.26-beta.1.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
platform-gitops/helm-charts/base-service/templates/deployment.yaml Adds probe fields (timeoutSeconds, plus failureThreshold for liveness/readiness) to rendered Deployment manifests.
platform-gitops/services/admins/openclaw/values.yaml Rolls back admins image/version and applies expanded probe timings to avoid startup probe failures.
platform-gitops/services/labs/openclaw/values.yaml Applies expanded probe timings consistent with the other OpenClaw tenants.
platform-gitops/services/ovk/openclaw/values.yaml Applies expanded probe timings consistent with the other OpenClaw tenants.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 69 to +90
@@ -75,6 +76,8 @@ spec:
port: {{ .Values.probes.liveness.port }}
initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }}
periodSeconds: {{ .Values.probes.liveness.periodSeconds }}
timeoutSeconds: {{ .Values.probes.liveness.timeoutSeconds | default 1 }}
failureThreshold: {{ .Values.probes.liveness.failureThreshold | default 3 }}
{{- end }}
{{- if .Values.probes.readiness }}
readinessProbe:
@@ -83,6 +86,8 @@ spec:
port: {{ .Values.probes.readiness.port }}
initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }}
periodSeconds: {{ .Values.probes.readiness.periodSeconds }}
timeoutSeconds: {{ .Values.probes.readiness.timeoutSeconds | default 1 }}
failureThreshold: {{ .Values.probes.readiness.failureThreshold | default 3 }}
Comment on lines 69 to +90
@@ -75,6 +76,8 @@ spec:
port: {{ .Values.probes.liveness.port }}
initialDelaySeconds: {{ .Values.probes.liveness.initialDelaySeconds }}
periodSeconds: {{ .Values.probes.liveness.periodSeconds }}
timeoutSeconds: {{ .Values.probes.liveness.timeoutSeconds | default 1 }}
failureThreshold: {{ .Values.probes.liveness.failureThreshold | default 3 }}
{{- end }}
{{- if .Values.probes.readiness }}
readinessProbe:
@@ -83,6 +86,8 @@ spec:
port: {{ .Values.probes.readiness.port }}
initialDelaySeconds: {{ .Values.probes.readiness.initialDelaySeconds }}
periodSeconds: {{ .Values.probes.readiness.periodSeconds }}
timeoutSeconds: {{ .Values.probes.readiness.timeoutSeconds | default 1 }}
failureThreshold: {{ .Values.probes.readiness.failureThreshold | default 3 }}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants