LVS

LVS是Linux Virtual Server,linux虚拟服务器。终端互联网用户从外部访问公司的外部负载均衡服务器,终端用户的Web请求会发送给LVS调度器,调度器根据自己预设的算法决定将该请求发送给后端的某台Web服务器,比如,轮询算法可以将外部的请求平均分发给后端的所有服务器,终端用户访问LVS调度器虽然会被转发到后端真实的服务器,但如果真实服务器连接的是相同的存储,提供的服务也是相同的服务,最终用户不管是访问哪台真实服务器,得到的服务内容都是一样的,整个集群对用户而言都是透明的。最后根据LVS工作模式的不同,真实服务器会选择不同的方式将用户需要的数据发送到终端用户,LVS工作模式分为NAT、TUN、DR、FULLNAT

将server1设置为调度器

配置环境:

设置server1 yum源

[rhel-source]
name=Red Hat Enterprise Linux $releasever - $basearch - Source
baseurl=http://172.25.38.250/sources6.5/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release

[LoadBalancer]
name=LoadBalancer
baseurl=http://172.25.38.250/sources6.5/LoadBalancer
gpgcheck=0

Lvs activeConn 爆涨_Lvs activeConn 爆涨

yum install -y ipvsadm
ipvsadm -l    ##查看策略

Lvs activeConn 爆涨_服务器_02

lsmod 查看模块

modprobe ....  可安装模块

Lvs activeConn 爆涨_IP_03

DR直连模式:

负载均衡器和RS都使用同一个IP对外服务,但只有VS对ARP请求进行响应,所有RS对本身这个IP的ARP请求保持静默.也就是说,网关会把对这个服务IP的请求全部定向给VS,而VS收到数据包后根据调度算法,找出对应的RS,把目的MAC地址改为RS的MAC(因为IP一致)并将请求分发给这台RS,这时RS收到这个数据包,处理完成之后,由于IP一致,可以直接将数据返给客户,则等于直接从客户端收到这个数据包无异,处理后直接返回给客户端,由于负载均衡器要对二层包头进行改换,所以负载均衡器和RS之间必须在一个广播域,也可以简单的理解为在同一台交换机上.

数据流向:

clent -> prerouting 源CIP 目的VIP -> input -> ipvs 源MAC:将CIP MAC地址转换为 VIP MAC地址 目的MAC:将VIP MAC 转换为RS MAC 真实服务器地址 -> postrouting -> RS ->lo ->eth0 源VIP 目的CIP-> client

设置DR直连模式:

server1:

ip addr add 172.25.76.100/24 dev eth0
ipvsadm -A -t 172.25.38.100:80 -s rr   ## -A表示添加虚拟主机 rr:表示轮询模式 -t表示tcp连接 -s表示负载均衡模式
ipvsadm -a -t 172.25.38.100:80 -r 172.25.38.2:80 -g  ##-a表示向一个记录中添加真实主机 -g直连模式 -r真实主机ip
ipvsadm -a -t 172.25.38.100:80 -r 172.25.38.3:80 -g

Lvs activeConn 爆涨_客户端_04


Lvs activeConn 爆涨_服务器_05


server2 server3:

ip addr add 172.25.76.100/32 dev eth0

设置成与VIP相同的IP 原因:当LVS把client的包转发给Real-server时,因为包的目的IP地址是VIP,那么如果Real-server收到这个包后,发现包的目的IP不是自己的系统IP,那么就会认为这个包不是发给自己的,就会丢弃这个包,所以需要将这个IP地址绑到网卡上;当发送应答包给client时,Real-server就会把包的源和目的地址调换,直接回复给client。
设置子网为32原因:不接受外部请求,只进行内部通信

Lvs activeConn 爆涨_服务器_06

/etc/init.d/httpd start   ##打开httpd服务器

测试:
客户端:

curl 172.25.38.100

Lvs activeConn 爆涨_Lvs activeConn 爆涨_07

server1:

ipvsadm -l    ##可看到访问记录
若无法轮询 则客户端存储了某个真实服务器的地址

Lvs activeConn 爆涨_客户端_08

arp -an | grep 100   #查看储存的MAC地址

Lvs activeConn 爆涨_Lvs activeConn 爆涨_09

arp -d 172.25.38.100  ##删除存储的真实服务器硬件地址

Lvs activeConn 爆涨_服务器_10

解决上述问题使客户访问时只能访问到调度器:

1.arptables 使用防火墙策略限制用户访问服务器:

Lvs activeConn 爆涨_IP_11


server2 and server3

yum install arptables_jf -y     
arptables -A IN -d 172.25.38.100 -j DROP     ##-A添加策略 在IN -d 目的地址IP -j 处理方式 DROP 拒绝访问不回应
arptables -A OUT -s 172.25.38.100 -j mangle --mangle-ip-s 172.25.38.2  ##管理输出来自38.100的请求 以38.2输出

Lvs activeConn 爆涨_IP_12


Lvs activeConn 爆涨_IP_13

TUN隧道模式:

IP隧道(IP tunning)是一种数据包封装技术,它可以将原始数据包封装并添加新的包头(内容包括新的源地址及端口、目标地址及端口),从而实现将一个目标为调度器的VIP地址的数据包封装,通过隧道转发给后端的真实服务器(Real Server),通过将客户端发往调度器的原始数据包封装,并在其基础上添加新的数据包头(修改目标地址为调度器选择出来的真实服务器的IP地址及对应端口),LVS(TUN)模式要求真实服务器可以直接与外部网络连接,真实服务器在收到请求数据包后直接给客户端主机响应数据。相比LVS/DR模式,LVS/TUN对网络的消耗比较大,因为要支持ip tunnel的开销

设置TUN隧道模式:

配置环境:
server1:

ipvsadm -C    ##清除策略
ip addr del 172.25.38.100/24 dev eth0

Lvs activeConn 爆涨_服务器_14


Lvs activeConn 爆涨_服务器_15


server2:

ip addr del 172.25.38.100/32 dev eth0

Lvs activeConn 爆涨_IP_16


server3:

ip addr del 172.25.38.100/32 dev eth0

Lvs activeConn 爆涨_Lvs activeConn 爆涨_17


server1:

modprobe ipip    ##添加ipip模块

Lvs activeConn 爆涨_IP_18

ip addr add 172.25.38.100/24 dev tunl0

Lvs activeConn 爆涨_IP_19

ip link set up tunl0

Lvs activeConn 爆涨_服务器_20

ipvsadm -A -t 172.25.38.100:80 -s rr
 ipvsadm -a -t 172.25.38.100:80 -r 172.25.38.2:80 -i
 ipvsadm -a -t 172.25.38.100:80 -r 172.25.38.3:80 -i

Lvs activeConn 爆涨_Lvs activeConn 爆涨_21

/etc/init.d/ipvsadm save

Lvs activeConn 爆涨_Lvs activeConn 爆涨_22

server2:

modprobe ipip    ##添加ipip模块 
ip addr add 172.25.38.100/32 dev tunl0
ip link set up tunl0

Lvs activeConn 爆涨_客户端_23


Lvs activeConn 爆涨_服务器_24

sysctl -a | grep rp_filter
将反向过滤关闭 (linux系统反向过滤 系统在接收到一个IP包后,检查该IP是不是合乎要求,不合要求的IP包会被系统丢弃)
[root@server1 ~]# sysctl -w net.ipv4.conf.lo.rp_filter=0
net.ipv4.conf.lo.rp_filter = 0
[root@server1 ~]# sysctl -w net.ipv4.conf.eth0.rp_filter=0
net.ipv4.conf.eth0.rp_filter = 0
[root@server1 ~]# sysctl -w net.ipv4.conf.tunl0.rp_filter=0
net.ipv4.conf.tunl0.rp_filter = 0

Lvs activeConn 爆涨_服务器_25

vim /etc/sysctl.conf 
net.ipv4.conf.default.rp_filter = 0

Lvs activeConn 爆涨_IP_26

sysctl -p ##重新加载

server3:

modprobe ipip    ##添加ipip模块 
ip addr add 172.25.38.100/32 dev tunl0
ip link set up tunl0

Lvs activeConn 爆涨_IP_27

sysctl -a | grep rp_filter
将反向过滤关闭 (linux系统反向过滤 系统在接收到一个IP包后,检查该IP是不是合乎要求,不合要求的IP包会被系统丢弃)
 sysctl -w net.ipv4.conf.lo.rp_filter=0
net.ipv4.conf.lo.rp_filter = 0
sysctl -w net.ipv4.conf.eth0.rp_filter=0
net.ipv4.conf.eth0.rp_filter = 0
 sysctl -w net.ipv4.conf.tunl0.rp_filter=0
net.ipv4.conf.tunl0.rp_filter = 0
vim /etc/sysctl.conf 
net.ipv4.conf.default.rp_filter = 0
sysctl -p ##重新加载

Lvs activeConn 爆涨_Lvs activeConn 爆涨_28

使用ldirectord实现自动检测服务器健康状态

server1:

modprobe -r ipip
ip addr add 172.25.38.100/24 dev eth0
ipvsadm -C 
 ipvsadm -A -t 172.25.38.100:80 -s rr
 ipvsadm -a -t 172.25.38.100:80 -r 172.25.38.2:80 -g
 ipvsadm -a -t 172.25.38.100:80 -r 172.25.38.3:80 -g

Lvs activeConn 爆涨_Lvs activeConn 爆涨_29


server2:

modprobe -r ipip
ip addr add 172.25.38.100/32 dev eth0

Lvs activeConn 爆涨_IP_30


server3:

modprobe -r ipip
ip addr add 172.25.38.100/32 dev eth0

Lvs activeConn 爆涨_Lvs activeConn 爆涨_31


arptables策略保留

模拟问题:

若此时一台服务器挂了,在轮询访问时一台服务其拒绝访问

Lvs activeConn 爆涨_客户端_32


server1:

安装软件ldirectord-3.9.5-3.1.x86_64

vim /etc/yum.repos.d/rhel-source.repo   ##添加高可用的软件包

[HighAvailability]
name=HighAvailability
baseurl=http://172.25.38.250/sources6.5/HighAvailability
gpgcheck=0
yum clean all
yum repolist   ##此时有高可用的56个包,但是安装还需要依赖性,再额外下载一个安装包ldirectord-3.9.5-3.1.x86_64.rpm

Lvs activeConn 爆涨_客户端_33

yum install ldirectord-3.9.5-3.1.x86_64.rpm   ##安装完成

配置

rpm -qpl ldirectord-3.9.5-3.1.x86_64.rpm

Lvs activeConn 爆涨_服务器_34

cp /usr/share/doc/ldirectord-3.9.5/ldirectord.cf cd /etc/ha.d

Lvs activeConn 爆涨_Lvs activeConn 爆涨_35

vim /etc/ha.d/ldirectord.cf
# Global Directives
checktimeout=3
checkinterval=1
#fallback=127.0.0.1:80
#fallback6=[::1]:80
autoreload=yes
#logfile="/var/log/ldirectord.log"
#logfile="local0"
#emailalert="admin@x.y.z"
#emailalertfreq=3600
#emailalertstatus=all
quiescent=no

# Sample for an http virtual service
virtual=172.25.38.100:80
        real=172.25.38.2:80 gate
        real=172.25.38.3:80 gate
        fallback=127.0.0.1:80 gate
        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

Lvs activeConn 爆涨_IP_36

/etc/init.d/ldirectord start

Lvs activeConn 爆涨_客户端_37


检测

客户端:

curl 172.25.38.100

Lvs activeConn 爆涨_IP_38

vim /etc/www/html/index.html

Lvs activeConn 爆涨_Lvs activeConn 爆涨_39

vim /etc/httpd/conf/httpd.conf
80
/etc/init.d/httpd restart

关闭server2 server3

curl 172.25.38.100

Lvs activeConn 爆涨_客户端_40

NAT 模式

客户端将请求发往前端的负载均衡器,请求报文源地址是CIP,目标地址为VIP。负载均衡器收到报文后,发现请求的是在规则里面存在的地址,那么它将客户端请求报文的目标地址改为了后端服务器的RIP地址并将报文根据算法发送出去。报文送到Real Server后,由于报文的目标地址是自己,所以会响应该请求,并将响应报文返还给LVS。然后lvs将此报文的源地址修改为本机并发送给客户端。

配置NAT模式

环境:
Server1: eth0 172.25.76.1 eth1:172.25.254.101
Server2:eth0 172.25.76.2
Server3:eth0 172.25.76.3
Client:172.25.254.76

Lvs activeConn 爆涨_IP_41


Lvs activeConn 爆涨_Lvs activeConn 爆涨_42


Lvs activeConn 爆涨_IP_43

在Server1中:

是双网卡可连接

Lvs activeConn 爆涨_客户端_44


Lvs activeConn 爆涨_客户端_45

添加ipvsadm策略

Lvs activeConn 爆涨_Lvs activeConn 爆涨_46


Lvs activeConn 爆涨_服务器_47


在server2中:

Lvs activeConn 爆涨_IP_48


Lvs activeConn 爆涨_客户端_49


在server3中:

Lvs activeConn 爆涨_Lvs activeConn 爆涨_50


Lvs activeConn 爆涨_服务器_51


在client中测试:

Lvs activeConn 爆涨_Lvs activeConn 爆涨_52

FULLNAT 模式

无论是 DR 还是 NAT 模式,不可避免的都有一个问题:LVS 和 RS 必须在同一个 VLAN 下,否则 LVS 无法作为 RS 的网关。
这引发的两个问题是:同一个 VLAN 的限制导致运维不方便,跨 VLAN 的 RS 无法接入。LVS 的水平扩展受到制约。当 RS 水平扩容时,总有一天其上的单点 LVS 会成为瓶颈.Full-NAT 由此而生,解决的是 LVS 和 RS 跨 VLAN 的问题,而跨 VLAN 问题解决后,LVS 和 RS 不再存在 VLAN 上的从属关系,可以做到多个 LVS 对应多个 RS,解决水平扩容的问题
传输过程:在包从 LVS 转到 RS 的过程中,源地址从客户端 IP 被替换成了 LVS 的内网 IP。内网 IP 之间可以通过多个交换机跨 VLAN 通信。当 RS 处理完接受到的包,返回时,会将这个包返回给 LVS 的内网 IP,这一步也不受限于 VLAN。LVS 收到包后,在 NAT 模式修改源地址的基础上,再把 RS 发来的包中的目标地址从 LVS 内网 IP 改为客户端的 IP。Full-NAT 主要的思想是把网关和其下机器的通信,改为了普通的网络通信,从而解决了跨 VLAN 的问题。

keepalived实现lvs高可用

建立虚拟机server4

server1:

tar zxf keepalive-2.0.6.tar.gz
yum install -y openssl-devel
./configure --prefix=/usr/local/keepalived --with-init=SYSV
make && make install

Lvs activeConn 爆涨_IP_53

chmod  +x /usr/local/keepalived/etc/rc.d/init.d/keepalived
ln -s /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
 ln -s /usr/local/keepalived/etc/keepalived/keepalived.conf samples/
 ln -s /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
 ln -s /usr/local/keepalived/etc/keepalived/ /etc/
 ln -s /usr/local/keepalived/sbin/keepalived /sbin/

Lvs activeConn 爆涨_IP_54


Lvs activeConn 爆涨_服务器_55


Lvs activeConn 爆涨_服务器_56

vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
     root@localhost
   }
   notification_email_from keepalived@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.38.100
    }
}

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

    real_server 172.25.38.2 80 {
	TCP_CHECK {
        weight 1
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }

    real_server 172.25.38.3 80 {
        TCP_CHECK {
        weight 1
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }

}
scp -r keepalived server4:/usr/local/    ##将配置信息复制给从服务器

Lvs activeConn 爆涨_Lvs activeConn 爆涨_57


Lvs activeConn 爆涨_服务器_58

/etc/init.d/ldirectord stop    ## keepalived 可实现健康检查  所以关闭ldirectord
chkconfig ldirectord off

server4:

[root@server4 ~]# ln -s /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
[root@server4 ~]# ln -s /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
[root@server4 ~]# ln -s /usr/local/keepalived/etc/keepalived/ /etc/
[root@server4 ~]# ln -s /usr/local/keepalived/sbin/keepalived /sbin/
chmod  +x /usr/local/keepalived/etc/rc.d/init.d/keepalived

Lvs activeConn 爆涨_IP_59

[root@server4 rc.d]# vim /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

global_defs {
   notification_email {
     root@localhost
   }
   notification_email_from keepalived@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 BACKUP
    interface eth0
    virtual_router_id 51
    priority 50
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.25.38.100
    }
}

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

    real_server 172.25.38.2 80 {
	TCP_CHECK {
        weight 1
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }

    real_server 172.25.38.3 80 {
        TCP_CHECK {
        weight 1
            connect_timeout 3
            retry 3
            delay_before_retry 3
        }
    }

}

Lvs activeConn 爆涨_服务器_60

检测ip是否会飘移

Lvs activeConn 爆涨_服务器_61

Lvs activeConn 爆涨_Lvs activeConn 爆涨_62

Lvs activeConn 爆涨_IP_63

lvs 内核中的连接调度算法

轮叫调度(Round-Robin Scheduling)
加权轮叫调度(Weighted Round-Robin Scheduling)
最小连接调度(Least-Connection Scheduling)
加权最小连接调度(Weighted Least-Connection Scheduling)
基于局部性的最少链接(Locality-Based Least Connections Scheduling)
带复制的基于局部性最少链接(Locality-Based Least Connections with Replication Scheduling)
目标地址散列调度(Destination Hashing Scheduling)
源地址散列调度(Source Hashing Scheduling)
最少期望延迟
永不排队

rr轮播调度

Round Robin Scheduling:算法就是以轮叫的方式依次将请求调度不同的服务器。算法的优点是其简洁性,它无需记录当前所有连接的状态,所以它是一种无状态调度

wrr加权轮播调度

Weighted Round-Robin Scheduling算法可以解决服务器间性能不一的情况,它用相应的权值表示服务器的处理性能,服务器的缺省权值为1。假设服务器A的权值为1,B的 权值为2,则表示服务器B的处理性能是A的两倍。加权轮叫调度算法是按权值的高低和轮叫方式分配请求到各服务器。权值高的服务器先收到的连接,权值高的服 务器比权值低的服务器处理更多的连接,相同权值的服务器处理相同数目的连接数。

lc最小连接调度

Least-Connection Scheduling算法是把新的连接请求分配到当前连接数最小的服务器。最小连接调度是一种动态调度算法,它通过服务器当前所活跃的连接数来估计服务器的负载情况。

wlc加权最少连接调度

Weighted Least-Connection Scheduling算法是最小连接调度的超集,各个服务器用相应的权值表示其处理性能。服务器的缺省权值为1,系统管理员可以动态地设置服务器的权 值。加权最小连接调度在调度新连接时尽可能使服务器的已建立连接数和其权值成比例。

lblc基于局部性的最少连接调度

先根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不 存在,或者该服务器超载且有服务器处于其一半的工作负载,则用“最少链接”的原则选出一个可用的服务器,将请求发送到该服务器。

lblcr带复制的基于局部性的最少链接调度

先根据请求的目标IP地址找出该目标IP地址对应的服务器组;按“最小连接”原则从该服务器组中选出一台服务器,若服务器没有超载, 将请求发送到该服务器;若服务器超载;则按“最小连接”原则从整个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该 服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低负载的程度。

dh目标地址散列调度

先根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。

sh源地址散列调度

根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。

sed最少期望延迟

不考虑非活动链接,谁的权重大,优先选择权重大的服务器来接收请求,但权重大的机器会比较忙

nq永不排队

无需队列,如果有realserver的连接数为0就直接分配过去