Drop the ks-ch-sync CronJob: adaptive-export mirrors kubescape state, on change - #274
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Removes the
ks-ch-syncCronJob. Adaptive-export 0.16.4-rc1 and later mirror kubescape state into ClickHouse from Go, writing only when the content actually changes.Why
ks-ch-syncruns apython:3.11-slimpod every 2 minutes that LISTs every ContainerProfile, GETs each one individually, and INSERTs all of them unconditionally. Measured on edge4:About 2,669 stored copies of each profile, and each row carries the container's whole learned behaviour as newline-joined text. That is why
kubescape_profilesreached 501 MB for 234 real profiles.It is not only storage. A single
dx/shadow_profilespanel reading that table cost ~1.95 GiB per query, the panel auto-refreshes every 10–40s, and concurrent refreshes crossed the ClickHouse server's 5.40 GiB total budget — the container was OOMKilled (exit 137) on 2026-09-10 at 09:39:19Z. One open browser tab was sufficient. It also cost the KPI series a tick: the single gap in edge4's 220 measured ticks is that outage.The amplification was never the language. It was a timer with no change detection; a Go rewrite that kept the loop would produce the same table.
What replaces it
internal/ae/kssyncinentlein/dx, shipped in adaptive-export:resourceVersionhas moved, removing the ~235 API calls per run as well.specon a LIST (execs/opens/egress come back empty) — which is exactly why the Python script GETs each object. An informer's cache would hold the truncated objects and mirror empty profiles. LIST for metadata, GET for content.hostname, which the PEM requires (WHERE hostname = gethostname()is injected onto everyclickhouse_dsnread).sync.py, including its spec→label fallbacks, so the existing views read identical rows.The three tables (
kubescape_profiles,kubescape_rogueartifacts,kubescape_trust) are declared in AE's schema exactly as this script created them — same columns, types,MergeTreeengine andORDER BY. No engine change:event_timeleading the sorting key is what makes every re-write distinct, and collapsing it would destroy the profile history, which is currently the only record of how a profile evolved.Order of operations
This PR must land with or after the adaptive-export roll (k8sstormcenter/pixie#105). If both run at once every changed row is written twice; if neither runs, the mirror stops.
ADAPTIVE_KSSYNC_DISABLE=trueis available on AE for a cluster that needs to keep the CronJob temporarily.Verifying after the change
AE logs
listed,fetchedandwrittenper sync. On a steady cluster the correct reading is non-zero listed, zero written — that is the fix working. Zero listed means it read nothing (a withheld grant or a missing CRD), and the note lines say which.🤖 Generated with Claude Code
https://claude.ai/code/session_014GDT6HWiFmRxmUaGFSKjPY