Gmane
From: Christophe Yayon <lists <at> nbux.com>
Subject: keepalived and LVS-DR directors are also realservers
Newsgroups: gmane.linux.keepalived.devel
Date: 2005-09-10 08:28:04 GMT (3 years, 42 weeks, 3 days, 23 hours and 25 minutes ago)
Hi all,

I know, this subject have already been discussed, but i have never found 
a real solution...
Here my sample topologie :

2 GNU/Linux servers which are smtp (postfix-amavisd, etc...) reals 
servers and ipvs directors (active/active for smtp and failover mode for 
directors).

If i leave keepalived 'do to it himself', when i try to connect to smtp 
port of vip, i can see loop packets in tcpdump, and my request (on smtp 
port) timed out ...

Here is my ugly workaround :
I am playing with notifications (master/backup/fault) ; when keepalived 
become backup i save current ipvs rules (ipvsadm -S) to a file 
(/var/lib/ipvs/ipvs.rules), and clear all currents rules (ipvsadm -C). 
When keepalived become master, i just restore this rules (ipvsadm -R) 
from my file (/var/lib/ipvs/ipvs.rules) if it exist/not empty of 
course... and when keepalived fault, i just clear rules, but in this 
case i am not sure...

Here is my sample configuration :

RIP1 : 10.133.100.103/24 (default MASTER)
RIP2 : 10.133.100.104/24 (default BACKUP)
VIP  : 10.133.100.107/24

I have setup the vip on lo:0 alias on both node, but with a netmask /32, 
here is what i get on both node :

- MASTER
2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
     link/ether 00:12:79:90:60:56 brd ff:ff:ff:ff:ff:ff
     inet 10.133.100.103/24 brd 10.133.100.255 scope global eth0
     inet 10.133.100.107/24 brd 10.133.100.255 scope global secondary eth0
4: lo: <LOOPBACK,UP> mtu 16436 qdisc noqueue
     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
     inet 127.0.0.1/8 scope host lo
     inet 10.133.100.107/32 scope global lo:0

- BACKUP
2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
     link/ether 00:12:79:93:f2:00 brd ff:ff:ff:ff:ff:ff
     inet 10.133.100.104/24 brd 10.133.100.255 scope global eth0
4: lo: <LOOPBACK,UP> mtu 16436 qdisc noqueue
     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
     inet 127.0.0.1/8 scope host lo
     inet 10.133.100.107/32 scope global lo:0

# MASTER node :
global_defs {
         notification_email {
                 sso <at> sofinco.fr
         }
         notification_email_from root <at> uxprod50.sofinco.fr
         smtp_server smtp.mail.sofinco.fr
         smtp_connect_timeout 30
         lvs_id LVS_AMAVIS_MASTER
}

vrrp_instance ID_200 {
         state BACKUP
         interface eth0
         virtual_router_id 200
         lvs_sync_daemon_interface eth0
         priority 100
         authentication {
                 auth_type PASS
                 auth_pass myvrrppassword
         }
         virtual_ipaddress {
                 10.133.100.107/24 brd 10.133.100.255 dev eth0
         }

         notify_master "/etc/keepalived/DirectorControl MASTER"
         notify_backup "/etc/keepalived/DirectorControl BACKUP"
         notify_fault "/etc/keepalived/DirectorControl FAULT"

}
virtual_server 10.133.100.107 25 {
         delay_loop 3
         lb_algo rr
         lb_kind DR
         #persistence_timeout 50
         protocol TCP

         real_server 10.133.100.103 25 {
                 TCP_CHECK {
                         connect_port 25
                         connect_timeout 3
                 }
         }

         real_server 10.133.100.104 25 {
                 TCP_CHECK {
                         connect_port 25
                         connect_timeout 3
                 }
         }
}

# BACKUP/SLAVE node :
global_defs {
         notification_email {
                 sso <at> sofinco.fr
         }
         notification_email_from root <at> uxprod51.sofinco.fr
         smtp_server smtp.mail.sofinco.fr
         smtp_connect_timeout 30
         lvs_id LVS_AMAVIS_BACKUP
}
vrrp_instance ID_200 {
         state MASTER
         interface eth0
         virtual_router_id 200
         lvs_sync_daemon_interface eth0
         priority 50
         authentication {
                 auth_type PASS
                 auth_pass myvrrppassword
         }
         virtual_ipaddress {
                 10.133.100.107/24 brd 10.133.100.255 dev eth0
         }

         notify_master "/etc/keepalived/DirectorControl MASTER"
         notify_backup "/etc/keepalived/DirectorControl BACKUP"
         notify_fault "/etc/keepalived/DirectorControl FAULT"
}
virtual_server 10.133.100.107 25 {
         delay_loop 3
         lb_algo rr
         lb_kind DR
         #persistence_timeout 50
         protocol TCP

         real_server 10.133.100.103 25 {
                 TCP_CHECK {
                         connect_port 25
                         connect_timeout 3
                 }
         }

         real_server 10.133.100.104 25 {
                 TCP_CHECK {
                         connect_port 25
                         connect_timeout 3
                 }
         }

}

# notification script DirectorControl :

#!/bin/sh
#
# Usage :
# $0 MASTER|BACKUP|FAULT
#

ipvsadm="/sbin/ipvsadm"
ipvsadm_save="$ipvsadm -S -n"
ipvsadm_restore="$ipvsadm -R"
ipvs_rules="/var/lib/ipvs/ipvs.rules"
ipvs_status="/var/lib/ipvs/ipvs.status"

[ -z "$1" ] && echo "usage : $0 MASTER|BACKUP|FAULT" && exit 1

file_empty() {
         if [ -f "$1" ] ; then
                 size=`wc -c "$1" | cut -d" " -f1`
                 [ $size -gt 1 ] && return 1 || return 0
         else
                 return 0
         fi
}

case $1 in
         MASTER)
                 echo "MASTER" > $ipvs_status
                 if ! file_empty $ipvs_rules ; then
                         $ipvsadm_restore < $ipvs_rules
                 fi ;;

         BACKUP)
                 echo "BACKUP" > $ipvs_status
                 $ipvsadm_save > $ipvs_rules
                 $ipvsadm -C ;;

         FAULT)
                 echo "FAULT" > $ipvs_status
                 $ipvsadm -C ;;

         *)
                 echo "Unknown request '$1'"
                 exit 1 ;;
esac

# sysctl params (on both nodes) :
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.eth0.arp_announce = 2
net.ipv4.ip_forward = 1

What do you think about this configuration ? Is this production ready ?
I have done some load tests, and it  seems to be ok, but is there a 
better solution ?

Thanks in advance...

-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf