I have set up keepalived for load balancing. It works for redundancy but does not work when trying to load balance.
I am using 2 servers and have exact same configurations on both servers. debian 64 bit squeeze.
keepaliv conf:
[CODE]
# Configuration File for Keepalived
# Global Configuration
global_defs {
notification_email {
[email]sharif@shopto.net[/email]
}
notification_email_from [email]keepalived@shopto.net[/email]
smtp_server smtp.shopto.lan
smtp_connect_timeout 30
router_id DEBIAN2 # string identifying the machine
}
# describe virtual service ip
vrrp_instance VI_1 {
# initial state
state BACKUP
interface eth0
# arbitary unique number 0..255
# used to differentiate multiple instances of vrrpd
virtual_router_id 1
# for electing MASTER, highest priority wins.
# to be MASTER, make 50 more than other machines.
priority 60
authentication {
auth_type PASS
auth_pass xxx
}
virtual_ipaddress {
192.168.0.199/32
}
# Invoked to master transition
notify_master "/etc/keepalived/bypass_ipvs.sh del 192.168.0.199"
# Invoked to slave transition
notify_backup "/etc/keepalived/bypass_ipvs.sh add 192.168.0.199"
# Invoked to fault transition
notify_fault "/etc/keepalived/bypass_ipvs.sh add 192.168.0.199"
smtp_alert
}
# describe virtual web server
virtual_server 192.168.0.199 8080 {
# delay_loop 5
# lc = least connected
lb_algo rr
# DR = Dynamic routing (best)
lb_kind NAT
# persistence_timeout 50
protocol TCP
real_server 192.168.0.212 80 {
TCP_CHECK {
connect_timeout 1
# nb_get_retry 2
# delay_before_retry 60
}
}
real_server 192.168.0.213 80 {
TCP_CHECK {
connect_timeout 1
# nb_get_retry 2
# delay_before_retry 60
}
}
}
[/CODE]
bypass script
[CODE]
#! /bin/sh
#
# Gael Charriere <gael.charriere@gmail.com>
# 10.11.2008
#
# Invoked by keepalived from master/slave
# to slave/master transition to add or remove
# a PREROUTING rule
#
# Essential for slave to redirect incoming
# service packet to localhost. Otherwise a
# loop can appear between master and slave.
#
# The routing table is consulted when a packet
# that creates a new connection is encountered.
# PREROUTING rule alters packets as soon as they come in.
# REDIRECT statement redirects the packet to the machine
# itself by changing the destination IP to the primary
# address of the incoming interface (locally-generated
# packets are mapped to the 127.0.0.1 address).
# Check number of command line args
EXPECTED_ARGS=2
if [ $# -ne $EXPECTED_ARGS ]; then
echo "Usage: $0 {add|del} ipaddress"
exit 1
fi
# Check if second arg is a valid ip address
VIP=$2
OLD_IFS=$IFS
IFS="."
VIP="$VIP"
IFS=$OLD_IFS
# Check that ip has 4 parts
#if [ ${#VIP[@]} -ne 4 ]; then
# echo "IP address must have 4 parts"
# echo "Usage: $0 {add|del} ipaddress"
# exit 1
#fi
# Check that each parts is a number which
# varies between 0 and 255
#for oct in ${VIP[@]} ; do
# echo "oct: "$oct
# echo $oct | egrep "^[0-9]+$" >/dev/null 2>&1
# if [ $? -ne 0 ]; then
# echo "$oct: Not numeric"
# echo "Usage: $0 {add|del} ipaddress"
# exit 1
# else
# if [ $oct -lt 0 -o $oct -gt 255 ]; then
# echo "$oct: Out of range"
# echo "Usage: $0 {add|del} ipaddress"
# exit 1
# fi
# fi
#done
# If we are here, ip address is validated
#echo "1stpart: ${VIP[1]} test"
#VIP="${VIP[0]}.${VIP[1]}.${VIP[2]}.${VIP[3]}"
# Add or remove the prerouting rule
case "$1" in
add)
# check if the rule was already specified
n=$(iptables -t nat -L| grep $VIP | wc -l)
#echo "n: "$n
if [[ $n == 0 ]]; then
# the rule was not found, add it
#echo $VIP
iptables -A PREROUTING -t nat -d $VIP -p tcp -j REDIRECT
fi
;;
del)
# check if the rule was already specified
n=$(iptables -t nat -L| grep $VIP | wc -l)
while [[ $n > 0 ]]; do
# remove the rule
iptables -D PREROUTING -t nat -d $VIP -p tcp -j REDIRECT
n=$(($n-1))
done
;;
*)
echo "Usage: $0 {add|del} ipaddress"
exit 1
esac
exit 0
[/CODE]
The servers are debina2 and debain3.
Now if debian3 is master i can netcat into port 8080 to debian2 but it won't work for debian3 locally using rr algorithim. same would happen if debian2 was master and debian3 slave. however i can ping the VIP from any local pc.
[CODE]
root@debian3:/etc/keepalived# ipvsadm -l -n --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes
-> RemoteAddress:Port
TCP 192.168.0.199:8080 8 21 10 1205 572
-> 192.168.0.212:80 4 17 10 965 572
-> 192.168.0.213:80 4 4 0 240 0
[/CODE]
In the above debian3 is master and debian 2 is backup. nothing is sent back when it tries itself
[CODE]
root@debian3:/etc/keepalived# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.0.199:8080 rr
-> 192.168.0.212:80 Masq 1 0 0
-> 192.168.0.213:80 Local 1 0 0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:17:31:8f:74:1c brd ff:ff:ff:ff:ff:ff
inet 192.168.0.213/24 brd 192.168.0.255 scope global eth0
inet 192.168.0.199/32 scope global eth0
inet6 fe80::217:31ff:fe8f:741c/64 scope link
valid_lft forever preferred_lft forever
[/CODE]
I have manually tried to add NAT rule onto backup using ''iptables -A PREROUTING -t nat -d 192.168.0.199 -p tcp -j REDIRECT'' but that doesn't work. I have also tried to change ''lb_kind'' to ''DR'' but that doesn't work. I have read many how to guides and have followed exactly same procedures and none seem to work.
I have loaded modules using modprobe and set ipv4 for port forward to 1 in sysctl.conf
keepalived.conf