LVS+keepalived 实现负载均衡和高可用
本文最后更新于 2365 天前,其中的信息可能已经有所发展或是发生改变。

负载均衡集群

负载均衡集群指使用多台提供相同服务的服务器组成集群系统,提高服务的并发处理能力。负载均衡集群的前端使用一个调度器,将客户端请求平均分配到后端的服务器中,同时调度器可能还具有后端服务器状态检测的功能,将故障的服务器自动下线,使得集群具有一定的容错能力。

使用负载均衡集群能够有效的扩展服务的并发能力,负载均衡集群中的主机间应该尽量的「低耦合」,最好是「无状态」的,这样就能够方便的增加主机实现扩展。

常见的负载均衡器

根据工作在的协议层划分可划分为:

  • 四层负载均衡:根据请求报文中的目标地址和端口进行调度
  • 七层负载均衡:根据请求报文的内容进行调度,这种调度属于「代理」的方式

根据软硬件划分:

  • 硬件负载均衡:
    • F5 的 BIG-IP
    • Citrix 的 NetScaler
    • 这类硬件负载均衡器通常能同时提供四层和七层负载均衡,但同时也价格不菲
  • 软件负载均衡:
    • TCP 层:LVS,HaProxy,Nginx
    • 基于 HTTP 协议:Haproxy,Nginx,ATS(Apache Traffic Server),squid,varnish
    • 基于 MySQL 协议:mysql-proxy

LVS

LVS 是一个工作在四层的负载均衡器,它的实现和 iptables/netfilter 类似,工作在内核空间的 TCP/IP 协议栈上,LVS 工作在 INPUT Hook Funtion 上,并在 INPUT 设置附加规则,一旦客户端请求的是集群服务,LVS 会强行修改请求报文,将报文发往 POSTROUTING,转发至后端的主机。

和 iptables/netfilter 类似,LVS 也是两段式的:

  • ipvsadm:工作在用户空间,负责定义和管理集群服务的规则
  • ipvs:工作在内核中,在 2.4.23 之前,必须向内核打补丁,并重新编译内核。在 2.4.23 和 2.6 之后的版本,ipvs 直接内置在内核中。

LVS 集群的设备地址命名

  • VIP:Virtual IP,LVS 面向用户请求的 IP 地址
  • RIP:Real server IP,后端服务器用于和 LVS 通信的 IP 地址
  • DIP:Director IP,LVS 用户和后端服务器通信的 IP 地址
  • CIP:Client IP,客户端 IP 地址

LVS 的工作模型

LVS-NAT

LVS-NAT 模型类似于 DNAT,工作机制与 DNAT 一样,当客户端请求的是集群服务时,LVS 修改请求报文的目标地址为 RIP,转发至后端的 RealServer,并修改后端响应报文的源地址为 VIP,响应至客户端。

在 LVS-NAT 模型下,Director 进出请求报文都经过 Director,因此 Director 的压力是比较大的。

LVS-NAT 的特性:

  • 集群节点跟 Director 必须在同一个 IP 网络中
  • RIP 通常是私有地址,仅用于各集群节点间的通信
  • Director 位于 client 和 Realserver 之间,负责处理进出的所有报文
  • Realserver 必须将网关指向 DIP
  • 支持端口映射
  • 较大规模应用场景中,Director 易成为系统瓶颈(bottleneck)

LVS-DR

\

DR 值 Direct Routing,直接路由,DR 模型中,Director 和 Realserver 处在同一网络中,对于 Director,VIP 用于接受客户端请求,DIP 用于和 Realserver 通信。对于 Realserver,每个 Realserver 都配有和 Director 相同的 VIP(此 VIP 隐藏,关闭对 ARP 请求的响应),仅用户响应客户端的请求,RIP 用于和 Director 通信。

当客户端请求集群服务时,请求报文发送至 Director 的 VIP(Realserver的 VIP 不会响应 ARP 请求),Director 将客户端报文的源和目标 MAC 地址进行重新封装,将报文转发至 Realserver,Realserver 接收转发的报文。此时报文的源 IP 和目标 IP 都没有被修改,因此 Realserver 接受到的请求报文的目标 IP 地址为本机配置的 VIP,它将使用自己的 VIP 直接响应客户端。

LVS-DR 模型中,客户端的响应报文不会经过 Director,因此 Director 的并发能力有很大提升。

LVS-DR 模型的特性:

  • 保证前端路由器将目标地址为 VIP 的报文通过 ARP 解析后送往 Director。
    • 静态绑定:在前端路由将 VIP 对应的目标 MAC 地址静态配置为Director VIP 接口的 MAC 地址。
    • arptables:在各 Realserver 上,通过 arptables 规则拒绝其响应对 VIP 的 ARP 广播请求
    • 修改内核参数:在 Realserver 上修改内核参数,并结合地址的配置方式实现拒绝响应对 VIP 的 ARP 广播请求
  • 各RIP 必须与 DIP 在同一个物理网络中
  • RS 的 RIP 可以使用私有地址,也可以使用公网地址,以方便配置
  • Director 仅负责处理入站请求,响应报文由 Realserver 直接发往客户端
  • Realserver 不能将网关指向 DIP,而直接使用前端网关
  • 不支持端口映射

LVS-TUN

 

和 DR 模型类似,Realserver 都配有不可见的 VIP,Realserver 的 RIP 是公网地址,且可能和 DIP 不再同一网络中。当请求到达 Director 后,Director 不修改请求报文的源 IP 和目标 IP 地址,而是使用 IP 隧道技术,使用 DIP 作为源 IP,RIP 作为目标 IP 再次封装此请求报文,转发至 RIP 的 Realserver 上,Realserver 解析报文后仍然使用 VIP 作为源地址响应客户端。

LVS-TUN 的特性: – 集群节点和可以跨越 Internet – RIP,DIP,VIP 都是公网地址 – Director 仅负责处理入站请求,响应报文由 Realserver 直接发往客户端 – Realserver 使用自己的网关而不是 Director – Realserver 只能使用支持隧道功能的操作系统 – 不支持端口映射

LVS-FULLNAT

FULLNAT 由淘宝研发,目前还没有加入至 CentOS 可用的内核中,使用时需要向内核打补丁。

类似于 DNAT,它修改请求报文的源地址为 DIP,目标地址为 RIP 来实现转发。对于响应报文,源地址修改为 VIP,目标地址修改为 CIP 来实现转发。

特点:

  • RIP,DIP 可以使用私有地址
  • RIP 和 DIP 可以不再同一网络中,且 RIP 的网关不需要指向 DIP
  • 支持端口映射
  • 请求和响应报文都经由 Director

LVS 的调度算法

当 LVS 接受到一个客户端对集群服务的请求后,它需要进行决策将请求调度至某一台后端主机进行响应。LVS 的调度算法共有 10 种,按类别可以分为动态和静态两种类型。

静态调度算法

静态调度算法调度时不会考虑后端服务器的状态

rr:round robin,轮询,即简单在各主机间轮流调度

wrr:weighted round robin,加权轮询,根据各主机的权重进行轮询

sh:source hash,源地址哈希,对客户端地址进行哈希计算,保存在 Director 的哈希表中,在一段时间内,同一个客户端 IP 地址的请求会被调度至相同的 Realserver。sh 算法的目的是实现 session affinity(会话绑定),但是它也在一定程度上损害了负载均衡的效果。如果集群本身有 session sharing 机制或者没有 session 信息,那么不需要使用 sh 算法

dh:destination hash,和 sh 类似,dh 将请求的目标地址进行哈希,将相同 IP 的请求发送至同一主机,dh 机制的目的是,当 Realserver 为透明代理缓存服务器时,提高缓存的命中率。

动态调度算法

动态调度算法在调度时,会根据后端 Realserver 的负载状态来决定调度选择,Realserver 的负载状态通常由活动链接(active),非活动链接(inactive)和权重来计算。

lc:least connted,最少连接,LVS 根据 overhead = active*256 + inactive 计算服务器的负载状态,每次选择 overhead 最小的服务器

wlc:weighted lc,加权最少连接,LVS 根据 overhead = (active*256+inactive)/weight 来计算服务器负载,每次选择 overhead 最小的服务器,它是 LVS 的默认调度算法

sed:shortest expected delay,最短期望延迟,它不对 inactive 状态的连接进行计算,根据overhead = (active+1)*256/weight 计算服务器负载,选择 overhead 最小的服务器进行调度

nq:never queue,当有空闲服务器时,直接调度至空闲服务器,当没有空闲服务器时,使用 SED 算法进行调度

LBLC:locality based least connection,基于本地的最少连接,相当于 dh + wlc,正常请求下使用 dh 算法进行调度,如果服务器超载,则使用 wlc 算法调度至其他服务器

LBLCR:locality based least connection with replication,基于本地的带复制功能的最少连接,与 LBLC 不同的是 LVS 将请求 IP 映射至一个服务池中,使用 dh 算法调度请求至对应的服务池中,使用 lc 算法选择服务池中的节点,当服务池中的所有节点超载,使用 lc 算法从所有后端 Realserver 中选择一个添加至服务吃中。

ipvsadm

ipvsadm 用于配置 LVS 的调度规则,管理集群服务和 Realserver

管理集群服务

添加:-A -t|u|f service-address [-s scheduler]
     -t: TCP协议的集群 
     -u: UDP协议的集群
        service-address:     IP:PORT
     -f: FWM: 防火墙标记 
        service-address: Mark Number
修改:-E
删除:-D -t|u|f service-address

例如:
# ipvsadm -A -t 10.10.0.1:80 -s rr

管理集群服务中的 RS

添加:-a -t|u|f service-address -r server-address [-g|i|m] [-w weight]
    -t|u|f service-address:事先定义好的某集群服务
    -r server-address: 某RS的地址,在NAT模型中,可使用IP:PORT实现端口映射;
    [-g|i|m]: LVS类型 
        -g: DR
        -i: TUN
        -m: NAT
    [-w weight]: 定义服务器权重
修改:-e
删除:-d -t|u|f service-address -r server-address

例如:
# ipvsadm -a -t 10.10.0.2:80 -r 192.168.10.8 -m 
# ipvsadm -a -t 10.10.0.3:80 -r 192.168.10.9 -m

查看规则

-L|-l
-n:数字格式显式主机地址和端口
--stats:统计数据
--rate: 速率
--timeout: 显示tcp、tcpfin和udp的会话超时时长
-c: 显示当前的ipvs连接状况

删除所有集群服务

-C:清空 ipvs 规则

保存规则

-S
如:
# ipvsadm -S > /path/to/somefile

载入保存的规则

-R
如:
# ipvsadm -R < /path/from/somefile

DR 模型的配置

DR 模型的 Realserver 禁止 ARP 响应

对于 Linux 来说,地址是属于主机的,Linux 主机在开机时会通告连接所有网络内的所有其他主机自己的所有 ip 地址和 mac 地址。

可以利用 Linux 的特性,将VIP配置在 Realserver 的本地回环接口上作为别名,并使用 arp_ignorearp_annouce内核参数。

禁止 ARP 响应的方式

arptables:红帽系类系统上提供的程序

修改内核参数:

  • arp_ignore:定义接收到 ARP 请i去时的响应级别
    • 0:只要本地配置有响应地址,就给与响应
    • 1:仅在请求的目标地址配置请i去到达的接口上的时候,才进行响应
  • arp_announce:定义主机将自己的地址想外通告时的通告级别
    • 0:将本地任何接口上的任何地址向外通告
    • 1:向目标网络通告与其网络匹配的地址
    • 2:仅向本地接口上匹配的网络进行通告

添加特殊的路由条目 Linux 主机在使用某一接口发出报文时,默认会使用此接口的 IP 作为源 IP 地址。

当请求 Realserver 时,Realserver 的 VIP 是 lo 接口的别名,而 VIP 对外的通信实际需要使用的却是 eth0 接口,因此需要添加路由条目,让主机在使用 VIP 向外通信时,强制使用 lo 端口,因而它会使用 lo 端口的地址作为源 IP 进行响应,并最终由 lo 接口转发至 eth0 接口发出报文。

实验以web服务为例

LVS-NAT 模式

三台机器,一台Driector Server,两台Real Server。

ip地址分别是:

driector外网:10.0.2.5
driector内网:192.168.1.6
real1:192.168.1.12
real2:192.168.1.15

driector内网IP和real的IP地址必须要一个网段,driector必须是Linux系统,real后面可以是Windows系统

首先配置Driector Server

yum -y install ipvsadm

清空iptables规则

iptables -F

关闭SELinux

setenforce 0

开启路由转发功能

echo 1 > /proc/sys/net/ipv4/ip_forward
ipvsadm -A -t 10.0.2.5:80 -s rr
ipvsadm -A -t 10.0.2.5:80 -r 192.168.1.12:80 -m
ipvsadm -A -t 10.0.2.5:80 -r 192.168.1.15:80 -m

关闭icmp的重定向

echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/default/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/eth1/send_redirects

// 关闭icmp的重定向

两台real分别设置网关为driector的内网IP地址

先删除默认的

route del default

添加新的

route add default gw 192.168.1.6

两台real新建不同的index.html文件便于区分

real1:192.168.1.12

echo "192.168.1.12" > /var/www/html/index.html

real2:192.168.1.15

echo "192.168.1.15" > /var/www/html/index.html

两台real分别关闭SELinux

setenforce 0

分别添加iptables规则放行

iptables -I INPUT -p tcp --dport 80 -j ACCEPT

现在可以找个客户机测试了

浏览器中输入:

http://10.0.2.5

内容不断的发生变化就代表成功了

LVS-DR 模式

三台机器,一个Driector Server,两个Real Server。

ip地址分别是:

driector外网:192.168.1.100
driector内网:192.168.1.6
real1:192.168.1.12
real2:192.168.1.15

现在只需要写两个脚本再执行就可以了

Director上:

vim ~/lvs-dr.sh

#! /bin/bash

echo 1 > /proc/sys/net/ipv4/ip_forward   // 开启路由转发
ipv=/sbin/ipvsadm
vip=192.168.1.100
rs1=192.168.1.12
rs2=192.168.1.15
ifconfig eth0:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip dev eth0:0
$ipv -C
$ipv -A -t $vip:80 -s rr 
$ipv -a -t $vip:80 -r $rs1:80 -g -w 1
$ipv -a -t $vip:80 -r $rs2:80 -g -w 1

保存之后执行

sh ~/lvs-dr.sh

两台real上:

vim ~/lvs_dr_rs.sh

#! /bin/bash

vip=192.168.1.100
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up 
route add -host $vip lo:0
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce

保存之后执行

找一个台客户机用浏览器多访问几次

http://192.168.1.100

如果内容不断的发生变化就可以了

LVS-TUN 模式

driector外网:192.168.1.100
driector内网:192.168.1.6
real1:192.168.1.12
real2:192.168.1.15

现在只需要写两个脚本再执行就可以了

Director上:

vim ~/lvs-tun.sh

#!/bin/bash  

vip=192.168.1.100 
RS1=192.168.1.12  
RS2=192.168.1.15  
ifconfig tunl0 $vip broadcast $vip netmask 255.255.255.255  
route add -host $vip dev tunl0  
echo "0" >/proc/sys/net/ipv4/ip_forward  
echo "1" >/proc/sys/net/ipv4/conf/all/send_redirects  
echo "1" >/proc/sys/net/ipv4/conf/default/send_redirects  
echo "1" >/proc/sys/net/ipv4/conf/eth0/send_redirects  
ipvsadm -C  
ipvsadm -A -t $vip:80 -s wlc  
ipvsadm -a -t $vip:80 -r $RS1 -i  
ipvsadm -a -t $vip:80 -r $RS2 -i

保存之后执行

sh ~/lvs-tun.sh

两台real上:

vim ~/lvs_tun_rs.sh

#!/bin/bash  

vip=192.168.1.100
ifconfig tunl0 $vip broadcast $vip netmask 255.255.255.255 up  
echo '0' > /proc/sys/net/ipv4/ip_forward  
echo '1' > /proc/sys/net/ipv4/conf/tunl0/arp_ignore  
echo '2' > /proc/sys/net/ipv4/conf/tunl0/arp_announce  
echo '1' > /proc/sys/net/ipv4/conf/all/arp_ignore  
echo '2' > /proc/sys/net/ipv4/conf/all/arp_announce  
echo '0' > /proc/sys/net/ipv4/conf/tunl0/rp_filter  
echo '0' > /proc/sys/net/ipv4/conf/all/rp_filter

保存之后执行

找一个台客户机用浏览器多访问几次

http://192.168.1.100

如果内容不断的发生变化就可以了

4. LVS/DR + keepalived配置

Keepalived 和 LVS 有一些冲突,因为keepalived的配置文件可以设置ipvsadm规则以及虚拟IP(VIP)所以这里先删除掉以前设置过的ipvsadm规则以及虚拟IP

ipvsadm -C
ifconfig tunl0 down && ifconfig eth0:0 down

前面的lvs虽然已经配置成功也实现了负载均衡,但是我们测试的时候发现,当某台real server把httpd进程停掉,那么director照样会把请求转发过去,这样就造成了某些请求不正常。所以需要有一种机制用来检测real server的状态,这就是keepalived。它的作用除了可以检测rs状态外,还可以检测备用director的状态,也就是说keepalived可以实现ha集群的功能,当然了也需要一台备用director,备用director也需要安装一下keepalived软件。

现在起码需要四台机器

IP如下:

主driector外网:192.168.1.100
主driector内网:192.168.1.6
从driector:192.168.1.8
real1:192.168.1.12
real2:192.168.1.15

主从上安装 keepalived

yum install -y keepalived

从上安装 ipvsadm

yum install  -y ipvsadm

安装好后,编辑配置文件,清空自带的内容。

vim /etc/keepalived/keepalived.conf //加入如下:

vrrp_instance VI_1 {
    state MASTER                  #备用服务器上为 BACKUP
    interface eth0
    virtual_router_id 51
    priority 100                  #备用服务器上为90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.100
    }
}
virtual_server 192.168.1.100 80 {
    delay_loop 6                  # 每隔10秒查询realserver状态)
    lb_algo wlc                   #(lvs 算法)
    lb_kind DR                    #(Direct Route)
    persistence_timeout 60        #(同一IP的连接60秒内被分配到同一台realserver)
    protocol TCP                  #(用TCP协议检查realserver状态)

    real_server 192.168.1.12 80 {
        weight 100                #(权重)
        TCP_CHECK {
        connect_timeout 10        #(10秒无响应超时)
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
    }
real_server 192.168.1.15 80 {
        weight 100
        TCP_CHECK {
        connect_timeout 10
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80
        }
     }
}

以上为主Director的keepalived的配置文件,从Director的配置文件只需要改两个地方

修改

state MASTER

state BACKUP

修改

priority 100

priority 90   // 比主小就行

配置完keepalived后,需要在主从上开启端口转发:

echo 1 > /proc/sys/net/ipv4/ip_forward

然后,两个real server 上执行 lvs_dr-rs.sh 脚本

最后,两个director上启动keepalived服务(先主后从)

/etc/init.d/keepalived start

另外,需要注意的是,启动keepalived服务会自动生成vip和ipvsadm规则,所以主director和从director上就不需要执行lvs-dr.sh脚本了

参考 & 扩展阅读:

1、http://liaoph.com/lvs/
2、http://outofmemory.cn/wiki/keepalived-configuration
3、http://wangyu.iteye.com/blog/424057
4、http://www.cnblogs.com/hdflzh/p/4057098.html
5、http://www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html

暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇