最近项目服务端有个服务要配置LVS,因为时间久了,隐约记得原理是改了数据包的目标地址,于是重读了之前看过的《构建高性能的web站点》的第12章的12.5小节,IP负载均衡,记录如下:
在数据链路层(第二层),网络层(第三层)以及传输层(四层)都可以实现不同机制的负载均衡,这些负载均衡必须由linux内核完成,我们希望网络数据包在内核缓冲区进入进程用户地址空间之前,尽早的被转发到其他实际服务器上。
基于NAT技术的负载均衡,工作在传输层,对数据包的IP地址和端口信息进行修改,所以也称四层负载均衡:DNAT:修改的是数据包的目标地址和端口;NAT服务器拥有两块网卡,分别连接外部网络和内部网络。
使用iptables实现转发:
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 8001 -j DNAT –to-destination 10.0.1.210:8000
这条将调度器外网网卡上的8001端口接收的所有请求转发给10.0.1.210这台服务器的8000端口
转发规则已经存在,但是我们必须将实际服务器的默认网关设置为NAT服务器,也就是说,NAT服务器必须为实际服务器的网关,否则,数据包被转发后会一去不复返。
添加默认网关:route add default gw 10.0.1.50
,查看路由表,刚才的默认网关已出现:$ route
LVS-NAT (net address transform):
ipvs = IP Virtual Server = LVS
要想知道内核中是否已经安装IPVS模块,可以查看:modprob -l | grep ipvs
ipvs也需要管理工具:ipvsadm
设置步骤:
- 打开调度器的数据包转发选项:
echo 1 > /proc/sys/net/ipv4/ip_forward
- 检查实际服务器是否已经将NAT服务器作为自己的默认网关
route add default gw 10.0.1.50
- 配置IPVS:
ipvsadm -A -t 125.12.12.12:80 -s rr
ipvsadm -a -t 125.12.12.12:80 -r 10.0.1.210:8000 -m
ipvsadm -a -t 125.12.12.12:80 -r 10.0.1.211:8000 -m
第一行规则添加一台虚拟服务器,也就是负载均衡调度器,这里的-s rr是指采用简单轮询的RR调度策略。后面两行用来为调度器添加实际服务器,其中-m表示采用NAT方式来转发数据包。
除了RR,LVS还提供了一系列的动态调度策略,比如最小连接(LC),带权重的最小连接(WLC),最短期望时间延迟(SED)等。
LVS-DR (direct route):
直接路由方式下的负载均衡调度工作在数据链路层(第二层),简单地说,它通过修改数据包的目标 MAC地址,将数据包转发到实际服务器上,并且,最重要的是,实际服务器的响应数据包将直接发送给客户端,而不经过调度器。(实际服务器要配置ip别名)
一个网络接口最多可以设置256个ip别名,可以把一个C类网段的所有IP地址都设置到一个网卡上。ipconfig eth0:0 125.12.12.77
使用以上命令就设置了一个ip别名。
工作过程
调度器通过修改数据包的目标MAC地址,将它转发给实际服务器,注意它并没有修改目标IP地址,那么一旦数据包到了实际服务器后,发现实际服务器的IP地址并不是数据包的目标IP地址。所以我们要做的就是给实际服务器添加和调度器IP地址相同的IP别名。
步骤
1,给调度器和实际服务器配置相同的IP别名。我们将IP别名添加到回环接口lo上,并且设置路由规则,让实际服务器不要去寻找其他拥有这个IP别名的服务器
ifconfig lo:0 125.12.12.77 broadcast 125.12.12.77 netmask 255.255.255.255 up
route add -host 125.12.12.77 dev lo:0
2,防止实际服务器响应来自网络针对ip别名的ARP广播,执行操作:
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
3,使用ipvsadm配置LVS-DR集群
ipvsadm -A -t 125.12.12.77:80 -s rr
ipvsadm -a -t 125.12.12.77:80 -r 125.12.12.20:80 -g
ipvsadm -a -t 125.12.12.77:80 -r 125.12.12.21:80 -g
这里使用了-g选项,告诉调度器使用直接路由的方式转发数据包。
需要注意的是,在使用DR进行转发的情况下,无法修改数据包的目的端口,原因是这种转发机制工作在数据链路层,所以对于上层的信息端口无能为力。
相比于LVS-NAT,LVS-DR的优势在于,实际服务器的响应数据包可以不经过调度器而直接发往客户端。
LVS-TUN (tunnel):
IP 隧道:
基于IP隧道的负载均衡系统同样可以用LVS来实现,也成为LVS-TUN,与LVS-DR不同的是,实际服务器可以和调度器不在同一个WAN网段,调度器通过IP隧道技术来实现转发请求到实际服务器,所以实际服务器也必须拥有合法的IP地址。
基于IP隧道的转发机制,简单来说,它是将调度器收到的IP数据包封装在一个新的IP数据包中,转交给实际服务器,然后实际服务器的响应数据包可以直接到达用户端。
调度器单点:
对于调度器,转移请求的机制注定它存在单点故障,我们必须实现故障平滑转移。心跳包可以很好的解决这个问题,我们可以准备一台备用调度器,通过运行heartbeat对主调度器进行心跳检测,一旦发现主调度器停止心跳,便立即启动故障转移,接管主调度器,这个接管过程包括IP别名变更,相关服务的启动等。