Skip to main content

Navin Cluster Agent

The Navin Cluster Agent (module navin-manager/cluster-agent, Go) runs inside a Kubernetes cluster managed by navin-manager. It reports the cluster inventory and applies the ManagedComponent changes asked by the manager, after verifying the signature of every command. Reference: CONTRACT.md section 7.14.

Import of a cluster without SSH​

A cluster is imported through its API only. Fetch the least privilege RBAC of the import identity:

GET /api/v1/clusters/{cluster_id}/kubernetes/import-rbac?namespace=navin-platform

Apply the returned yaml with an administrator account, then register the cluster with a kubeconfig holding the token of the navin-import ServiceAccount (kubectl -n navin-platform create token navin-import). That identity may read nodes, namespaces, CRDs, storage classes and ingress classes, read the CoreDNS Deployment, and write only the platform.navin.ai resources of the managed namespace. Secrets, workloads, RBAC objects and every other namespace are refused.

Install​

  1. Issue the identity of the agent of this cluster (one per cluster; a new one revokes the previous one): POST /api/v1/clusters/{cluster_id}/kubernetes/agent {"gateway_url": "https://manager.example:8462"}. The answer holds the client certificate and its private key (returned once, never stored), the manager CA, the manager public key and the signed configuration.
  2. Create the Secret navin-cluster-agent-identity in the managed namespace with the files config.json (the config object), manager.pem, tls.crt, tls.key and ca.crt.
  3. Apply the manifests of GET /api/v1/clusters/{cluster_id}/kubernetes/agent/manifests?image=<image@sha256:...>: ServiceAccount, RBAC and a Deployment of 2 replicas (pod anti affinity, non root, read only file system).

RBAC of the agent​

  • cluster scope, read only: nodes, namespaces, CRDs, storage classes, ingress classes, /version, /api, /apis;
  • managed namespace: the Lease navin-cluster-agent (get, create, update), the ConfigMap navin-cluster-agent-state (create, get and update of that name only), events, and the platform.navin.ai resources. No Secret, no workload.

The Kubernetes identity is the ServiceAccount token of the pod: it is valid on this cluster only. The manager identity is the client certificate: the gateway serves to it the commands of this cluster only and refuses (403, audited) a receipt for the command of another cluster.

Outbound connection​

The agent opens every connection: HTTPS (TLS 1.2 or newer) to the manager gateway with its client certificate, the manager CA as the only trusted issuer, proxies of the environment ignored. No Service, no inbound port. It long polls GET /v1/cluster-agent/commands (up to 30 s), posts the inventory to /v1/cluster-agent/report and every result to /v1/cluster-agent/receipts. The manager starts the gateway with python -m navin_manager.kubernetes.agent_gateway --host <address> --port <port> --tls-dir <dir> --server-name <name>.

High availability​

Only the replica holding the Lease acts. When it disappears, another replica takes the Lease after its expiry (lease_duration_s, 15 s by default) and continues with the same nonces, receipts and desired state, kept in the ConfigMap navin-cluster-agent-state. A command delivered to the lost leader without receipt is delivered again by the gateway after 15 s; if it had already run, the new leader refuses it as nonce_replayed with the original result, and the manager keeps the original status.

Commands​

Every command is a signed envelope (Ed25519, canonical JSON, same envelope as the Node Agent). It is refused on an invalid signature, an unknown key, another target or tenant, an expired or future validity window, or a nonce already used. Operations: managedcomponent.apply {name, spec}, managedcomponent.delete {name} (sensitive) and inventory.report (read only).

Offline behaviour​

The configuration is signed: a modified configuration is refused at start. When the manager cannot be reached for offline_after_s, the agent is offline:

  • it keeps re-applying the last approved desired state (a component modified or deleted by hand is restored); a desired state whose signature no longer verifies is not applied;
  • it refuses every new sensitive operation with manager_unreachable, also a validly signed command dropped in the break glass directory --inbox (each <name>.json is answered in <name>.receipt.json);
  • read only operations still run. Receipts are sent again when the manager is back.