Skip to content

fix(scanner): reap finished scanner jobs independent of TTLAfterFinished controller - #492

Merged
mayankpande88 merged 2 commits into
mainfrom
feat/scanner-job-reaper
Jun 24, 2026
Merged

fix(scanner): reap finished scanner jobs independent of TTLAfterFinished controller#492
mayankpande88 merged 2 commits into
mainfrom
feat/scanner-job-reaper

Conversation

@mayankpande88

Copy link
Copy Markdown
Contributor

Description

Scanner Jobs (trivy image scan, popeye, kube-bench, trivy CIS, helm chart upgrade) were only cleaned up by the cluster's TTLAfterFinished controller — every Job is stamped with TTLSecondsAfterFinished=600 and nothing else deletes them. That controller is GA/on-by-default since k8s 1.21 but can be disabled in customer environments (hardened/managed distros, explicit --controllers=-ttl-after-finished, or pre-1.21). When it's off, finished Jobs and their Completed pods accumulate indefinitely.

This adds an in-agent background reaper so cleanup never depends on the cluster having that controller:

  • StartReaper runs a 60s-ticker goroutine (cancelled by the agent shutdown ctx) that deletes the agent's own finished Jobs once they're more than 600s past completion, cascade-deleting their pods (PropagationPolicy=Background).
  • Strictly scoped: only Jobs carrying both app.kubernetes.io/managed-by=nudgebee-agent and nudgebee.com/orchestrator=api-server, in the runner's namespace. Customer Jobs are never touched.
  • 600s grace mirrors the existing TTLSecondsAfterFinished semantics, preserving the log-availability window for retries/manual debugging.
  • No-op where the TTL controller is present (it typically wins the race).

Also adds a delete_k8s_job primitive so the api-server orchestrator can delete a Job promptly after fetching its logs (happy-path cleanup); the reaper is the backstop for crash/timeout paths.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

  • Unit tests: past-grace deletion (Complete + Failed), fresh/running survival, unmanaged-Job safety, cascade propagation, handler registration
  • go build ./..., go vet, go test ./pkg/scanners/... pass

Review Notes

Risks & Counterarguments

  • Re-implements TTLAfterFinished in-agent. Intentional — the whole point is to not depend on the cluster controller. Where the controller exists this is a harmless no-op.
  • Grace race with log fetch. Reaper gates on completion + 600s; the orchestrator fetches logs within seconds of completion, so a finished Job is never deleted before its logs are read.
  • Failed Jobs have no CompletionTimejobFinishedAt falls back to the terminal condition's LastTransitionTime.

@mayankpande88
mayankpande88 requested a review from a team as a code owner June 24, 2026 07:31

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a new delete_k8s_job handler and a background reaper service to clean up finished Kubernetes jobs and pods, making cleanup independent of the cluster's TTLAfterFinished controller. The feedback focuses on enhancing the robustness of the background reaper by suggesting a limit on the list query to prevent memory spikes, adding a timeout to context execution to avoid hanging on unresponsive API servers, and suppressing warning logs for expected context cancellations during shutdown.

Comment thread runner/pkg/scanners/reaper.go
Comment thread runner/pkg/scanners/reaper.go
Comment thread runner/pkg/scanners/reaper.go
Comment thread runner/pkg/scanners/reaper.go
@github-actions

Copy link
Copy Markdown
Contributor

📦 Image Tags Updated

I've automatically updated the image tags in `charts/nudgebee-agent/values.yaml` to the latest versions from GHCR for the `main` branch.

The image tags are now synchronized with the latest builds and ready for release.

mayankpande88 and others added 2 commits June 24, 2026 14:06
…hed controller

Scanner Jobs were only cleaned up by the cluster's TTLAfterFinished
controller (via TTLSecondsAfterFinished=600). That controller can be
disabled in customer environments, leaving finished Jobs and their
Completed pods to accumulate forever.

Add a background reaper that periodically deletes the agent's own
finished Jobs (cascading to their pods) once past the same 600s grace
the TTL field encodes. It is strictly label- and namespace-scoped so it
can never touch customer Jobs, and is a no-op where the TTL controller
is present. Also add a delete_k8s_job primitive so the orchestrator can
delete a Job promptly after fetching its logs.
@mayankpande88
mayankpande88 force-pushed the feat/scanner-job-reaper branch from bb27efc to 105f67b Compare June 24, 2026 08:36
@github-actions

Copy link
Copy Markdown
Contributor

📦 Image Tags Updated

I've automatically updated the image tags in `charts/nudgebee-agent/values.yaml` to the latest versions from GHCR for the `main` branch.

The image tags are now synchronized with the latest builds and ready for release.

@mayankpande88
mayankpande88 merged commit 3a1509d into main Jun 24, 2026
8 checks passed
@mayankpande88
mayankpande88 deleted the feat/scanner-job-reaper branch June 24, 2026 09:11
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