References: http://www.austintek.com/LVS/LVS-HOWTO/HOWTO/LVS-HOWTO.LVS-DR.html http://kb.linuxvirtualserver.org/wiki/LVS/DR

Test Setup: http://lb-www.club.cc.cmu.edu

IPVS kernel support is already in the default Debian kernel. All that needs to be installed is the administration tool (ipvsadm) and a management tool. The only management tool that I have tested, and thus the one I like most, is keepalived.

Install the tools on the load balancer only.

apt-get install ipvsadm keepalived

All (most) configuration is done on the load balancer side. In particular, /etc/keepalived/keepalived.conf. Below is the current configuration.

global_def {
        notification_email {
                awesie@club.cc.cmu.edu
        }
        notification_email_from root@club.cc.cmu.edu
        smtp_server localhost
        smtp_connect_timeout 30
        router_id lvs-b6
}

vrrp_instance VI_B6 {
!       state BACKUP
        state MASTER
        interface eth0
        lvs_sync_daemon_inteface eth0
        virtual_router_id 200
!       priority 100
        priority 150
        advert_int 1
        authentication {
                auth_type PASS
                auth_pass badpass
        }
        virtual_ipaddress {
                128.237.157.89
        }
}

! ftp active/passive
virtual_server fwmark 1 {
        delay_loop 6
        lb_algo rr
        lb_kind DR
        protocol TCP

        real_server 128.237.157.9 21 {
                weight 100
                TCP_CHECK {
                        connect_port 21
                        connect_timeout 3
                }
        }

        real_server 128.237.157.10 21 {
                weight 100
                TCP_CHECK {
                        connect_port 21
                        connect_timeout 3
                }
        }
}

! rsync
virtual_server 128.237.157.89 873 {
        delay_loop 6
        lb_algo rr
        lb_kind DR
        protocol TCP
        persistence_timeout 300
        protocol TCP
        persistence_timeout 300

        real_server 128.237.157.9 873 {
                weight 100
                TCP_CHECK {
                        connect_port 873
                        connect_timeout 3
                }
        }

        real_server 128.237.157.10 873 {
                weight 100
                TCP_CHECK {
                        connect_port 873
                        connect_timeout 3
                }
        }
}

! nntp
virtual_server 128.237.157.89 119 {
        delay_loop 6
        lb_algo rr
        lb_kind DR
        protocol TCP

        real_server 128.237.157.36 119 {
                weight 100
                TCP_CHECK {
                        connect_timeout 10
                }
        }

        real_server 128.237.157.69 119 {
                weight 100
                TCP_CHECK {
                        connect_timeout 10
                }
        }
}

! web servers
virtual_server 128.237.157.89 80 {
        delay_loop 6
        lb_algo wlc
        lb_kind DR
        protocol TCP

        virtualhost www.club.cc.cmu.edu

!       Can't have a server be the local computer, must be remote.
!       sorry_server 127.0.0.1 8080

        real_server 128.237.157.9 80 {
                weight 100
                HTTP_GET {
                        url {
                                path /index.cgi
                        url {
                                path /index.cgi
                                status_code 200
!                               digest 523d93c9f140610c309061167f92a4b2
                        }
                        connect_timeout 3
                        nb_get_retry 3
                        delay_before_retry 2
                }
        }
        real_server 128.237.157.10 80 {
                weight 100
                HTTP_GET {
                        url {
                                path /index.cgi
                                status_code 200
                                #digest 523d93c9f140610c309061167f92a4b2
                        }
                        connect_timeout 3
                        nb_get_retry 3
                        delay_before_retry 2
                }
        }
}

! web (ssl) servers
virtual_server 128.237.157.89 443 {
        delay_loop 6
        lb_algo wlc
        lb_kind DR
        protocol TCP
        persistence_timeout 360

        virtualhost www.club.cc.cmu.edu

!       Can't have a server be the local computer, must be remote.
!       sorry_server 127.0.0.1 8080

        real_server 128.237.157.49 443 {
                weight 100
                SSL_GET {
                        url {
                                path /index.cgi # replace with a file that does exist
                                status_code 404
!                               digest 523d93c9f140610c309061167f92a4b2
                        }
                        connect_timeout 3
                        connect_port 443
                        nb_get_retry 3
                        delay_before_retry 2
                }
        }
        real_server 128.237.157.50 443 {
                weight 100
                SSL_GET {
                        url {
                                path /index.cgi # replace with a file that does exist
                                status_code 404
                                #digest 523d93c9f140610c309061167f92a4b2
                                status_code 404
                                #digest 523d93c9f140610c309061167f92a4b2
                        }
                        connect_timeout 3
                        connect_port 443
                        nb_get_retry 3
                        delay_before_retry 2
                }
        }
}

! dns server (not working)
virtual_server 128.237.157.89 53 {
        delay_loop 10
        lb_algo wrr
        lb_kind DR
        protocol UDP

        real_server 128.237.157.12 53 {
                weight 100
                MISC_CHECK {
                        misc_path "/usr/bin/dig -b 128.237.157.89 a www.club.cc.cmu.edu @128.237.157.12 +time=1 +tries=5 +fail > /dev/null"
                        misc_timeout 6
                }
        }
        real_server 128.237.157.14 53 {
                weight 100
                MISC_CHECK {
                        misc_path "/usr/bin/dig -b 128.237.157.89 a www.club.cc.cmu.edu @128.237.157.14 +time=1 +tries=5 +fail > /dev/null"
                        misc_timeout 6
                }
        }
}

Most of the configuration is relatively intuitive. More documentation can be found at the keepalived website (http://www.keepalived.org).

That finishes all of the load balancer server configuration. So go ahead and tell keepalived to reload it's configuration.

On the backends, you need to tell Linux to accept packets for your virtual server IP. In the configuration above, this IP is 128.237.157.89. There are several ways to do this, as described in the references. Also, as described in the references, since we have our load balancer on the same network as the backends, we need to prevent our backends from broadcasting ARP packets for the virtual server IP, and this is all documented in the references. Below is the way I prefer to do this.

iptables -t nat -A PREROUTING -p tcp -d <virtual_server_ip> --dport <virtual_server_port> -j REDIRECT --to-port <local_port>

It's simple. Doesn't require adding another address to an interface. Note that djbdns doesn't seem to like this at all.

Congratulations! The load balancing is now setup with failover. Both IPVS and keepalived are flexible systems, with support for failover load balancers as well, via VRRP2.

Current firewall configuration files:

load-balancer

# Flush chains
iptables -F

# Set chain policies
iptables -P INPUT ACCEPT
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Delete old chains
iptables -X PROPERREJECT 2> /dev/null

# Create new chains
iptables -N PROPERREJECT

# Drop invalid packets
iptables -A INPUT -m state --state INVALID -j DROP

# Accept connections on the local interface.
iptables -A INPUT -i lo -j ACCEPT

# Drop connections to the local interface from outside
iptables -A INPUT -d 127.0.0.0/8 -j DROP

# Reject connections from evil sources
# iptables -A INPUT -s 72.20.0.0/18 -j REJECT   # 72.20.0.14

# Reject all TCP & UDP connections, drop others
iptables -A PROPERREJECT -p tcp -j REJECT --reject-with tcp-reset
iptables -A PROPERREJECT -p udp -j REJECT --reject-with icmp-port-unreachable
iptables -A PROPERREJECT -j DROP

# mark ftp passive/active packets
iptables -t mangle -A PREROUTING -i eth0 -p tcp -s 0.0.0.0/0 -d 128.237.157.89 --dport ftp -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -i eth0 -p tcp -s 0.0.0.0/0 -d 128.237.157.89 --dport ftp-data -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -i eth0 -p tcp -s 0.0.0.0/0 -d 128.237.157.89 --dport 60000: -j MARK --set-mark 1

www

# Flush chains
iptables -F

# Set chain policies
iptables -P INPUT ACCEPT
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Delete old chains
iptables -X PROPERREJECT 2> /dev/null

# Create new chains
iptables -N PROPERREJECT

# Drop invalid packets
iptables -A INPUT -m state --state INVALID -j DROP

# Accept connections on the local interface.
iptables -A INPUT -i lo -j ACCEPT

# Drop connections to the local interface from outside
iptables -A INPUT -d 127.0.0.0/8 -j DROP

# Reject connections from evil sources
iptables -A INPUT -s 72.20.0.0/18 -j REJECT     # 72.20.0.14

# Reject all TCP & UDP connections, drop others
iptables -A PROPERREJECT -p tcp -j REJECT --reject-with tcp-reset
iptables -A PROPERREJECT -p udp -j REJECT --reject-with icmp-port-unreachable
iptables -A PROPERREJECT -j DROP

# Forward load balancing ip
iptables -t nat -A PREROUTING -p tcp -d 128.237.157.89 -j REDIRECT

ftp configuration additions (vsftpd.conf)

# load balancing
pasv_min_port=60000
pasv_max_port=65535
pasv_address=128.237.157.89

Other Informative Documentation/Setting Up LVS (last edited 2009-12-21 05:02:40 by localhost)