Skip to content

Kamailio SIP Proxy (multitenancy + zero-downtime) — design

Status: PLANNED — not yet implemented

This captures the agreed design for putting Kamailio in front of the Asterisk media nodes. No code/config is deployed yet. Prove it on staging first (Kamailio in front of the staging Asterisk) before it fronts prod.

Why Kamailio

Two problems it solves at once, both currently structural limits:

  1. Multitenancy — today every org is a set of generated .conf files on a single Asterisk, reloaded with a global core reload, and there is no mechanism to shard orgs across nodes. That is the scaling ceiling.
  2. Zero-downtime — today any Asterisk restart/upgrade risks live calls and needs a quiet window.

Kamailio is a stateless SIP proxy / registrar / load-balancer that sits in front of a pool of Asterisk media nodes. Routing decisions move up out of the monolithic dialplan; Asterisk becomes a near-stateless media worker.

Role in the stack

   carriers + customer endpoints (register / INVITE)
                     │  SIP (DNS NAPTR/SRV: Kamailio-A primary, Kamailio-B secondary)
        ┌─────────────────────────┐   DMQ (usrloc/htable replication)
        │  KAMAILIO-A  ◄──────────►  KAMAILIO-B   │   active/active, floating VIP on-prem
        │  • registrar (usrloc)                   │
        │  • dispatcher (OPTIONS-healthchecked)   │
        │  • per-tenant routing (DB / htable)     │
        │  • RTPengine = SBC (NAT, topology hide) │
        └──────────────┬──────────────────────────┘
                       │ route by domain / DID / source-IP → org → node
        ┌──────────────┼───────────────┐
        ▼              ▼               ▼
   Asterisk NUC-1   Asterisk NUC-2   Asterisk cloud-1     (media pool)

How it delivers each goal

Multitenancy (routing layer, not config files)

  • Kamailio routes by domain / DID / source-IP → org → media node, via a DB or htable lookup. Adding an org = a row, not a monolith reload.
  • Orgs shard across nodes cleanly (e.g. by DID or linkedid hash). This is the org-sharding mechanism the platform lacks today.

Zero-downtime upgrades (dispatcher)

  • Kamailio health-checks each Asterisk node with SIP OPTIONS.
  • To patch/upgrade a node: drain it (dispatcher stops sending new calls), let active calls finish, upgrade, re-add → new calls go to the survivors throughout. Rolling upgrades, no maintenance window.
  • A dead node is removed from rotation automatically in seconds → node failure ≠ outage.

HA of Kamailio itself (so it isn't a new SPoF)

  • Two instances: A on-prem (floating VIP via keepalived/VRRP), B in cloud (SIP SRV secondary — fills today's "no SIP SRV" gap).
  • Registrations (usrloc) replicated A↔B via DMQ, so a Kamailio failover does not drop registrations.

SBC role (with RTPengine)

  • Pair Kamailio with RTPengine for NAT traversal, topology hiding, and optional media anchoring / transcoding offload — letting carriers and customer endpoints fail over cleanly and taking transcode load off Asterisk.

What must be preserved when Asterisk moves behind Kamailio

Asterisk still depends on cloud-side services — keep these reachable from every media node (see system overview):

  • MariaDB via ODBCfunc_odbc routing (sticky-agent, per-user DID, spam-block) + CDR.
  • AMI — config push from the AstraPBX API.
  • Recordings — MixMonitor → move-recordings.sh → Firebase/GCS.

Sharding orgs across nodes also means CDR dedup (linkedid) and multi-leg recording stitching must remain coherent across nodes.

Rollout (staging first)

  1. Stand up Kamailio on staging in front of the staging Asterisk; prove dispatcher drain + rolling reload with live test calls.
  2. Add per-tenant routing for a couple of orgs; verify CDR/recording coherence.
  3. Add the 2nd instance + DMQ + SRV/VIP; test Kamailio failover.
  4. Promote in front of prod during a quiet window, with the direct-to-Asterisk path kept as fallback.