共计 5566 个字符,预计需要花费 14 分钟才能阅读完成。
Linux 下 LVS 的实现
配置 LVS-NAT
这里以 HTTP 服务为例,前端服务器配置 VIP 向外响应来自客户的请求,后端两台 REALSERVER 运行 WEB 服务,首先在后端的两台 web 上面配置相同的网页,设置网关都指向前端服务器的 DIP
在 director 上面的配置
echo 1 >proc/sys/net/ipv4/ip_forward 打开路由转发
ipvsadm -A -t 192.168.0.1:80 -s rr 定义一个集群服务,这个 VIP 在实际应用中应该是外网地址
ipvsadm -a -t 192.168.0.1:80 -r 192.168.1.2 -m
ipvsadm -a -t 192.168.0.1:80 -r 192.168.1.3 -m 添加两台 REALSERVER
查看 ipvsadm -L -n
ipvsadm -E -t 192.168.0.1:80 -s wlc 设置算法为 wlc
ipvsadm -e -t 192.168.0.1:80 -r 192.168.1.2 -m -w 4 设置权重为 4,即 1.2 服务器的性能是 1.3 服务器的 4 倍
ab -c -n 10000 http://192.168.0.1/index.html 用 ab 命令做测试
watch -n 1 ‘ipvsadm -L -n’ 每秒刷新一次来查看状态变化, 可以看到 1.2 服务器的响应数基本上为 1.3 服务器的 4 倍
##########################################################################
配置 LVS-DR
在如上图的 VS/DR 或 VS/TUN 应用的一种模型中(所有机器都在同一个物理网络),所有机器(包括 Director 和 RealServer)都使用了一个额外的 IP 地址,即 VIP。
当一个客户端向 VIP 发出一个连接请求时,此请求必须要连接至 Director 的 VIP,而不能是 RealServer 的。因为,LVS 的主要目标就是要 Director 负责调度这些连接请求至 RealServer 的。因此,在 Client 发出至 VIP 的连接请求后,只能由 Director 将其 MAC 地址响应给客户端(也可能是直接与 Director 连接的路由设备),而 Director 则会相应的更新其 ipvsadm table 以追踪此连接,而后将其转发至后端的 RealServer 之一。
如果 Client 在请求建立至 VIP 的连接时由某 RealServer 响应了其请求,则 Client 会在其 MAC table 中建立起一个 VIP 至 RealServer 的对就关系,并以至进行后面的通信。此时,在 Client 看来只有一个 RealServer 而无法意识到其它服务器的存在。
为了解决此问题,可以通过在路由器上设置其转发规则来实现 (静态的 MAC-IP 绑定)。当然,如果没有权限访问路由器并做出相应的设置,则只能通过传统的本地方式来解决此问题了。
这些方法包括:
1、禁止 RealServer 响应对 VIP 的 ARP 请求;
2、在 RealServer 上隐藏 VIP,以使得它们无法获知网络上的 ARP 请求;
3、基于“透明代理(Transparent Proxy)”或者“fwmark(firewall mark)”;
4、禁止 ARP 请求发往 RealServers;
传统认为,解决 ARP 问题可以基于网络接口,也可以基于主机来实现。Linux 采用了基于主机的方式,因为其可以在大多场景中工作良好,但 LVS 却并不属于这些场景之一,因此,过去实现此功能相当麻烦。现在可以通过设置 arp_ignore,arp_announce,这变得相对简单的多了。
Linux 2.2 和 2.4(2.4.26 之前的版本)的内核解决“ARP 问题”的方法各不相同,且比较麻烦。幸运的是,2.4.26 和 2.6 的内核中引入了两个新的调整 ARP 栈的标志
(device flags):arp_announce 和 arp_ignore。基于此,在 DR/TUN 的环境中,所有 IPVS 相关的设定均可使用 arp_announce= 2 和 arp_ignore=1/2/ 3 来解决“ARP 问题”了。以下是官方说明:
arp_annouce:Define different restriction levels for announcing the local source IP address from IP packets in ARP requests sent on interface;
0 – (default) Use any local address, configured on any interface.
1 – Try to avoid local addresses that are not in the target’s subnet for this interface.
2 – Always use the best local address for this target.
arp_ignore: Define different modes for sending replies in response to received ARP requests that resolve local target IP address.
0 – (default): reply for any local target IP address, configured on any interface.
1 – reply only if the target IP address is local address configured on the incoming interface.
2 – reply only if the target IP address is local address configured on the incoming interface and both with the sender’s IP address are part from same subnet on this interface.
3 – do not reply for local address configured with scope host,only resolutions for golbal and link addresses are replied.
4-7 – reserved
8 – do not reply for all local addresses
arp_announce:定义了网卡在向外宣告自己的 MAC-IP 时候的限制级别
有三个值:
0:默认值,不管哪块网卡接收到了 ARP 请求,只要发现本机有这个 MAC 都给与响应
1:尽量避免响应 ARP 请求中 MAC 不是本网卡的,一个主机有多块网卡,其中一块网卡接收到了 ARP 请求,发现所请求的 MAC 是本机另一块网卡的,这个时候接收到 ARP 请求的这块网卡就尽量避免响应
2:总是使用最合适的网卡来响应,一个主机有多块网卡,其中一块网卡接收到了 ARP 请求,发现所请求的 MAC 是本机另一块网卡的,这个时候接收到 ARP 请求的这块网卡就一定不响应,只有发现请求的 MAC 是自己的才给与响应
arp_ignore: 定义了网卡在响应外部 ARP 请求时候的响应级别
这里有 8 个值,但我们只使用了 2 个
0:默认值,不管哪块网卡接收到了 ARP 请求,只要发现本机有这个 MAC 都给与响应
1:总是使用最合适的网卡来响应,一个主机有多块网卡,其中一块网卡接收到了 ARP 请求,发现所请求的 MAC 是本机另一块网卡的,这个时候接收到 ARP 请求的这块网卡就一定不响应,只有发现请求的 MAC 是自己的才给与响应
在 RealServers 上,VIP 配置在本地回环接口 lo 上。如果回应给 Client 的数据包路由到了 eth0 接口上,则 arp 通告或请应该通过 eth0 实现,因此,需要在 sysctl.conf 文件中定义如下配置:
vim /etc/sysctl.conf
net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.eth0.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
以上选项需要在启用 VIP 之前进行,否则,则需要在 Drector 上清空 arp 表才能正常使用 LVS。
到达 Director 的数据包首先会经过 PREROUTING,而后经过路由发现其目标地址为本地某接口的地址,因此,接着就会将数据包发往 INPUT(LOCAL_IN HOOK)。此时,正在运
行内核中的 ipvs(始终监控着 LOCAL_IN HOOK)进程会发现此数据包请求的是一个集群服务,因为其目标地址是 VIP。于是,此数据包的本来到达本机 (Director) 目标行程被改变为经由 POSTROUTING HOOK 发往 RealServer。这种改变数据包正常行程的过程是根据 IPVS 表 (由管理员通过 ipvsadm 定义) 来实现的。
如果有多台 Realserver,在某些应用场景中,Director 还需要基于“连接追踪”实现将由同一个客户机的请求始终发往其第一次被分配至的 Realserver,以保证其请求的完整性等。其连接追踪的功能由 Hash table 实现。Hash table 的大小等属性可通过下面的命令查看:
# ipvsadm -lcn
为了保证其时效性,Hash table 中“连接追踪”信息被定义了“生存时间”。LVS 为记录“连接超时”定义了三个计时器:
1、空闲 TCP 会话;
2、客户端正常断开连接后的 TCP 会话;
3、无连接的 UDP 数据包(记录其两次发送数据包的时间间隔);
上面三个计时器的默认值可以由类似下面的命令修改,其后面的值依次对应于上述的三个计时器:
# ipvsadm –set 28800 30 600
数据包在由 Direcotr 发往 Realserver 时,只有目标 MAC 地址发生了改变(变成了 Realserver 的 MAC 地址)。Realserver 在接收到数据包后会根据本地路由表将数据包路由至本地回环设备,接着,监听于本地回环设备 VIP 上的服务则对进来的数据库进行相应的处理,而后将处理结果回应至 RIP,但数据包的原地址依然是 VIP。
配置拓扑如下图: