一、实验原理:
过程如下:
1)client 向目标 vip 发出请求,LB 接收。
2)VS 根据负载均衡算法选择一台 active 的 real server,将此 RIP 所在网卡的 mac 地址作为目标 mac 地址,发送到局域网里。
3)realserver在局域 网中收到这个帧,拆开后发现目标 IP(VIP)与本地匹配,于是
处理这个报文;随后重新封装报文,发送到局域网。
4)如果 client 与 VS在 同一网段,那么 client将收到这个回复报文。
注意:
- 它是通过在调度器LB上修改数据包的目的MAC地址实现转发,注意源地址仍然是CIP,目的地址仍然是VIP地址;
- 请求的报文经过调度器,而服务器响应处理后的报文无需经过调度器LB,因此并发访问量大时使用效率很高(和NAT模式比)
- 因为DR模式是通过MAC地址改写机制实现转发,因此所有RS节点和调度器LB只能在一个局域网里面;由于DR模式的调度器仅做MAC地址的改写,所以调度器LB就不能改写目标端口,那么服务器就得使用和VIP相同的端口提供服务(即RS和LB必须拥有相同的IP,处于一个vlan下)。
- 服务器主机需要绑定VIP地址在LO接口上,并且需要配置ARP抑制。(如果不做arp抑制,那么访问100这个VIP并不能始终指向调度器、而是具有随机性)
注:DR模式工作在数据链路层,且不支持端口转发;
二、部署
(1)实验环境:
本次实验所有主机均为rhel6.5,并且selinux为disabled、防火墙为关闭状态;
主机 角色 IP
server1 LB(调度器) 172.25.45.1
server2 RS(真实后端服务器) 172.25.45.2
server3 RS(真实后端服务器) 172.25.45.3
(2)实验过程:
1、首先在官网下载:bansys.zip varnish-3.0.5-1.el6.x86_64.rpm varnish-libs-3.0.5-1.el6.x86_64.rpm;
2、扩展yum源;
[root@server1 mnt]# vim /etc/yum.repos.d/rhel-source.repo ##在原来的yum基础上添加如下内容
[HighAvailability] //高可用
name=HighAvailability
baseurl=http://172.25.45.250/rhel6.5/HighAvailability
gpgcheck=0
[LoadBalancer] //负载均衡
name=LoadBalancer
baseurl=http://172.25.45.250/rhel6.5/LoadBalancer
gpgcheck=0
[ResilientStorage] //分布式存储
name=ResilientStorage
baseurl=http://172.25.45.250/rhel6.5/ResilientStorage
gpgcheck=0
[ScalableFileSystem] //大文件系统
name=ScalableFileSystem
baseurl=http://172.25.45.250/rhel6.5/ScalableFileSystem
gpgcheck=0
[root@server1 mnt]# yum repolist ##可以看到新的yum源的软件数有3800多左右;如果不是,代表yum源的搭建有误;
3、将调度器和 真实服务器设置在同一个vlan;
##server1
[root@server1 mnt]# ip addr add 172.25.45.100/24 dev eth0 ##给调度器添加虚拟IP(即客户端访问的IP)
[root@server1 mnt]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:ed:2a:d6 brd ff:ff:ff:ff:ff:ff
inet 172.25.45.1/24 brd 172.25.45.255 scope global eth0
inet 172.25.45.100/24 scope global secondary eth0
inet6 fe80::5054:ff:feed:2ad6/64 scope link
valid_lft forever preferred_lft forever
##server2
[root@server2 ~]# cd /var/www/html
[root@server2 ~]# vim index.html
www.westos.org - server2
[root@server2 ~]# /etc/init.d/httpd start
[root@server2 ~]# ip addr add 172.25.45.100/24 dev eth0
[root@server2 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:74:2d:3b brd ff:ff:ff:ff:ff:ff
inet 172.25.45.2/24 brd 172.25.45.255 scope global eth0
inet 172.25.45.100/24 scope global secondary eth0
inet6 fe80::5054:ff:fe74:2d3b/64 scope link
valid_lft forever preferred_lft forever
##server3
[root@server2 ~]# cd /var/www/html
[root@server2 ~]# vim index.html
bbs.westos.org
[root@server3 ~]# /etc/init.d/httpd start
[root@server3 ~]# ip addr add 172.25.45.100/24 dev eth0
[root@server3 ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:1b:16:a3 brd ff:ff:ff:ff:ff:ff
inet 172.25.45.3/24 brd 172.25.45.255 scope global eth0
inet 172.25.45.100/24 scope global secondary eth0
inet6 fe80::5054:ff:fe1b:16a3/64 scope link
valid_lft forever preferred_lft forever
4、添加策略:
[root@server1 mnt]# ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
[root@server1 mnt]# ipvsadm -A -t 172.25.45.100:80 -s rr ##rr是轮询算法;10种算法之一
[root@server1 mnt]# ipvsadm -a -t 172.25.45.100:80 -r 172.25.45.3:80 -g
[root@server1 mnt]# ipvsadm -a -t 172.25.45.100:80 -r 172.25.45.2:80 -g
[root@server1 mnt]# ipvsadm -ln ## nl 不解析
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.45.100:80 rr
-> 172.25.45.2:80 Route 1 0 0
-> 172.25.45.3:80 Route 1 0 0
5、在物理机进行测试:
[root@foundation45 rhel6.5]# arp -d 172.25.45.100 ##ARP是地址解析协议;将IP地址映射为物理硬件(MAC)地址;
可以看到这里的100的IP地址指向的并不是指向调度器(即server1),而是server3(后端真实服务器);
我们用命令清除一下缓存:
重新ping 172.25.45.100,再次查看这个100的IP指向的主机为server1:
所以说,现在我们访问100这个IP时,并不能唯一指定调度器,且具有随即性;那么,现在不是我们想要的效果。所以说,此时我们要解决的问题是如何让100这个IP地址唯一地指向调度器(即server1)
抑制server2和server3的ARP:
##server2
[root@server2 ~]# yum install -y arptables_jf
[root@server2 ~]# arptables -A IN -d 172.25.45.100 -j DROP ##禁止100这个IP包发送进来
[root@server2 ~]# arptables -A OUT -s 172.25.45.100 -j mangle --mangle-ip-s 172.25.45.2 ##允许server2的IP数据包发送给为100这个IP
[root@server2 ~]# /etc/init.d/arptables_jf save ##保存策略
[root@server2 ~]# arptables -nL
##server3
[root@server3 ~]# yum install -y arptables_jf
[root@server3 ~]# arptables -A IN -d 172.25.45.100 -j DROP ##禁止100这个IP包发送进来
[root@server3 ~]# arptables -A OUT -s 172.25.45.100 -j mangle --mangle-ip-s 172.25.45.2 ##允许server3的IP数据包发送给为100这个IP
[root@server3 ~]# /etc/init.d/arptables_jf save ##保存策略
Saving current rules to /etc/sysconfig/arptables: [ OK ]
物理机测试:
[root@foundation45 ~]# vim /etc/hosts ##本地解析
172.25.45.100 www.westos.org
[root@foundation45 ~]# curl 172.25.45.100 ##我们用curl命令获取100这个IP的内容,
bbs.westos.org
[root@foundation45 ~]# curl 172.25.45.100
www.westos.org - server2
[root@foundation45 ~]# curl 172.25.45.100
bbs.westos.org
[root@foundation45 ~]# arp -an | grep 100 ##现在这里的物理硬件地址为一指向server1;
? (172.25.45.100) at 52:54:00:ed:2a:d6 [ether] on br0
浏览器测试:
1)输入域名(必须要做本地解析):
server2和server3的默认发布内容随着刷新,一直轮询;
2)输入IP:
用ldirectord实现健康检查
1、下载软件ldirectord-3.9.5-3.1.x86_64.rpm ,并安装;
[root@server1 ~]# yum install -y ldirectord-3.9.5-3.1.x86_64.rpm
[root@server1 mnt]# rpm -ql ldirectord ##查看安装路径
/etc/ha.d
/etc/ha.d/resource.d
/etc/ha.d/resource.d/ldirectord
/etc/init.d/ldirectord
/etc/logrotate.d/ldirectord
/usr/lib/ocf/resource.d/heartbeat/ldirectord
/usr/sbin/ldirectord
/usr/share/doc/ldirectord-3.9.5
/usr/share/doc/ldirectord-3.9.5/COPYING
/usr/share/doc/ldirectord-3.9.5/ldirectord.cf
/usr/share/man/man8/ldirectord.8.gz
[root@server1 mnt]# cp /usr/share/doc/ldirectord-3.9.5/ldirectord.cf /etc/ha.d/
[root@server1 mnt]# cd /etc/ha.d
[root@server1 ha.d]# ls
ldirectord.cf resource.d shellfuncs
[root@server1 ha.d]# vim ldirectord.cf
25 virtual=172.25.45.100:80 ##LB的虚拟IP
26 real=172.25.45.2:80 gate ##真实真实服务器的IP
27 real=172.25.45.3:80 gate
28 fallback=127.0.0.1:80 gate
29 service=http
30 scheduler=rr
31 #persistent=600
32 #netmask=255.255.255.255
33 protocol=tcp
34 checktype=negotiate
35 checkport=80
36 request="index.html"
37 #receive="Test Page"
38 #virtualhost=www.x.y.z
[root@server1 ha.d]# ipvsadm -C ##清除所与的策略
[root@server1 ha.d]# /etc/init.d/ldirectord restart
Restarting ldirectord... success
[root@server1 ha.d]# ipvsadm -l
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.45.100:http rr
-> server2:http Route 1 0 0
-> server3:http Route 1 0 0
[root@server1 ha.d]# /etc/init.d/httpd restart
[root@server1 html]# vim index.html
系统正在维护中......
测试时,如果当关闭server3的httpd,只会server2;如果server2和server3的httpd 都关闭时,我们访问100这个IP时,它会访问本地,即显示:系统正在维护中……
keepalived实现高可用集群
下载keepalived-2.0.6.tar.gz软件包;
实验环境:
server1 LB(主 master)
server2 RS
server3 RS
server4 LB (备用master;当主master在工作时,它是处于休眠状态,一旦原来的master挂掉,立马成为新的主master)
##server1(LB调度器)
[root@server1 ~]# tar zxf keepalived-2.0.6.tar.gz
[root@server1 keepalived-2.0.6]# ./configure --prefix=/usr/local/keepalived --with-init=SYSV ##源码编译;安装openssl-devel依赖性.
[root@server1 keepalived-2.0.6]# make
[root@server1 keepalived-2.0.6]# make install
[root@server1 keepalived-2.0.6]# cd /usr/local/keepalived/etc/rc.d/init.d
[root@server1 init.d]# chmod +x keepalived
[root@server1 init.d]# ln -s /usr/local/keepalived/etc/sysconfig/keepalived /etc/init.d
[root@server1 init.d]# ln -s /usr/local/keepalived/etc/keepalived /etc/
[root@server1 init.d]# ln -s /usr/local/keepalived/etc/sysconfig/keepalive /etc/sysconfig/
[root@server1 init.d]# ln -s /usr/local/keepalived/sbin/keepalived /sbin/
[root@server1 init.d]# /etc/init.d/keepalived start ##检测服务是否可以正常启动
[root@server1 init.d]# cd /usr/local
[root@server1 local]# scp -r keepalived/ server4:/usr/local/
[root@server1 local]# cd /etc/keepalived
[root@server1 keepalived]# vim keepalived.conf
//Virtual_router_id虚拟路由id,Delay_loop后端的健康检查,Persistence_timeout持续连接,一直保持协议磋商
global_defs {
notification_email {
root@localhost
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
#vrrp_strict #注释以放其修改防火墙规则
vrrp_garp_interval 0
vrrp_gna_interval 0
vrrp_instance VI_1 {
state MASTER ##默认为master
interface eth0
virtual_router_id 35
priority 100 #数值越大,优先级越高
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.45.100
}
}
virtual_server 172.25.45.100 80 { #VS的vip,服务启动生效时自动添加
delay_loop 3 #对后端的健康检查时间
lb_algo rr #调度算法
lb_kind DR #模式为DR
#persistence_timeout 50 #注释持续连接
protocol TCP
real_server 172.25.45.2 80{ #RS
weight 1
TCP_CHECK{
connect_timeout 3
retry 3
delay_before_retry 3
}
}
real_server 172.25.45.3 80{
weight 1
TCP_CHECK{
connect_timeout 3
retry 3
delay_before_retry 35
}
}
}
[root@server1 keepalived]# ip addr del 172.25.45.100/24 dev eth0 ##删除虚拟IP
[root@server1 keepalived]# /etc/init.d/keepalived restart ##重启服务
[root@server1 keepalived]# scp keepalived.conf server4:/etc/keepalived/
......
server1 Keepalived_vrrp[1875]: (VI_1) Entering MASTER STATE
......
[root@server1 keepalived]# yum install mailx
##server3
4条软链接;
[root@server4 keepalived]# /etc/init.d/keepalived start
[root@server4 keepalived]# yum install mailx -y
[root@server4 keepalived]# vim keepalived.conf
vrrp_instance VI_1 {
state BACKUP ##设置为默认备用的master
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.25.45.100
}
}
[root@server4 keepalived]# /etc/init.d/keepalived restart
......
server1 Keepalived_vrrp[1875]: (VI_1) Entering BACKUP STATE
......
测试:
关闭server1的keepalived,server4会自动替补,通过查看邮件 cat /var/log/message ,可以看到server4的状态由BACKUP升级为master;
附:
(1)10种算法:
1、轮叫调度(简称 rr)
轮叫调度算法就是以轮叫的方式依次请求服务器,即每次调度执行i = (i + 1) mod n,并选出第i台服务器。算法的优点是其简洁性,它无需记录当前所有连接的状态,不管服务器上实际的连接数和系统负载,所以它是一种无状态调度。
2、加权轮叫(简称 wrr)
加权轮叫调度算法可以解决服务器间性能不一的情况,它用相应的权值表示服务器的处理性能,服务器的缺省权值为1。加权轮叫调度算法是按权值的高低和轮叫方式分配请求到各服务器。权值高的服务器优先级更高,所以先收到连接;权值高的服务器比权值低的服务器处理更多的连接,相同权值的服务器处理相同数目的连接数。
假设服务器A的权值为1,B的权值为2,则表示服务器B的处理性能是A的两倍,如果客户端请求后端服务器,B先处理且每轮处理次数为2次,然后才是A进行处理且处理次数为1次;之后就是B 2,A 1轮询。
3、最少链接(简称 LC)
最小连接调度算法是把新的连接请求分配到当前连接数最小的服务器。最小连接调度是一种动态调度算法,它通过服务器当前所活跃的连接数来估计服务器的负载情况。调度器需要记录各个服务器已建立连接的数目,当一个请求被调度到某台服务器,其连接数加1;当连接中止或超时,其连接数减一。
如果集群系统的真实服务器具有相近的系统性能,采用”最小连接”调度算法可以较好地均衡负载。
4、加权最少链接(简称 WLC)
加权最小连接调度算法是最小连接调度的超集,各个服务器用相应的权值表示其处理性能。服务器的缺省权值为1,系统管理员可以动态地设置服务器的权值。加权最小连接调度在调度新连接时尽可能使服务器的已建立连接数和其权值成比例。
调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。
5、基于局部性的最少链接(简称 LBLC)
基于局部性的最少链接调度算法是针对请求报文的目标IP地址的负载均衡调度,目前主要用于Cache集群系统,因为在Cache集群中客户请求报文的目标IP地址是变化的。这里假设任何后端服务器都可以处理任一请求,算法的设计目标是在服务器的负载基本平衡情况下,将相同目标IP地址的请求调度到同一台服务器,来提高各台服务器的访问局部性和主存Cache命中率,从而提高整个集群系统的处理能力。
6、带复制的基于局部性最少链接(简称 LBLCR)
带复制的基于局部性最少链接调度算法也是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。它与LBLC算法的不同之处是它要维护从一个目标IP地址到一组服务器的映射,而LBLC算法维护从一个目标IP地址到一台服务器的映射。LBLCR算法先根据请求的目标IP地址找出该目标IP地址对应的服务器组;按“最小连接”原则从该服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载;则按“最小连接”原则从整个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的程度。
7、.目标地址散列(简称DH)
“目标地址散列”调度算法根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。
8、源地址散列(简称SH)
“源地址散列”调度算法根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。
9、最短的期望的延迟(简称SED)
基于wlc算法。这个必须举例来说了。ABC三台机器分别权重123 ,连接数也分别是123。那么如果使用WLC算法的话一个新请求进入时它可能会分给ABC中的任意一个。使用SED算法后会进行这样一个运算
A(1+1)/1
B(1+2)/2
C(1+3)/3
根据运算结果,把连接交给C 。
10、最少队列调度(简称NQ)
无需队列,如果有台realserver的连接数=0就直接分配过去,不需要在进行sed运算。
其中rr、wrr、DH、SH是静态调度;其余为动态调度
(2)arp地址解析协议:
将IP地址影射到mac地址:要和其他设备进行通信,需要通过发送arp包告诉其他设备