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:
- Multitenancy — today every org is a set of generated
.conffiles on a single Asterisk, reloaded with a globalcore reload, and there is no mechanism to shard orgs across nodes. That is the scaling ceiling. - 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
htablelookup. Adding an org = a row, not a monolith reload. - Orgs shard across nodes cleanly (e.g. by DID or
linkedidhash). 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 ODBC —
func_odbcrouting (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)¶
- Stand up Kamailio on staging in front of the staging Asterisk; prove
dispatcherdrain + rolling reload with live test calls. - Add per-tenant routing for a couple of orgs; verify CDR/recording coherence.
- Add the 2nd instance + DMQ + SRV/VIP; test Kamailio failover.
- Promote in front of prod during a quiet window, with the direct-to-Asterisk path kept as fallback.
Related¶
- High availability — where Kamailio fits in the bigger plan
- Multi-carrier trunks · Concurrent-call cap