Verify the install
Running pods does not mean a working platform. A worker with no Service, a misconfigured credential,
or a missing route all leave every pod Ready while no data moves.
This page defines what "installed successfully" means.
Before you start
- First sign-in complete
- An agent API key was created
1. Every pod is ready
kubectl -n gen0sec-system get pods
kubectl -n gen0sec get pods
Every pod reports Running and n/n in the READY column. On a correct install there are no
exceptions: nothing is expected to sit unready.
A pod in CrashLoopBackOff still reports status.phase: Running. A --field-selector on phase
reports a broken install as clean, which is why the command above reads the READY column instead.
2. The migration job is gone
kubectl -n gen0sec get job g0s-db-migrate
The output is similar to this:
Error from server (NotFound): jobs.batch "g0s-db-migrate" not found
NotFound is the pass. Helm deletes the job the moment it succeeds. If it is still there, it failed:
kubectl -n gen0sec logs job/g0s-db-migrate.
3. The relay is connected
kubectl -n gen0sec get --raw \
'/api/v1/namespaces/gen0sec/services/g0s-download-api:http/proxy/status/healthz'
The output is similar to this:
{ "status": "ready", "mode": "proxy", "upstream": "https://api.gen0sec.com",
"external_relays": ["geoip", "ids-rules"] }
"mode": "proxy" confirms the relay came up. If the upstream is unreachable, relayed routes answer
502, which a polling agent reads as "ask again later" rather than "the artifact is gone".
Then confirm it is actually authorized upstream, which the mode alone does not tell you:
kubectl -n gen0sec logs deploy/g0s-download-api | grep -i 'relayed from upstream' | tail -5
Any status=401 means your Gen0Sec API key is wrong.
4. The platform serves an agent
This is the check that matters. It makes the same requests an agent makes, from outside the cluster, over your published address.
export GEN0SEC_BASE_URL=https://$ENTRYPOINT_HOST
export GEN0SEC_AGENT_KEY=$(cat ~/.gen0sec/agent-key)
$KIT/scripts/verify-deployment.sh
It checks four things:
- The API refuses unauthenticated callers.
- Configuration is served.
- Threat intelligence and IDS rule bundles are published.
- A downloaded bundle matches the SHA-256 its manifest advertises.
It is read-only and safe to run against production. It exits non-zero and names the failing check.
Run it after every install and every upgrade. It is the cheapest way to catch a deployment that looks healthy and serves nothing.
Offline bundle only: confirm nothing pulls from outside
kubectl -n gen0sec-system get pods -o yaml | grep -E '^\s+image:' | sort -u
kubectl -n gen0sec get pods -o yaml | grep -E '^\s+image:' | sort -u
Every image listed is under your registry. Anything else means a values file was not passed with
-f.
The application runs in gen0sec; only the operators, object store and cache run in
gen0sec-system. Checking one namespace covers well under half the images. Reading the YAML rather
than a container template also catches init containers, which is where the object store's init image
is.
Definition of installed successfully
All five are true:
- Every pod in both namespaces reports
Runningandn/nready. kubectl -n gen0sec get job g0s-db-migratereturnsNotFoundor appears asCompleted.download-apireports"mode": "proxy"with your upstream, and its log shows nostatus=401orstatus=402on relayed paths.verify-deployment.shexits zero.- On the offline bundle method, every image reference is under your registry.
If all five hold, the install is done. If any fail, start at the symptom index.
You may be interested in...
- Upgrade, so you know how to move before you need to
- Roll back, and where the data boundary is
- Known limitations in this release