LVS负载均衡

2019-12-09

LVS负载均衡

Netfilter 基本原理

LVS 是基于 Linux 内核中 netfilter 框架实现的负载均衡系统,所以要学习 LVS 之前必须要先简单了解netfilter 基本工作原理。netfilter 其实很复杂也很重要,平时我们说的 Linux 防火墙就是netfilter,不过我们平时操作的都是 iptables,iptables 只是用户空间编写和传递规则的工具而已,真正工作的是 netfilter。通过下图可以简单了解下 netfilter 的工作机制:
image.png

netfilter 是内核态的 Linux 防火墙机制,作为一个通用、抽象的框架,提供了一整套的 hook 函数管理机制,提供诸如数据包过滤、网络地址转换、基于协议类型的连接跟踪的功能。

通俗点讲,就是 netfilter 提供一种机制,可以在数据包流经过程中,根据规则设置若干个关卡(hook 函数)来执行相关的操作。netfilter 总共设置了 5 个点,包括:PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING
* PREROUTING:刚刚进入网络层,还未进行路由查找的包,通过此处
* INPUT:通过路由查找,确定发往本机的包,通过此处
* FORWARD:经路由查找后,要转发的包,在POST_ROUTING之前
* OUTPUT:从本机进程刚发出的包,通过此处
* POSTROUTING:进入网络层已经经过路由查找,确定转发,将要离开本设备的包,通过此处

当一个数据包进入网卡,经过链路层之后进入网络层就会到达 PREROUTING,接着根据目标 IP 地址进行路由查找,如果目标 IP 是本机,数据包继续传递到 INPUT 上,经过协议栈后根据端口将数据送到相应的应用程序;应用程序处理请求后将响应数据包发送到 OUTPUT 上,最终通过 POSTROUTING 后发送出网卡。如果目标 IP 不是本机,而且服务器开启了 forward 参数,就会将数据包递送给 FORWARD 上,最后通过 POSTROUTING 后发送出网卡。

LVS基本原理

LVS 是基于 netfilter 框架,主要工作于 INPUT 链上,在 INPUT 上注册 ip_vs_in HOOK 函数,进行 IPVS 主流程,大概原理如图所示:
image.png

  • 当用户访问 www.sina.com.cn 时,用户数据通过层层网络,最后通过交换机进入 LVS 服务器网卡,并进入内核网络层。
  • 进入 PREROUTING 后经过路由查找,确定访问的目的 VIP 是本机 IP 地址,所以数据包进入到 INPUT 链上
  • IPVS 是工作在 INPUT 链上,会根据访问的 vip+port 判断请求是否 IPVS 服务,如果是则调用注册的 IPVS HOOK 函数,进行 IPVS 相关主流程,强行修改数据包的相关数据,并将数据包发往 POSTROUTING 链上。
  • POSTROUTING 上收到数据包后,根据目标 IP 地址(后端服务器),通过路由选路,将数据包最终发往后端的服务器上。

Lvs 三种实现教程

lvs 使用过ipvsadm来管理操作的,不管哪种方式我们都需要安装此数据包

yum -y install ipvsadm-1.27-7.el7.x86_64

ipvsadm 命令选项解释

-A --add-service                         在内核的虚拟服务器表中添加一条新的虚拟服务器记录。也就是增加一台新的虚拟服务器。   
-E --edit-service                        编辑内核虚拟服务器表中的一条虚拟服务器记录。   
-D --delete-service                      删除内核虚拟服务器表中的一条虚拟服务器记录。   
-C --clear                               清除内核虚拟服务器表中的所有记录。   
-R --restore                             恢复虚拟服务器规则   
-S --save                                保存虚拟服务器规则,输出为-R 选项可读的格式   
-a --add-server                          在内核虚拟服务器表的一条记录里添加一条新的真实服务器记录。也就是在一个虚拟服务器中增加一台新的真实服务器   
-e --edit-server                         编辑一条虚拟服务器记录中的某条真实服务器记录   
-d --delete-server                       删除一条虚拟服务器记录中的某条真实服务器记录   
-L|-l --list                             显示内核虚拟服务器表   
-Z --zero                                虚拟服务表计数器清零(清空当前的连接数量等)   
--set tcp tcpfin udp                     设置连接超时值   
--start-daemon                           启动同步守护进程。他后面可以是master 或backup,用来说明LVS Router 是master 或是backup。在这个功能上也可以采用keepalived的VRRP 功能。   
--stop-daemon                            停止同步守护进程   
-h --help                                显示帮助信息   
其他的选项:   
-t --tcp-service service-address         说明虚拟服务器提供的是tcp 的服务[vip:port] or [real-server-ip:port]   
-u --udp-service service-address         说明虚拟服务器提供的是udp 的服务[vip:port] or [real-server-ip:port]   
-f --fwmark-service fwmark               说明是经过iptables 标记过的服务类型。   
-s --scheduler scheduler                 使用的调度算法,有这样几个选项rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,   默认的调度算法是: wlc.   
-p --persistent [timeout]                持久稳固的服务。这个选项的意思是来自同一个客户的多次请求,将被同一台真实的服务器处理。timeout 的默认值为300 秒。   
-M --netmask                             netmask persistent granularity mask   
-r --real-server server-address          真实的服务器[Real-Server:port]   
-g --gatewaying                          指定LVS 的工作模式为直接路由模式(也是LVS 默认的模式)   
-i --ipip                                指定LVS 的工作模式为隧道模式   
-m --masquerading                        指定LVS 的工作模式为NAT 模式   
-w --weight weight                       真实服务器的权值   
--mcast-interface interface              指定组播的同步接口   
-c --connection                          显示LVS 目前的连接 如:ipvsadm -L -c   
--timeout                                显示tcp tcpfin udp 的timeout 值 如:ipvsadm -L --timeout   
--daemon                                 显示同步守护进程状态   
--stats                                  显示统计信息   
--rate                                   显示速率信息   
--sort                                   对虚拟服务器和真实服务器排序输出   
--numeric -n                             输出IP 地址和端口的数字形式

DR模式

类型 IP地址 作用 
虚拟IP-> VIP 172.16.1.254 虚拟ip地址,提供统一入口,实际环境中应该设置为公网地址
负载调度器 192.168.1.254 负载调度器的真实IP地址,实际中应该给后端服务器处于同一个局域网(交换机下)
后端服务1 192.168.1.101 真实提供服务,端口80
后端服务2 192.168.1.102 真实提供服务,端口80
客户ip 172.16.1.200 客户端ip地址

在调度服务器上

//关闭防火墙,关闭selinux

//配置虚拟IP
ifconfig eth0:0 172.16.1.254 netmask 255.255.255.255

// 安装ipvsadm
yum -y install ipvsadm
ipvsadm --save > /etc/sysconfig/ipvsadm
systemctl start ipvsadm
lsmod | grep ip_vs

//配置ipvsadm
ipvsadm -C #清除内核虚拟服务器表中的所有记录。
ipvsadm --set 30 5 60 #设置连接超时值,TCP为30s UDP为60s

//ipvsadm -A -t [VIP]:80 -s wrr -p 20
ipvsadm -A -t  172.16.1.254:80 -s rr -p 5
ipvsadm -a -t 172.16.1.254:80 -r 192.168.1.101:80 -g -w 3
ipvsadm -a -t 172.16.1.254:80 -r 192.168.1.102:80 -g -w 3
//上一步不能同一个ip的不同端口,会报错: No such device or address(lvs不能重新映射端口)

查看请求转发情况:ipvsadm -lnc | grep [VIP]
查看日志:tail -f /var/log/messages
保存规则到文件:ipvsadm --save 或 service ipvsadm save

在后端服务器上

ifconfig lo:0 172.16.1.254 broadcast 172.16.1.254 netmask 255.255.255.255  up

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

sysctl -p

问题解答

1,为什么需要在 lo 接口配置 vip ?

我们知道如果服务器收到的数据包 IP 地址不是本机地址(没开启转发模式),就会丢弃。后端服务器收到 DR 模式的数据包,此时目标 IP 是 VIP,服务器会认为此数据包不是发送给本机的,会丢弃。而我们在 lo 接口上配置 VIP 后,服务器就能够正常接收此数据包,发送给相应的应用程序了。因此,在 lo 上配置 vip 能够完成接收数据包并将结果返回给 client。

2,为什么需要配置 arp_ignore 参数?

我们在 lo 上配置了 vip,正常情况下,其它设备发送 vip 的 arp 请求时,除了负载均衡设备会响应 arp 请求之外,后端服务器也会响应 vip 的 arp 请求,这样请求设备不知道哪个是准确的了,反正就是乱了。我们在参数中配置 arp_ignore=1 之后,后端服务器只会响应目的 IP 地址为接收网卡上的本地地址的 arp 请求。由于 vip 配置了在 lo 上,所以其它接口收到相关的 arp 请求都会忽略掉,这样保证了 arp 请求正确性。这也说明了为什么 vip 必须配置在 lo 接口上而不是其它接口上了。

3,为什么需要配置 arp_announce 参数?

当后端服务器向客户端发送响应数据包时,源地址和目的地址确定,通过目标地址查找路由后,发送网卡也是确认的,也就是源 MAC 地址是确认的,目的 MAC 地址还不确定,需要获取下一跳 IP 对应的 MAC 地址,就需要发送 arp 请求了。发送的 arp 请求目的 IP 就是下一跳的地址,而源 IP 是什么呢?系统通常默认会取数据包的源 IP 作为 arp 的源 IP。我们认真想一下,源 IP 不就是 VIP 么,假设以 VIP 为源 IP 发送 arp 请求,那下一跳(路由器)学习到的 MAC 地址和 IP 地址对应关系就会错乱,因为负载均衡设备上的 VIP 对应的 MAC 地址肯定与这个不同,导致整个系统 arp 紊乱。

而我们配置参数 arp_announce=2 后,操作系统在发送 arp 请求选择源 IP 时,就会忽略数据包的源地址,选择发送网卡上最合适的本地地址作为 arp 请求的源地址。

NAT 模式操作实践

类型 IP地址 作用 
虚拟IP-> VIP 172.16.1.254 虚拟ip地址,提供统一入口,实际环境中应该设置为公网地址
负载调度器 192.168.1.254 负载调度器的真实IP地址,实际中应该给后端服务器处于同一个局域网(交换机下)
后端服务1 192.168.1.101 真实提供服务,端口80
后端服务2 192.168.1.102 真实提供服务,端口80
客户ip 172.16.1.200 客户端ip地址

负载调度器

ipvsadm -A -t  172.16.1.254:80 -s rr -p 5
ipvsadm -a -t 172.16.1.254:80 -r 192.168.1.101:80 -m
ipvsadm -a -t 172.16.1.254:80 -r 192.168.1.102:80 -m

查看请求转发情况:ipvsadm -lnc | grep [VIP]
查看日志:tail -f /var/log/messages
保存规则到文件:ipvsadm --save 或 service ipvsadm save

后端服务器

route add default gw 192.168.1.254 dev eth0 

TUN模式

类型 IP地址 作用 
虚拟IP-> VIP 172.16.1.254 虚拟ip地址,提供统一入口,实际环境中应该设置为公网地址
负载调度器 192.168.1.254 负载调度器的真实IP地址,实际中应该给后端服务器处于同一个局域网(交换机下)
后端服务1 192.168.1.101 真实提供服务,端口80
后端服务2 192.168.1.102 真实提供服务,端口80
客户ip 172.16.1.200 客户端ip地址

负载调度器配置

ipvsadm -A -t  172.16.1.254:80 -s rr -p 5
ipvsadm -a -t 172.16.1.254:80 -r 192.168.1.101:80 -i
ipvsadm -a -t 172.16.1.254:80 -r 192.168.1.102:80 -i

查看请求转发情况:ipvsadm -lnc | grep [VIP]
查看日志:tail -f /var/log/messages
保存规则到文件:ipvsadm --save 或 service ipvsadm save

后端服务器配置

ifconfig tunl0 172.16.1.254 broadcast 172.16.1.254 netmask 255.255.255.255 up
echo "0" > /proc/sys/net/ipv4/ip_forward
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/all/rp_filter
echo "0" > /proc/sys/net/ipv4/conf/tunl0/rp_filter


标题:LVS负载均衡
作者:shoufuzhang
地址:https://www.zhangshoufu.com/articles/2019/12/09/1575878750064.html
名言:The master has failed more times than the beginner has tried.
评论
发表评论