LVS实现(VS/DR)负载均衡和Keepalived高可用

一、虚拟服务器LVS基本介绍

LVS是Linux Virtual Server的简写,即Linux虚拟服务器,是一个虚拟的服务器集群系统。这是一个由章文嵩博士发起的一个开源项目,它的官方网站是 http://www.linuxvirtualserver.org。LVS工作在一台server上提供Directory(负载均衡器)的功能,本身并不提供服务,只是把特定的请求转发给对应的realserver(真正提供服务的主机),从而实现集群环境中的负载均衡。LVS架构从逻辑上可分为调度层、Server集群层和共享存储。
【1】技术简介
LVS集群采用IP负载均衡技术和基于内容请求分发技术。调度器具有很好的吞吐率,将请求均衡地转移到不同的服务器上执行,且调度器自动屏蔽掉服务器的故障,从而将一组服务器构成一个高性能的、高可用的虚拟服务器。整个服务器集群的结构对客户是透明的,而且无需修改客户端和服务器端的程序。为此,在设计时需要考虑系统的透明性、可伸缩性、高可用性和易管理性。
【2】集群采用三层结构
一般来说,LVS集群采用三层结构,其主要组成部分为:
A.负载调度器(load balancer),它是整个集群对外面的前端机,负责将客户的请求发送到一组服务器上执行,而客户认为服务是来自一个IP地址(我们可称之为虚拟IP地址)上的。
B.服务器池(server pool),是一组真正执行客户请求的服务器,执行的服务有WEB、MAIL、FTP和DNS等。
C.共享存储(shared storage),它为服务器池提供一个共享的存储区,这样很容易使得服务器池拥有相同的内容,提供相同的服务。

二、LVS的基本工作原理

这里写图片描述

1. 当用户向负载均衡调度器(Director Server)发起请求,调度器将请求发往至内核空间
2. PREROUTING链首先会接收到用户请求,判断目标IP确定是本机IP,将数据包发往INPUT链
3. IPVS是工作在INPUT链上的,当用户请求到达INPUT时,IPVS会将用户请求和自己已定义好的集群服务进行比对,如果用户请求的就是定义的集群服务,那么此时IPVS会强行修改数据包里的目标IP地址及端口,并将新的数据包发往POSTROUTING链
4. POSTROUTING链接收数据包后发现目标IP地址刚好是自己的后端服务器,那么此时通过选路,将数据包最终发送给后端的服务器

三、LVS的组成

LVS 由2部分程序组成,包括 ipvs 和 ipvsadm。

1. ipvs(ip virtual server):一段代码工作在内核空间,叫ipvs,是真正生效实现调度的代码。
2. ipvsadm:另外一段是工作在用户空间,叫ipvsadm,负责为ipvs内核框架编写规则,定义谁是集群服务,而谁是后端真实的服务器(Real Server)

四、LVS相关术语

  1. DS:Director Server。指的是前端负载均衡器节点。
  2. RS:Real Server。后端真实的工作服务器。
  3. VIP:向外部直接面向用户请求,作为用户请求的目标的IP地址。
  4. DIP:Director Server IP,主要用于和内部主机通讯的IP地址。
  5. RIP:Real Server IP,后端服务器的IP地址。
  6. CIP:Client IP,访问客户端的IP地址。

下边是三种工作模式的原理和特点总结。

五、LVS/NAT原理和特点

1. 重点理解NAT方式的实现原理和数据包的改变。
这里写图片描述

(a). 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP
(b). PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
(c). IPVS比对数据包请求的服务是否为集群服务,若是,修改数据包的目标IP地址为后端服务器IP,然后将数据包发至POSTROUTING链。 此时报文的源IP为CIP,目标IP为RIP
(d). POSTROUTING链通过选路,将数据包发送给Real Server
(e). Real Server比对发现目标为自己的IP,开始构建响应报文发回给Director Server。 此时报文的源IP为RIP,目标IP为CIP
(f). Director Server在响应客户端前,此时会将源IP地址修改为自己的VIP地址,然后响应给客户端。 此时报文的源IP为VIP,目标IP为CIP
2. LVS-NAT模型的特性

RS应该使用私有地址,RS的网关必须指向DIP
DIP和RIP必须在同一个网段内
请求和响应报文都需要经过Director Server,高负载场景中,Director Server易成为性能瓶颈
支持端口映射
RS可以使用任意操作系统
缺陷:对Director Server压力会比较大,请求和响应都需经过director server

六、LVS/DR原理和特点

1. 重将请求报文的目标MAC地址设定为挑选出的RS的MAC地址

这里写图片描述
(a) 当用户请求到达Director Server,此时请求的数据报文会先到内核空间的PREROUTING链。 此时报文的源IP为CIP,目标IP为VIP
(b) PREROUTING检查发现数据包的目标IP是本机,将数据包送至INPUT链
(c) IPVS比对数据包请求的服务是否为集群服务,若是,将请求报文中的源MAC地址修改为DIP的MAC地址,将目标MAC地址修改RIP的MAC地址,然后将数据包发至POSTROUTING链。 此时的源IP和目的IP均未修改,仅修改了源MAC地址为DIP的MAC地址,目标MAC地址为RIP的MAC地址
(d) 由于DS和RS在同一个网络中,所以是通过二层来传输。POSTROUTING链检查目标MAC地址为RIP的MAC地址,那么此时数据包将会发至Real Server。
(e) RS发现请求报文的MAC地址是自己的MAC地址,就接收此报文。处理完成之后,将响应报文通过lo接口传送给eth0网卡然后向外发出。 此时的源IP地址为VIP,目标IP为CIP
(f) 响应报文最终送达至客户端

七、LVS的八种调度算法

1. 轮叫调度 rr
这种算法是最简单的,就是按依次循环的方式将请求调度到不同的服务器上,该算法最大的特点就是简单。轮询算法假设所有的服务器处理请求的能力都是一样的,调度器会将所有的请求平均分配给每个真实服务器,不管后端 RS 配置和处理能力,非常均衡地分发下去。

2. 加权轮叫 wrr
这种算法比 rr 的算法多了一个权重的概念,可以给 RS 设置权重,权重越高,那么分发的请求数越多,权重的取值范围 0 – 100。主要是对rr算法的一种优化和补充, LVS 会考虑每台服务器的性能,并给每台服务器添加要给权值,如果服务器A的权值为1,服务器B的权值为2,则调度到服务器B的请求会是服务器A的2倍。权值越高的服务器,处理的请求越多。

3. 最少链接 lc
这个算法会根据后端 RS 的连接数来决定把请求分发给谁,比如 RS1 连接数比 RS2 连接数少,那么请求就优先发给 RS1

4. 加权最少链接 wlc
这个算法比 lc 多了一个权重的概念。

5. 基于局部性的最少连接调度算法 lblc
这个算法是请求数据包的目标 IP 地址的一种调度算法,该算法先根据请求的目标 IP 地址寻找最近的该目标 IP 地址所有使用的服务器,如果这台服务器依然可用,并且有能力处理该请求,调度器会尽量选择相同的服务器,否则会继续选择其它可行的服务器

6. 复杂的基于局部性最少的连接算法 lblcr
记录的不是要给目标 IP 与一台服务器之间的连接记录,它会维护一个目标 IP 到一组服务器之间的映射关系,防止单点服务器负载过高。

7. 目标地址散列调度算法 dh
该算法是根据目标 IP 地址通过散列函数将目标 IP 与服务器建立映射关系,出现服务器不可用或负载过高的情况下,发往该目标 IP 的请求会固定发给该服务器。

8. 源地址散列调度算法 sh
与目标地址散列调度算法类似,但它是根据源地址散列算法进行静态分配固定的服务器资源。


Heartbeat
Heartbeat 项目是 Linux-HA 工程的一个组成部分,其与lvs在本质上无关。
Heartbeat提供了2个核心的功能正是lvs所需要的,心跳监测部分和资源接管,心跳监测可以通过网络链路和串口进行,而且支持冗余链路,安装了 Heartbeat 的两台机器会通过心跳检测互相检测对方的状态,当检测到对方失效的时候会调用资源接管来做接管服务器,保证高可靠性。
在一个高可靠的lvs集群中,负载调度IPVS部分一般由2台服务器组成,一台负责调度,一台负责备用,当负责调度的服务器出现问题的时候迅速切换到备用机器上,而heartbeat 就是负责检测,负载调度 IPVS 的可用性,并在出现问题的时候切换到备用 IPVS 上面。

ldirectord
ldirectord是专门为LVS监控而编写的,用来监控lvs架构中服务器池(server pool) 的服务器状态。
ldirectord 运行在 IPVS 节点上, ldirectord作为一个守护进程启动后会对服务器池中的每个真是服务器发送请求进行监控,如果 服务器没有响应 ldirectord 的请求,那么ldirectord 认为该服务器不可用, ldirectord 会运行 ipvsadm 对 IPVS表中该服务器进行删除,如果等下次再次检测有相应则通过ipvsadm 进行添加。

Keepalived
Keepalived在这里主要用作RealServer的健康状态检查以及LoadBalance主机和BackUP主机之间failover的实现 。IPVS通常与keepalived配合使用,后者也是LVS项目的子项目之一,用于检测服务器的状态。
在lvs体系中,Keepalived主要有如下3个功能:
1 管理LVS负载均衡软件
2 实现对LVS集群节点的健康检查功能
3 作为系统网络服务的高可用功能
即 Keepalived 实现了 heartbeat + ldirectord 的功能。

LVS的两种实现方法(heartbeat与KeepAlived)
第一种集群方式 : LVS+heartbeat+ldirectord实现集群负载
第二种集群方式:LVS+KeepAlived集群负载
本文主要介绍 第二种集群方式:LVS+KeepAlived集群负载


实验一:LVS负载均衡

Server1:
<1>添加yum源完整的安装包
将6.5的镜像挂载到/var/www/html/source6.5
这里写图片描述

[root@server1 ~]# cd /etc/yum.repos.d/
[root@server1 yum.repos.d]# vim rhel-source.repo

gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release

[HighAvailability]
name=HighAvailability
baseurl=http://172.25.8.250/source6.5/HighAvailability
gpgcheck=0

[LoadBalancer]
name=LoadBalancer
baseurl=http://172.25.8.250/source6.5/LoadBalancer
gpgcheck=0

[ResilientStorage]
name=ResilientStorage
baseurl=http://172.25.8.250/source6.5/ResilientStorage
gpgcheck=0

[ScalableFileSystem]
name=ScalableFileSystem
baseurl=http://172.25.8.250/source6.5/ScalableFileSystem
gpgcheck=0

这里写图片描述

[root@server1 yum.repos.d]# yum repolist
Loaded plugins: product-id, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
HighAvailability                                                              | 3.9 kB     00:00     
HighAvailability/primary_db                                                   |  43 kB     00:00     
LoadBalancer                                                                  | 3.9 kB     00:00     
LoadBalancer/primary_db                                                       | 7.0 kB     00:00     
ResilientStorage                                                              | 3.9 kB     00:00     
ResilientStorage/primary_db                                                   |  47 kB     00:00     
ScalableFileSystem                                                            | 3.9 kB     00:00     
ScalableFileSystem/primary_db                                                 | 6.8 kB     00:00     
rhel-source                                                                   | 3.9 kB     00:00     

repo id                        repo name                                                       status
HighAvailability               HighAvailability                                                   56
LoadBalancer                   LoadBalancer                                                        4
ResilientStorage               ResilientStorage                                                   62
ScalableFileSystem             ScalableFileSystem                                                  7
rhel-source                    Red Hat Enterprise Linux 6Server - x86_64 - Source              3,690
repolist: 3,819                # 6.5镜像yum源完整的安装包

<2>安装管理集群服务ipvsadm

[root@server1 ~]# yum install ipvsadm -y

<3>临时添加ip,并设置为lvs的vip

[root@server1 ~]# ip addr add 172.25.8.100/24 dev eth0  #临时添加ip
[root@server1 ~]# ipvsadm -A -t 172.25.8.100:80 -s rr   # A:添加虚拟服务 a:添加真实主机 s:调度算法 rr:轮询

添加虚拟ip后:
这里写图片描述

查询ipvsadm状态:
这里写图片描述
<4>vip添加RS地址,并设置为DR模式

[root@server1 ~]# ipvsadm -a -t 172.25.8.100:80 -r 172.25.8.2:80 -g    # a:添加真实主机  t:地址和端口号 rRS地址 gDR模式
[root@server1 ~]# ipvsadm -a -t 172.25.8.100:80 -r 172.25.8.3:80 -g

查询ipvsadm状态
这里写图片描述
<5>保存ipvsadm操作

[root@server1 ~]# /etc/init.d/ipvsadm save
ipvsadm: Saving IPVS table to /etc/sysconfig/ipvsadm:     [  OK  ]

servser2:
<1>修改Apache服务测试页内容,并开启httpd服务

[root@server2 ~]# vim /var/www/html/index.html 
server2
[root@server2 ~]# /etc/init.d/httpd start
Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using 172.25.8.2 for ServerName
                                                           [  OK  ]

<2>Realserver同样添加虚拟ip地址,与调度器虚拟ip地址一致

[root@server2 ~]# ip addr add 172.25.8.100/24 dev eth0

<3>安装arp防火墙
arp防火墙用来屏蔽数据包,拦截ip冲突,因为虚拟机与real server的地址一致,所以进入real server时需要把虚拟ip DROP掉,即拦截real server的虚拟ip

[root@server2 ~]# yum install arptables_jf -y

<4>设置arp抑制

[root@server2 ~]# vim /var/www/html/index.html
[root@server2 ~]# arptables -A IN -d 172.25.8.100 -j DROP   #拒绝客户端访问realserver的虚拟ip,只要输入进来直接DROP掉
[root@server2 ~]# arptables -A OUT -s 172.25.8.100 -j mangle --mangle-ip-s 172.25.8.2    #由于tcp三次握手,出去时仍要以vip地址形式才会握手,而真正将数据传输给客户端的就是realserver,mangle参数就是这个功能
[root@server2 ~]# /etc/init.d/arptables_jf save
Saving current rules to /etc/sysconfig/arptables:         [  OK  ]

查看arp防火墙状态

[root@server2 ~]# arptables -L
Chain IN (policy ACCEPT)
target     source-ip            destination-ip       source-hw          destination-hw     hlen   op         hrd        pro       
DROP       anywhere             172.25.8.100         anywhere           anywhere           any    any        any        any       

Chain OUT (policy ACCEPT)
target     source-ip            destination-ip       source-hw          destination-hw     hlen   op         hrd        pro       
mangle     172.25.8.100         anywhere             anywhere           anywhere           any    any        any        any       --mangle-ip-s server2 

Chain FORWARD (policy ACCEPT)
target     source-ip            destination-ip       source-hw          destination-hw     hlen   op         hrd        pro       

Server3:
<1>修改Apache服务测试页内容,并开启httpd服务

[root@server3 ~]# vim /var/www/html/index.html 
server3
[root@server3 ~]# /etc/init.d/httpd start
Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using 172.25.8.3 for ServerName
                                                           [  OK  ]

<2>Real server同样添加虚拟ip地址,与调度器虚拟ip地址一致

[root@server3 ~]# ip addr add 172.25.8.100/24 dev eth0

<3>安装arp防火墙
arp防火墙用来屏蔽数据包,拦截ip冲突,因为虚拟机与real server的地址一致,所以进入real server时需要把虚拟ip DROP掉,即拦截real server的虚拟ip

[root@server3 ~]#  yum install arptables_jf -y

<4>设置arp抑制

[root@server3 ~]# arptables -A IN -d 172.25.8.100 -j DROP      #拒绝客户端访问realserver的虚拟ip,只要输入进来直接DROP掉
[root@server3 ~]# arptables -A OUT -s 172.25.8.100 -j mangle --mangle-ip-s 172.25.8.3    #由于tcp三次握手,出去时仍要以vip地址形式才会握手,而真正将数据传输给客户端的就是realserver,mangle参数就是这个功能
[root@server3 ~]# /etc/init.d/arptables_jf save
Saving current rules to /etc/sysconfig/arptables:          [  OK  ]

查看arp防火墙状态


[root@server3 ~]# arptables -L
Chain IN (policy ACCEPT)
target     source-ip            destination-ip       source-hw          destination-hw     hlen   op         hrd        pro       
DROP       anywhere             172.25.8.100         anywhere           anywhere           any    any        any        any       

Chain OUT (policy ACCEPT)
target     source-ip            destination-ip       source-hw          destination-hw     hlen   op         hrd        pro       
mangle     172.25.8.100         anywhere             anywhere           anywhere           any    any        any        any       --mangle-ip-s server3 

Chain FORWARD (policy ACCEPT)
target     source-ip            destination-ip       source-hw          destination-hw     hlen   op         hrd        pro    

测试:
1.负载均衡
物理机访问172.25.8.100
这里写图片描述
server1查看ipvsadm状态,server2、3负载均衡
这里写图片描述
2.显示arp缓冲区中的条目
示图:arp缓冲区中MAC地址与server1的MAC地址相同
这里写图片描述
这里写图片描述


实验二:LVS健康检查

server1:

<1>.下载并安装监控软件

下载地址:http://rpm.pbone.net/index.php3/stat/4/idpl/23860919/dir/centos_6/com/ldirectord-3.9.5-3.1.x86_64.rpm.html

[root@server1 ~]# yum install ldirectord-3.9.5-3.1.x86_64.rpm -y

<2>修改配置文件

[root@server1 ~]# rpm -qpl ldirectord-3.9.5-3.1.x86_64.rpm    #查找配置文件

这里写图片描述


[root@server1 ~]# cd /etc/ha.d/
[root@server1 ha.d]# ls
resource.d  shellfuncs
[root@server1 ha.d]# cp /usr/share/doc/ldirectord-3.9.5/ldirectord.cf .
[root@server1 ha.d]# ls
ldirectord.cf  resource.d  shellfuncs
[root@server1 ha.d]# vim ldirectord.cf      #修改配置文件
virtual=172.25.8.100:80
        real=172.25.8.2:80 gate
        real=172.25.8.3:80 gate
        fallback=127.0.0.1:80 gate          #server2、3服务down后,访问本机80端口
        service=http
        scheduler=rr                        #调度模式:轮询
        #persistent=600
        #netmask=255.255.255.255
        protocol=tcp
        checktype=negotiate
        checkport=80                        #端口
        request="index.html"                #文件
        #receive="Test Page"
        #virtualhost=www.x.y.z
[root@server1 ha.d]# /etc/init.d/ldirectord start  开启服务
Starting ldirectord... success

修改配置文件内容:
这里写图片描述

<3>测试页

[root@server1 ha.d]# vim /var/www/html/index.html
此网站正在维护中...

<4>监听端口80

[root@server1 html]# vim /etc/httpd/conf/httpd.conf 
136 Listen 80
[root@server1 html]# /etc/init.d/httpd start

<5>Real Server主机关闭http服务,Virtual Server主机

[root@server2 ~]# /etc/init.d/httpd stop
Stopping httpd:                                            [  OK  ]
[root@server3 ~]# /etc/init.d/httpd stop
Stopping httpd:                                            [  OK  ]

查看ipvsadm状态
这里写图片描述
测试:物理机
这里写图片描述

这里写图片描述

注意:当安装 php 模块后,默认优先读取 index.php,应将index.php删除,才可读取Index.html

[root@server1 html]# ls
bansys            config.php  index.php         static
class_socket.php  index.html  purge_action.php
[root@server1 html]# rm  -rf index.php 

实验三:高可用集群High-Avaliability

实验环境:
server1:
<1>停止 ldirectord 服务

[root@server1 ~]# /etc/init.d/ldirectord stop
Stopping ldirectord... success
[root@server1 ~]# chkconfig ldirectord off

<2>下载并安装keepalived

[root@server1 ~]# ls
keepalived-2.0.6.tar.gz
[root@server1 ~]# tar zxf keepalived-2.0.6.tar.gz 
[root@server1 ~]# cd keepalived-2.0.6
[root@server1 keepalived-2.0.6]# ./configure --prefix=/usr/local/keepalived --with-init=SYSV
[root@server1 keepalived-2.0.6]# yum install openssl-devel.x86_64 -y  #compile报错时,解决依赖性, 安装 openssl-devel
[root@server1 keepalived-2.0.6]# make && make install

<3>配置keepalived服务

[root@server1 ~]# 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/keepalived/ /etc         
[root@server1 init.d]# ln -s /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
[root@server1 init.d]# ln -s /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d
[root@server1 init.d]# ln -s /usr/local/keepalived/sbin/keepalived /sbin
[root@server1 init.d]# vim /etc/keepalived/keepalived.conf 

! Configuration File for keepalived

global_defs {
   notification_email {
     root@localhost
   }
   notification_email_from Alexandre.Cassen@localhost
   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
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.25.8.100
    }
}

virtual_server 172.25.8.100 80 {
    delay_loop 3
    lb_algo rr
    lb_kind DR
    #persistence_timeout 50
    protocol TCP

    real_server 172.25.8.2 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }
    real_server 172.25.8.3 80 {
        weight 1
        TCP_CHECK {
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }
}

<4>scp配置文件给server4

[root@server1 ~]# scp -r /usr/local/keepalived/ server4:/usr/local/
[root@server1 ~]# scp -r /etc/keepalived/keepalived.conf server4:/etc/keepalived/

注意:server1和server4都要安装scp

[root@server4 ~]# yum search /* openssh
[root@server4 ~]# yum install openssh-clients.x86_64 -y

server4:

<1>配置keepalived服务

[root@server4 ~]# ln -s /usr/local/keepalived/etc/keepalived/ /etc/
[root@server4 ~]# ln -s /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
[root@server4 ~]# ln -s /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
[root@server4 ~]# ln -s /usr/local/keepalived/sbin/keepalived /sbin/
[root@server4 ~]# cd /usr/local/keepalived/etc/rc.d/init.d
[root@server4 init.d]# chmod +x keepalived 
[root@server4 init.d]# vim /etc/keepalived/keepalived.conf  ##主要修改以下部分
vrrp_instance VI_1 {
    state BACKUP                    ##备用
    interface eth0
    virtual_router_id 51
    priority 50                     ##优先级
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.25.8.100
    }
}

<2>重启服务

[root@server4 ~]# /etc/init.d/keepalived start
[root@server4 ~]# /etc/init.d/keepalived reload

server2:

[root@server2 ~]# /etc/init.d/httpd start

server3:

[root@server3 ~]# /etc/init.d/httpd start

测试:
<1>轮询
这里写图片描述

猜你喜欢

转载自blog.csdn.net/wwy0324/article/details/81283371
今日推荐