Kamailio 是一个高性能、可扩展的 SIP Server,广泛应用于 SIP Proxy、Registrar、负载均衡、路由控制以及 VoIP 核心网络。
对于已经熟悉 Docker 的开发者来说,使用容器运行 Kamailio 可以避免直接在 Linux 主机上安装大量依赖,同时也方便进行版本管理、配置管理和环境迁移。
本文介绍如何使用 Kamailio 官方 Docker 镜像快速部署一个 SIP Proxy,并进一步介绍 Kamailio 与 FreeSWITCH 配合使用的典型架构。
1. Kamailio Docker 镜像
Kamailio 官方提供了 Docker 镜像。
目前官方镜像主要发布在 GitHub Container Registry(GHCR):
dockerpull ghcr.io/kamailio/kamailio:latest官方 Docker 项目:
Kamailio Docker GitHub Repository
可以先检查镜像:
dockerimages|grepkamailio例如:
ghcr.io/kamailio/kamailio latest xxxxx ...生产环境不建议长期使用latest,最好固定到具体版本。
例如:
dockerpull ghcr.io/kamailio/kamailio:6.0具体可用的 Tag 可以在官方镜像仓库中确认。
2. 最简单的运行方式
Kamailio 是 SIP Server,因此除了 SIP 端口之外,还需要考虑 RTP。
需要注意的是:
Kamailio 本身通常不负责 RTP Media。
它主要处理 SIP signaling。
因此,一个简单的 Kamailio 容器可以这样启动:
dockerrun-d\--namekamailio\--networkhost\ghcr.io/kamailio/kamailio:latest这里使用:
--network host对于 SIP Server 非常方便。
因为 SIP 通常涉及:
UDP 5060 TCP 5060 TLS 5061如果使用 Docker bridge network,则需要额外配置端口映射。
对于生产环境中的 SIP Proxy,Host Network 往往能够减少 NAT、端口映射以及 SIP Contact/Via 地址处理方面的问题。
3. 为什么 SIP Server 更适合考虑 Host Network
普通 Web 服务通常可以这样:
Internet | v Docker Host | +---- 8080 -> Container 80但是 SIP 比较特殊。
例如:
INVITE sip:1001@example.com SIP/2.0 Via: SIP/2.0/UDP 10.0.0.10:5060 Contact: <sip:1001@10.0.0.10:5060>SIP 消息里面本身就包含 IP 地址和端口。
如果 Docker 使用 NAT:
Internet | v Host:5060 | Docker NAT | v Container:5060就可能需要处理:
- Via
- Contact
- Record-Route
- SDP
- NAT traversal
- source IP
- advertised IP
因此,对于一个直接暴露 SIP 服务的 Kamailio 实例:
dockerrun--networkhost...通常是一个比较简单可靠的方案。
4. 使用自己的 Kamailio 配置
实际部署中不应该直接使用容器内部的默认配置。
通常把配置文件放到 Host:
/opt/kamailio/ ├── kamailio.cfg ├── tls.cfg └── dispatcher.list然后通过 Volume Mount 到容器。
例如:
dockerrun-d\--namekamailio\--networkhost\-v/opt/kamailio:/etc/kamailio\ghcr.io/kamailio/kamailio:latest这样:
Host /opt/kamailio/kamailio.cfg | | volume mount v Container /etc/kamailio/kamailio.cfg修改配置后可以重新加载或者重启容器。
5. 一个最简单的 Kamailio 配置
下面是一个非常简单的 SIP Proxy 示例。
#!KAMAILIO listen=udp:0.0.0.0:5060 loadmodule "sl.so" loadmodule "tm.so" loadmodule "rr.so" loadmodule "maxfwd.so" loadmodule "textops.so" request_route { if (!mf_process_maxfwd_header("10")) { sl_send_reply("483", "Too Many Hops"); exit; } if (is_method("OPTIONS")) { sl_send_reply("200", "OK"); exit; } if (is_method("INVITE|REGISTER")) { record_route(); } if (!t_relay()) { sl_reply_error(); } exit; }这里最核心的是:
t_relay();Kamailio 收到 SIP Request 后,可以根据路由逻辑决定下一跳,然后把 SIP 消息转发出去。
6. Kamailio + FreeSWITCH
Kamailio 最常见的应用之一,就是作为 FreeSWITCH 前面的 SIP Proxy。
一个典型架构:
Internet | | SIP INVITE | v +----------------+ | Kamailio | | SIP Proxy | +-------+--------+ | | v +----------------+ | FreeSWITCH | | Media Server | +----------------+ | | RTP / MediaKamailio 负责:
- SIP Routing
- Registrar
- Authentication
- Load Balancing
- Failover
- Dispatcher
- NAT handling
- SIP filtering
- SIP topology control
FreeSWITCH 负责:
- Media
- Bridge
- IVR
- Recording
- Conference
- Playback
- Application logic
这样可以把:
SIP Signaling和:
Media Processing分离。
7. Kamailio + 多个 FreeSWITCH
当 FreeSWITCH 数量增加以后,Kamailio 的优势更加明显。
例如:
Internet | v +---------------+ | Kamailio | | SIP Proxy/LB | +-------+-------+ | +--------------+--------------+ | | | v v v +---------+ +---------+ +---------+ | FS-1 | | FS-2 | | FS-3 | +---------+ +---------+ +---------+Kamailio 可以通过 dispatcher 等模块实现:
SIP | +---- FS-1 | +---- FS-2 | +---- FS-3例如:
loadmodule "dispatcher.so" modparam("dispatcher", "list_file", "/etc/kamailio/dispatcher.list")dispatcher.list:
1 sip:10.10.10.101:5060 1 sip:10.10.10.102:5060 1 sip:10.10.10.103:5060然后在 Kamailio 中:
ds_select_dst("1", "4"); t_relay();就可以根据 Dispatcher 的策略选择 FreeSWITCH 节点。
8. 使用 Docker Compose
如果 Kamailio 和 FreeSWITCH 都运行在 Docker 中,可以使用 Docker Compose 管理。
例如:
services:kamailio:image:ghcr.io/kamailio/kamailio:latestcontainer_name:kamailionetwork_mode:hostvolumes:-./kamailio:/etc/kamailiorestart:unless-stoppedfreeswitch:image:my-freeswitch:latestcontainer_name:freeswitchnetwork_mode:hostrestart:unless-stopped启动:
dockercompose up-d查看:
dockercomposeps查看 Kamailio 日志:
dockerlogs-fkamailio进入容器:
dockerexec-itkamailiobash9. 查看 Kamailio 运行状态
可以首先检查容器:
dockerps然后检查 SIP 端口:
ss-lunp|grep5060或者:
ss-lntup|grep5060也可以直接使用sngrep:
sngrep这对于 SIP 问题定位非常方便。
例如:
INVITE Client ----------------> Kamailio INVITE Client <---------------- Kamailio INVITE Kamailio ---------------> FreeSWITCH通过sngrep可以非常直观地看到 SIP signaling。
10. Docker 环境中的日志
Kamailio 的日志通常可以直接输出到 Docker stdout/stderr。
因此:
dockerlogs kamailio就可以查看。
实时查看:
dockerlogs-fkamailio如果需要生产环境日志管理,可以进一步接入:
Docker | +---- Fluent Bit | +---- Elasticsearch | +---- Loki | +---- Cloud logging这样 Kamailio 本身不需要负责复杂的日志轮转。
11. 不要把 SIP Server 和 RTP 混为一谈
这是部署 Kamailio 时非常容易踩的坑。
Kamailio:
SIP SignalingFreeSWITCH:
SIP + RTP + Media Application如果架构是:
Client | | SIP v Kamailio | | SIP v FreeSWITCH那么 Kamailio 不一定需要看到 RTP。
媒体可以:
Client <=================> FreeSWITCH RTP这也是 Kamailio + FreeSWITCH 架构比较常见的原因。
12. Docker 部署 Kamailio 的几个注意事项
12.1 固定版本
生产环境不要:
image:ghcr.io/kamailio/kamailio:latest更建议:
image:ghcr.io/kamailio/kamailio:6.x.x这样升级不会因为latest自动变化而导致生产环境行为发生变化。
12.2 配置文件不要写进 Image
不推荐:
COPY kamailio.cfg /etc/kamailio/如果配置经常变化,更适合:
Host | +-- kamailio.cfg | +-- dispatcher.list | +-- tls.cfg | +-- docker compose通过 Volume 注入。
这样升级 Image 不会影响配置。
12.3 SIP 服务需要特别关注网络模式
如果使用:
bridge需要认真处理:
SIP NAT RTP Contact Via advertised address如果部署环境允许,直接:
network_mode:host通常更加简单。
13. 总结
使用官方 Kamailio Docker 镜像,可以把传统的:
Linux | +-- Kamailio +-- dependencies +-- configuration转换成:
Docker Host | +-------------------+ | Kamailio | | Docker | +-------------------+进一步结合 FreeSWITCH:
SIP | v +-----------+ | Kamailio | | Docker | +-----+-----+ | SIP | v +-----------+ |FreeSWITCH | | Docker | +-----------+ | RTP这种架构尤其适合:
- SIP Proxy
- SIP Registrar
- SIP Load Balancer
- FreeSWITCH 集群
- VoIP SBC 前端
- SIP Failover
- 多 FreeSWITCH 节点路由
- 开发/测试环境快速搭建
对于已经使用 Docker 的 VoIP 环境,Kamailio 容器化最大的价值并不是“把 Kamailio 放进 Docker”,而是让 SIP Routing 层和 Media Server 层拥有独立的生命周期、版本和扩缩容能力。