Idea to have 2 instances of Freeswitch in Master-Slave mode, if one node dies, second will automatically takeover calls with 2-3 seconds lag. Yep, media would be restored.
Main scheme is looks like this
We need 3 IP's. 2 for nodes and 1 for floating.
Solution based on this, but with a bit of additional config.
Used Debian 8x64 as a host OS.
Assume, that we have FreeSWITCH'es already installed.
Install keepalived on both nodes.
apt-get install keepalived
Create files on both nodes
/etc/keepalived/keepalived.conf
global_defs {
router_id FREESW
}
vrrp_script chk_fs {
script "/etc/keepalived/scripts/ka-status.pl"
interval 1
}
vrrp_instance VI_FREESW {
# replace with SLAVE on a slave node
state MASTER
# change to SLAVE on slave node
interface <YOUR_INTERFACE_HERE>
#interface eth0
virtual_router_id <YOUR_ROUTER_ID>
# virtual_router_id 15
# higher is preferred for master
# disable to have failover be sticky
priority 1
advert_int 1
unicast_src_ip <CURRENT_NODE_IP>
#unicast_src_ip 192.168.10.10
unicast_peer {
<SLAVE_NODE_IP>
#192.168.10.11
}
authentication {
auth_type PASS
auth_pass YourPassHere
}
notify "/etc/keepalived/scripts/ka-notify.pl"
virtual_ipaddress {
<FLOATING_IP/CIDR> dev <YOUR_INTERFACE_HERE>
# 192.168.0.15/24 dev eth0 - Example
}
track_script {
chk_fs
}
}
/etc/keepalived/scripts/ka-notify.pl
#!/usr/bin/perl
# INSTANCE|VI_FREESW|BACKUP|50
my ($what,$id,$state,$prio) = @ARGV;
open(STDOUT, "|/usr/bin/logger -t ka-notify");
print "what($what) id($id) state($state) prio($prio)\n";
if ( $state eq "MASTER" )
{
print "Instance went to master, issuing sofia recover.\n";
system("/usr/bin/fs_cli", "-x", "sofia recover");
}
/etc/keepalived/scripts/ka-status.pl
#!/usr/bin/perl
use Sys::Syslog;
openlog "ka-status", "ndelay,pid", "local0";
my @required = ("internal", "external");
my %saw = ();
open(my $in, "-|") || exec("/usr/bin/fs_cli", "-x", "sofia xmlstatus");
while ( defined(my $line = <$in>) )
{
if ( $line =~ m|<name>(.*)</name>|o )
{
$saw{$1} = 1;
}
}
close($in);
foreach my $profile ( @required )
{
if ( ! $saw{$profile} )
{
syslog(LOG_INFO, "sip profile $profile not found, marking failure");
exit(1);
}
}
exit(0);
chmod +x /etc/keepalived/scripts/*.pl
echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf
Make sure, that FreeSWITCH'es uses same runtime database and uses same hostname in switch.conf Also profiles you control, need to listen on FLOATING_IP address.
Better reboot here.
service keepalived start
To check state, best is to use ip addr show. On which node FLOATING_IP address is, this is master :)
You can play with priority parameter in keepalived.conf file to make one node Master at all cases.
Point, there is a issue, when you restore calls on one node, you can't get same calls back with sofia recover.
Hi, thank you so much for writing this post. I followed exactly same method but floating IP doesn't get assigned to any freeswitch server and we keep getting below errors on both freeswitch servers.
ReplyDeleteMar 31 09:46:55 fs-ha-2 Keepalived_vrrp[5333]: Opening script file /etc/freeswitch/ka-notify.pl
Mar 31 09:46:55 fs-ha-2 Keepalived_vrrp[5333]: Opening script file /etc/freeswitch/ka-notify.pl
Mar 31 09:46:55 fs-ha-2 ka-notify: what(INSTANCE) id(VI_FREESW) state(FAULT) prio(1)
Mar 31 09:46:55 fs-ha-2 ka-notify: what(INSTANCE) id(VI_FREESW) state(FAULT) prio(1)
Mar 31 09:47:01 fs-ha-2 ka-status[5353]: sip profile internal not found, marking failure
Mar 31 09:47:01 fs-ha-2 ka-status[5352]: sip profile internal not found, marking failure
Any suggestions please? Thanks