Abstract
This chapter presents solutions to implement load balancing and service distribution to create a high availability service environment. You'll learn about install methods, specific service requirements, as well as how to configure load balancing correctly.
We will look at a simple case: an administrator wants to establish transparent redundancy for his Intranet web server to guarantee service availability. In this case, we have 4 servers allocated as described below:
Loadbalancers allocate the “load” according to predefined parameters. The real servers are the physical machines running the service. In our case, it's a web server. If the load increases, you can transparently add more hardware.
Here are the IP addresses we will be using:
10.0.0.3 - adresse IP de lb1 10.0.0.4 - adresse IP de lb2 10.0.0.5 - adresse IP du service Web de l'Intranet
192.168.0.1 - adresse IP local de la passerelle 192.168.0.12 - adresse IP de rs1 192.168.0.13 - adresse IP de rs2
Load balancing happens at IP level. It is handled directly by the Linux kernel. The loadbalancer acts as a “router” since it redirects requests (therefore packets) towards a target according to different rules.
As root, install the keepalived RPM which will ask to you to satisfy the required dependencies:
[root@lb1 ~]#urpmi keepalived To satisfied dependencies, the following packages will be installed: ipvsadm-1.24-6mdv2009.0 keepalived-1.1.17-1mdvmes5 Install these required packages? (0 Mo) (Y/n)
Normally, the
iproute2 package should already be
installed. If it's not the case, install it:
[root@lb1 ~]#urpmi iproute2
General
configuration is only within
/etc/keepalived/keepalived.conf. All the
following configuration elements should be placed in this file (by
default, it contains an example configuration).
First, the module
ip_vs needs to be loaded at boot. Add it to
/etc/modprobe.preload. Normally,
keepalived will load this module
automatically.
#modprobe ip_vs
Keepalived is be used to manage ipvsadm as well as the fail-over between the loadbalancers. We have established redundancy between the loadbalancers for security reasons, to make sure we don't have to worry about this. Keepalived also installs ipvsadm, the ip_vs administration tool.
Let's make sure
that it implements ip_forward, because it
will not function without it:
echo "1" > /proc/sys/net/ipv4/ip_forward
Edit
/etc/keepalived/keepalived.conf. The
global_defs section applies to the general
configuration of Keepalived. It allows you
to define notification options, and mainly the
lvs_id (unique machine identifier).
global_defs {
notification_email {
mon@mail.com
}
notification_email_from keepalived@domaine.tld
smtp_server 127.0.0.1
smtp_connect_timeout 30
lvs_id LVS_MAIN
}
The
vrrp\_instance section defines use parameters
of the VRRP daemon included in
Keepalived. This protocol handles
dynamic IP addressing between many
systems. This allows redundancy of the loadbalancers. If one
becomes unavailable, the other picks up the load and grabs the
IP address specified in
virtual\_ipaddress{}. For the second
loadbalancer, the state variable contains the
SLAVE
value. virtual_ipaddress defines all the
IP address that the loadbalancers should
attribute itself when it is the master. Be careful,
virtual_ipaddress only handles one
IP per line with a maximum of 32
addresses.
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
10.0.0.5
}
}
The following section discusses defining virtual servers for redundancy, as well as the protocols to implement it.
# Virtual Servers definitions
virtual_server 192.168.0.1 80 {
delay_loop 30
lb_algo wlc
lb_kind NAT
persistence_timeout 50
protocol TCP
If all the real servers are unavailable, keepalived will return the request. It allows you to show a static information page in case of a problem.
sorry_server 192.168.0.1 80
real_server 192.168.0.12 80 {
weight 20
}
real_server 192.168.0.13 80 {
weight 8
}
}
Since the machines are within a local network with the loadbalancers, we must force them to use the loadbalancers as gateways for all traffic. Let's create a static route to do this with iproute2.
Let's create the following rules:
#!/bin/sh -e
echo 200 LVS >> /etc/iproute2/rt_tables
/sbin/ip rule add from 192.168.0.12 table LVS
/sbin/ip route add default via 192.168.0.1 dev eth0 table LVS
/sbin/ip route flush cache
Let's test the configuration. First, restart keepalived:
# service keepalived restart
Use your favorite Web browser to access http://10.0.0.5. If the page loads correctly, your configuration is working. Of course, this is a basic configuration. It may be interesting to add more advanced features such as firewalling, monitoring, etc.
Once the server is installed, you can use ipvsadm -L to view the state of your load balancing:
# ipvsadm
IP Virtual Server version 1.2.0 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn
InActConn TCP 10.0.0.5:www wlc persistent 20
-> 10.0.0.3:www Route 25 294 916
-> 10.0.0.4:www Route 8 243 754
Keepalived
includes a monitoring system capable of checking if the servers in
your high availability cluster are reachable. You only need to add
a section in the Web server's configuration in
/etc/keepalived/keepalived.conf. The
monitoring can be a simple ping:
TCP_CHECK { connect_port 80 connect_timeout 3
}
It can go as far as checking that the returned page is the page it should be.
HTTP_GET {
url {
path /
digest 69c520033af926d40e7d5d832e3933f6
}
connect_timeout 5
nb_get_retry 3
delay_before_retry 2
}
To manage the hash, use genhash with the following command:
[root@lb1 ~]# genhash -s 193.188.255.4 -p 80 -u /
MD5SUM = 5b5af20a92f1dbe92328005329d1753f
You can also
launch actions if a specific event happens (typically, fall over to
the other loadbalancer if the master becomes unreachable), with the
following set up in section vrrp :
notify_master /path_to_script/script_master.sh
(or notify_master “/path_to_script/script_master.sh <arg_list>”)
notify_backup /path_to_script/script_backup.sh
(or notify_backup “/path_to_script/script_backup.sh <arg_list>”)
notify_fault /path_to_script/script_fault.sh
(or notify_fault “/path_to_script/script_fault.sh <arg_list>”)