集群高可用之lvs

集群:

随着互联网的发展,大量的客户端的请求,服务器的负载越来越大,单台服务器的负载有限,会导致服务器响应客户端请求的时间越长,甚至产生拒绝服务的情况。目前网站是24小时不间断提供网络服务,仅采用单点服务器对外提供要求,如果出现单点故障,会导致整个网络的中断。集群环境的核心是负载均衡和高可用。

常见的负载均衡器

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

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

根据软硬件划分:

  • 硬件负载均衡:
    • 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有三种模式:

1)基于NAT的lvs负载均衡

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)

 

2)基于TUN的lvs负载均衡

 

和 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 只能使用支持隧道功能的操作系统
  • 不支持端口映射

3)基于DR的lvs负载均衡

 

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 模型的特性:

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调度算法:

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

轮询调度:

rr      简单在各主机间轮流调度

加权轮询调度:

wrr    根据各主机的权重进行轮询

最小连接调度:

lc     根据 overhead = active*256 + inactive 计算服务器的负载状态,每次选择 overhead 最小的服务器

加权最小连接调度:

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

基于局部性的最少连接:

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

带复制的基于局部性的最少连接:

lblcr 与 LBLC 不同的是 LVS 将请求 IP 映射至一个服务池中,使用 dh 算法调度请求至对应的服务池中,使用 lc 算法选择服务池中的节点,当服务池中的所有节点超载,使用 lc 算法从所有后端 Realserver 中选择一个添加至服务吃中。

目标地址散列调度

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

原地址散列调度

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

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工作模式的负载均衡

LVS负载均衡调度器设置,修改配置文件

ROUTER:
外网接口(eno16)    124.126.147.169
内网接口(eno33)    192.168.0.253

lvs.example.com
eno16(VIP)            124.126.147.168
eno33                    192.168.0.254

web1.example.com
eno16                    192.168.0.1
lo:0(VIP)                124.126.147.168

web2.example.com 
eno16                    192.168.0.2
lo:0(VIP)                124.126.147.168


vim /etc/sysconfig/network-scripts/ifcfg-eno16
DEVICE=eno16
BOOTPROTO=statci
ONBOOT=yes
TYPE=Ethernet
IPADDR=124.126.147.168
DNS1=202.106.0.20
NETMASK=255.255.255.0

vim /etc/sysconfig/network-scripts/ifcfg-eno33
DEVICE=eno33
BOOTPROTO=statci
ONBOOT=yes
TYPE=Ethernet
IPADDR=192.168.0.254
DNS1=202.106.0.20
NETMASK=255.255.255.0

systemctl restart network
安装ipvsadm管理工具,创建虚拟服务,添加真实服务器组,为虚拟服务器设置适当的调度算法
yum -y install ipvsadm
ipvsadm -A -t 124.126.147.168:80 -s wrr
ipvsadm -a -t 124.126.147.168:80 -r 192.168.0.1:80 -g -w 1
ipvsadm -a -t 124.126.147.168:80 -r 192.168.0.2:80 -g -w 2
-A:添加虚拟服务
-t:TCP协议
-r:真实IP(RIP)
-g:DR模式
ipvsadm -Sn > /etc/sysconfig/ipvsadm  保存调度规则
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --reload
                                                                                                                                                             

真实的web服务器设置如下(测试将web页面内容设置不同的内容,真实的生产环境服务器都提供相同的页面内容)

注意:调度器和真实服务器都设置了vip,所以这里要求所有的真实服务器禁止对VIP地址的ARP响应,通过配置arp_ignore和arp_announce来实现

vim /etc/sysconfig/network-scripts/ifcfg-eno16
DEVICE=eno16
BOOTPROTO=statci
ONBOOT=yes
TYPE=Ethernet
IPADDR=192.168.0.1
NETMASK=255.255.255.0
GATEWAY=192.168.0.253

vim /etc/sysconfig/network-scripts/ifcfg-lo:0
DEVICE=lo:0
BOOTPROTO=statci
ONBOOT=yes
TYPE=Ethernet
IPADDR=124.126.147.168
NETMASK=255.255.255.255
GATEWAY=192.168.0.253

vim /etc/sysctl.conf
net.ipv4.conf.eno16.arp_ignore = 1
net.ipv4.conf.eno16.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce =2

sysctl -p
yum -y install httpd
systemctl restart httpd
systemctl restart network
echo "192.168.0.1" > /var/www/html/index.html
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --reload



vim /etc/sysconfig/network-scripts/ifcfg-eno16
DEVICE=eno16
BOOTPROTO=statci
ONBOOT=yes
TYPE=Ethernet
IPADDR=192.168.0.2
NETMASK=255.255.255.0
GATEWAY=192.168.0.253

vim /etc/sysconfig/network-scripts/ifcfg-lo:0
DEVICE=lo:0
BOOTPROTO=statci
ONBOOT=yes
TYPE=Ethernet
IPADDR=124.126.147.168
NETMASK=255.255.255.255
GATEWAY=192.168.0.253

vim /etc/sysctl.conf
net.ipv4.conf.eno16.arp_ignore = 1
net.ipv4.conf.eno16.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce =2

sysctl -p
yum -y install httpd
systemctl restart httpd
systemctl restart network
echo "192.168.0.2" > /var/www/html/index.html
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --reload

 

路由器采用Linux作为软件路由来实现本例:

vim /etc/sysconfig/network-scripts/ifcfg-eno16
DEVICE=eno16
BOOTPROTO=static
ONBOOT=yes
TYPE=Ethernet
IPADDR=192.168.0.253
NETMASK=255.255.255.0

vim /etc/sysconfig/network-scripts/ifcfg-eno33
DEVICE=eno33
BOOTPROTO=static
ONBOOT=yes
TYPE=Ethernet
IPADDR=124.126.147.168
NETMASK=255.255.255.255

vim /etc/sysctl.conf
net.ipv4.ip_forward = 1

sysctl -p
systemctl restart network

客户端使用浏览器访问http://124.126.147.168,最终可以访问到真实服务器所提供的页面内容,由于lvs采用WRR(加权轮询)算法,不同的请求将被分配到不同的后端服务器上,但服务器的优先级是不同的,本例中由于所有的页面都不相同,所以访问后得到不同的页面内容。

 

arp_ignore用来定义网卡在响应外部ARP请求时的响应级别

0:默认值,在任何网络接口收到ARP请求后,如果本机的任意接口有该ip,则予以响应

1:只回答目标IP地址是来访网络接口本地地址的ARP查询请求

2 -只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内

 

 

arp_announce:对网络接口上,本地IP地址的发出的,ARP回应,作出相应级别的限制: 确定不同程度的限制,宣布对来自本地源IP地址发出Arp请求的接口 

0 - (默认) 在任意网络接口(eth0,eth1,lo)上的任何本地地址 

1 -尽量避免不在该网络接口子网段的本地地址做出arp回应. 当发起ARP请求的源IP地址是被设置应该经由路由达到此网络接口的时候很有用.此时会检查来访IP是否为所有接口上的子网段内ip之一.如果改来访IP不属于各个网络接口上的子网段内,那么将采用级别2的方式来进行处理. 

2 - 对查询目标使用最适当的本地地址.在此模式下将忽略这个IP数据包的源地址并尝试选择与能与该地址通信的本地地址.首要是选择所有的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址. 如果没有合适的地址被发现,将选择当前的发送网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送.

 

关于对arp_announce 理解的一点补充:

其实就是路由器的问题,因为路由器一般是动态学习ARP包的(一般动态配置DHCP的话),当内网的机器要发送一个到外部的ip包,那么它就会请求 路由器的Mac地址,发送一个arp请求,这个arp请求里面包括了自己的ip地址和Mac地址,而linux默认是使用ip的源ip地址作为arp里面 的源ip地址,而不是使用发送设备上面的 ,这样在lvs这样的架构下,所有发送包都是同一个VIP地址,那么arp请求就会包括VIP地址和设备 Mac,而路由器收到这个arp请求就会更新自己的arp缓存,这样就会造成ip欺骗了,VIP被抢夺,所以就会有问题。  

arp缓存为什么会更新了,什么时候会更新呢,为了减少arp请求的次数,当主机接收到询问自己的arp请求的时候,就会把源ip和源Mac放入自 己的arp表里面,方便接下来的通讯。如果收到不是询问自己的包(arp是广播的,所有人都收到),就会丢掉,这样不会造成arp表里面无用数据太多导致 有用的记录被删除。  

在设置参数的时候将arp_ignore 设置为1,意味着当别人的arp请求过来的时候,如果接收的设备上面没有这个ip,就不做出响应,默认是0,只要这台机器上面任何一个设备上面有这个ip,就响应arp请求,并发送mac地址
posted @ 2018-05-15 18:36  风中驻足  阅读(503)  评论(0编辑  收藏  举报