Skip to main content

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

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.

Check readiness, not phase

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:

  1. The API refuses unauthenticated callers.
  2. Configuration is served.
  3. Threat intelligence and IDS rule bundles are published.
  4. 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.

Why both namespaces, and why read the YAML

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:

  1. Every pod in both namespaces reports Running and n/n ready.
  2. kubectl -n gen0sec get job g0s-db-migrate returns NotFound or appears as Completed.
  3. download-api reports "mode": "proxy" with your upstream, and its log shows no status=401 or status=402 on relayed paths.
  4. verify-deployment.sh exits zero.
  5. 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...