OpenSIPS Cluster + CLB在腾讯云部署的坑(从尝试到放弃)

想采用Cluster+CLB模式部署OpenSIPS,并不是担心单台OpenSIPS的处理能力。实际上因为媒体流直接建立在OpenSIPS后面的FreeSWITCH上,OpenSIPS仅做信令的load balance,在会议场景下并无压力。

采用Cluster+CLB模式部署是为了OpenSIPS的高可用。为什么不用keepalived是考虑到:

第一,云厂商都禁止了arp广播,只能用keepalived单播模式,也就是一对一的主备(这点其实不是问题,一般也都是一对一主备);

第二,腾讯云的HAVIP据说不对新用户开放了,阿里云的社区直接建议用CLB,亚马逊云还要用awscli工具来让VIP指向某服务器,没有统一的做法,而CLB每家云厂商大同小异;

第三,keepalived主备毕竟比Cluster+CLB浪费了服务器资源。

接下来进入正题,介绍环境、OpenSIPS配置、踩的坑。

一、环境

  1. CLB:10.18.2.77
  2. CLB绑定的EIP:139.155.xxx.xxx
  3. OpenSIPS:10.18.2.197、10.18.2.181
  4. FreeSWITCH:10.18.2.206(实际有两个,为了清晰点讲OpenSIPS的部署,关掉了一个)

二、OpenSIPS配置

#### CLUSTER module
loadmodule "proto_bin.so"
modparam("proto_bin", "bin_port", 5555)
loadmodule "clusterer.so"
modparam("clusterer", "my_node_id", 1)
modparam("clusterer", "sharing_tag", "vip/1=active")
modparam("clusterer", "db_url", "postgres://xxx")

#### DIALOG module
loadmodule "dialog.so"
modparam("dialog", "dlg_match_mode", 1)
modparam("dialog", "default_timeout", 21600)  # 6 hours timeout
modparam("dialog", "db_mode", 2)
modparam("dialog", "db_url","postgres://xxx")
modparam("dialog", "dialog_replication_cluster", 1)
modparam("dialog", "profile_replication_cluster", 1)

上图是Cluster相关配置,原理可以参考下:

https://blog.opensips.org/2018/03/23/clustering-ongoing-calls-with-opensips-2-4/

https://blog.opensips.org/2018/03/27/clustering-presence-services-with-opensips-2-4/

https://blog.opensips.org/2018/03/21/full-anycast-support-in-opensips-2-4/

else if (is_method("INVITE")) {
                if ($fU == "022xxxxxxxx") {
                        sethostport("xxx.xxx.xxx.xxx:5060");
                        t_check_trans();
                        record_route_preset("139.155.xxx.xxx:5060","10.18.2.197:5060");
                        add_rr_param(";r2=on");
                        if (check_address(1,"$si",0,"",$avp(ctx))) {
                            xlog("fix callout invite, si:$si, set:$avp(ctx)\n");
                            fix_nated_sdp(10,$avp(ctx));
                        }
                        route(RELAY);
                } else {
                        record_route_preset("10.18.2.197:5060","139.155.xxx.xxx:5060");
                        add_rr_param(";r2=on");
                        create_dialog();
                        set_dlg_sharing_tag("vip");
                        t_on_reply("save_status");
                }
}

1. 这里用到了double record-routing,注意呼入和呼出时route头顺序的不同

2. route头中内网ip没有用10.18.2.77,而是用了真实的内网ip 10.18.2.197。因为用clb的ip会遇到问题,下面会讲到

三、遇到的问题

1. 为什么RequestLine、Route等字段被改为内网IP了?

刚开始就怀疑腾讯云做了修改,但是CLB控制台并未有说明,CLB作为四层负载均衡去改应用层协议内容,也让我感觉奇怪。后来问了腾讯的技术支持,原来是ALG起的作用,可以看看这篇文章:

http://www.ctiforum.com/news/guonei/578434.html

那么要不要关掉呢?我是让运维给腾讯提了工单,加了关闭的按钮并关闭了ALG。

2. 如果record route头中使用clb ip 10.18.2.77,freeswitch向opensips发送re-invite时会遇到奇怪的问题:

这是在opensips 10.18.2.197上抓的包,可以看到从freeswitch 10.18.2.206发送的re-invite包,udp的dst ip竟然是10.18.2.77!这很难让人理解,CLB没有做dst url的替换吗?

3. record route头中使用真实OpenSIPS ip而不是clb ip

避免了问题2,测试下来呼入正常!呼出正常!看似完美,等等~~为什么有时候呼出会收到运营商的403 forbidden呢?

抓包分析正常呼出和被403拒掉的呼出,完全一样!那么问题就出在出口处了,毕竟403看起来是因为非法的来源ip,难道是因为云厂商的出口ip会变的?

好吧,自己先测试下:

  • 测试场景

    10.18.2.220是clb的地址,后面的cvm的ip是10.18.2.197

    # server端在10.18.2.197,使用nc命令监听UDP的5061端口
    nc -lu 5061

    # client端在10.18.2.207,使用nc命令主动发送请求
    nc -u -p 5061 10.18.2.220 5061

  • # 10.18.2.207侧主动发 经过clb
    # 10.18.2.207侧
    07:10:48.595627 52:54:00:48:24:bd > fe:ee:c4:93:e0:9a, ethertype IPv4 (0x0800), length 47: 10.18.2.207.5061 > 10.18.2.220.5061: UDP, length 5

    # 10.18.2.197侧
    07:20:45.627133 fe:ee:c4:93:e0:9a > 52:54:00:bf:db:49, ethertype IPv4 (0x0800), length 47: 10.18.2.207.5061 > 10.18.2.197.5061: UDP, length 5

  • # 10.18.2.197侧主动发 回的时候也经过了clb
    # 10.18.2.197侧
    07:21:05.905816 52:54:00:bf:db:49 > fe:ee:c4:93:e0:9a, ethertype IPv4 (0x0800), length 47: 10.18.2.197.5061 > 10.18.2.207.5061: UDP, length 5

    # 10.18.2.207侧
    07:21:05.906772 fe:ee:c4:93:e0:9a > 52:54:00:48:24:bd, ethertype IPv4 (0x0800), length 47: 10.18.2.220.5061 > 10.18.2.207.5061: UDP, length 5

  • # 过一段时间后10.18.2.197侧主动发 此时没有经过clb了
    # 10.18.2.197侧
    07:26:02.890328 52:54:00:bf:db:49 > fe:ee:c4:93:e0:9a, ethertype IPv4 (0x0800), length 47: 10.18.2.197.5061 > 10.18.2.207.5061: UDP, length 5

    # 10.18.2.207侧
    07:26:02.891358 fe:ee:c4:93:e0:9a > 52:54:00:48:24:bd, ethertype IPv4 (0x0800), length 47: 10.18.2.197.5061 > 10.18.2.207.5061: UDP, length 5

是不是很神奇?从cvm出去的包有时候是不经过CLB的。

和腾讯云方面抓包确认问题,好么,对方说这是“串流”现象:

https://cloud.tencent.com/document/product/214/5411#19

是由于底层封装逻辑导致的(这应该就是bug),并且目前还没有修复的打算。

问题现在就很清楚了:由于腾讯云的”串流“,导致移动运营商看到的IP,有可能是CLB绑定的EIP,也有可能是opensips服务器的真实外网IP;而我们让运营商配置的IP只是EIP,这也导致了呼出时,有时被403拒掉。

那么怎么解决呢?是不是把真实外网IP也配置到运营商那边?这是不合理的,不能基于有问题的基础往下走。至此,笔者已经决定放弃CLB了 。

如果有SIP方面的大神,希望可以对这种case指导下!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值