Hosting topologies
This page describes where and how to host the Navin Platform: on premises servers installed from packages, Kubernetes clusters, the high availability topology, several sites and disaster recovery. Each topology lists what the repository provides and what stays the responsibility of the hosting team.
On premises servers (OS packages)
| Topology | Hosts | When |
|---|---|---|
| Standalone | One server: Navin Manager, agent, platform (API, worker, portal) and local PostgreSQL | Pilot, small entity, isolated site |
| Cluster | One Navin Manager host, nodes with the agent navin-manager-agent; the Manager installs the services on the nodes | Several servers without Kubernetes |
| Platform with the services of the bank | Platform host with the PostgreSQL, Keycloak, Redis and OpenBao servers that the bank already runs | Shared infrastructure, central operations |
The services listen in plain HTTP (8080, 3300): a TLS reverse proxy of the bank is always in front of them
(TLS). The database moves to an external server with navin-platform-db external, with TLS
(sslmode=verify-full). Guided installation: OS packages; Manager and nodes:
os/install/README.md.
High availability of the services installed by the Navin Manager (PostgreSQL with Patroni and etcd, Redis Sentinel,
NATS JetStream R3) is described in navin-manager/docs/availability.en.md, with the measured local failover times and
their limits (asynchronous replication: zero loss is measured, not guaranteed).
Kubernetes
One cluster per environment (dev, staging, prod), each registered in Argo CD with the label
eai.io/environment. The namespaces are created by the bootstrap with their Pod Security level:
| Namespace | Content |
|---|---|
enterprise-ai | Control Plane API, worker, portal, LiteLLM, vLLM, Ollama, media workers |
eai-sandbox | Sandboxes of the tools and of the code interpreter (gVisor, Kata) |
eai-data | PostgreSQL, Redis, NATS, Qdrant, Temporal, LiveKit |
eai-security | Keycloak, OpenFGA, OPA |
openbao | OpenBao (raft) |
observability, observability-agents | Prometheus, OpenSearch, Jaeger, Opik, ClickHouse, OpenTelemetry Collector, Alloy |
apisix | API gateway |
toolhive-system, mcp-<id> | ToolHive Operator and the MCP Runtime namespaces |
Installation: Kubernetes with Helm.
High availability topology
Use values-prod.yaml then values-ha.yaml on a cluster with at least three nodes in three zones.
| Component | Topology | Source |
|---|---|---|
| Control Plane API | 3 to 20 replicas (HPA), PDB minAvailable: 2, required zone anti affinity, spread over hostnames, 60 s graceful shutdown | values-prod.yaml, values-ha.yaml |
| Portal, LiteLLM | 3 replicas minimum, PDB minAvailable: 2 | values-prod.yaml, values-ha.yaml |
| Worker | 1 active replica per plane, PostgreSQL advisory lock; extra replicas wait for the lock | values.yaml (worker) |
| PostgreSQL | CloudNativePG, 3 instances, automatic failover, WAL archive to S3 | deploy/data/postgres/cluster.yaml |
| NATS JetStream | 3 replicas | deploy/data/nats/values.yaml |
| Qdrant | 3 nodes, 3 shards, 2 replicas per shard: one node may be lost | deploy/data/qdrant/values.yaml, EAI_QDRANT_* |
| OpenBao | 3 node raft | deploy/openbao/values.yaml |
| Temporal | 3 replicas | deploy/data/temporal/values.yaml |
| Redis | Replication through the operator; the rate limits of APISIX tolerate a transient loss; no backup needed (cache rebuilt from PostgreSQL) | deploy/data/redis/values.yaml |
| vLLM | Replicas of one model on distinct GPU nodes with vllm.antiAffinity: required, PodDisruptionBudget | values.yaml (vllm) |
A rendered manifest proves the configuration only (HA_CONFIGURED). A topology is validated (HA_VALIDATED) only
after a recorded failover test on a real cluster.
Recovery objectives
Targets of High availability and disaster recovery:
| Scope | RPO | RTO |
|---|---|---|
| PostgreSQL (CloudNativePG, continuous WAL) | 5 min | 30 min |
| WORM audit archive (S3 object lock, replication) | 0 (synchronous write) | 1 h |
| Kubernetes configuration (hourly Velero and GitOps) | 1 h | 1 h |
| Qdrant indexes (daily snapshots, reindex possible) | 24 h | 4 h |
| OpenBao (daily raft snapshot, 3 node raft) | 24 h | 1 h |
| vLLM inference (stateless) | not applicable | 15 min (model from the cache) |
Multi-site and disaster recovery
The repository provides one active site per environment and a recovery site restored from the backups. An active
active deployment across several sites is not provided: the Navin Manager marks MULTI_CLUSTER as unsupported.
- Several clusters, one Argo CD. A central Argo CD manages several clusters: register each one with
argocd cluster add <kube-context> --label eai.io/environment=<env>and add its address todestinationsofdeploy/argocd/appproject.yaml. The second site receives the same manifests from Git. - Backups outside the site. CloudNativePG archives the WAL and a daily base backup to
s3://eai-backups/cnpg(retention 30 days, encrypted). Velero runseai-platform-daily(volumes,pg_dumpall, Qdrant snapshot, OpenBao raft snapshot hooks, 30 days) andeai-config-hourly(configuration, 7 days). Replicate these buckets and the WORM bucket to the object storage of the recovery site. - Recovery. On the recovery cluster: bootstrap and
infralayer, OpenBao restored from its raft snapshot, PostgreSQL restored with a new CloudNativePGClusterandbootstrap.recovery(point in time withrecoveryTarget.targetTime), thenvelero restore create --from-backup <backup>and theappslayer. - Drill every quarter. Restore into isolated namespaces (
deploy/velero/restore-test.yaml, or--namespace-mappings enterprise-ai:enterprise-ai-drill), runGET /v1/audit/verify, record the measured RPO and RTO. - Isolated site. Reinstall from the signed bundle verified offline (Air-gapped installation).
The recovery procedure has been validated offline only (manifests rendered and checked against the pinned schemas). Run the drill on an acceptance cluster before you rely on the objectives above.