最近在配置lvs,想用lvs做个VIP,这样不用客户端自己做LB
配置整体思路
VIP 机器上配置eth0虚拟ip,
安装lvs
使用
ipvsadm -A -t 192.168.59.106:8080 -s wlc 设置vip 和lb的策略
ipvsadm -a -t ip:port -r realip:port -g 设置真实ip 映射和传递策略
真实机器上配置lo的虚拟ip,
设置允许路由
route add -host ip dev lo:0
真实机器上关闭这个虚拟ip的arp应答
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
原理
客户端请求到vip, 先发送arp请求得到VIP机器的mac地址,然后发送tcp请求,在ethernet上填写的是VIP的mac地址也就是安装lvs的服务器的mac地址
lvs服务器内核在收到包解析到mac地址的时候,修改包里的mac地址到真实服务器的mac地址然后重新请求,修改mac地址后的包,被真实服务器收到,真实服务器上因为也配有这个vip的虚拟ip,所以完成应答,然后直接回给客户端,也不需要改变任何内容。
在客户端抓包能看到,客户端发出的包的mac地址是vip的地址 收到的包的对方的mac地址是真实的服务器地的
在真实服务器端抓包,因为被vip修改了mac地址,真实服务器上能看到的是自己的mac地址和客户端的mac地址
因为VIP是在IP包前修改的,tcpdump无法抓到包
netstat 查看
客户端和真实服务器端查看正常
也是因为VIP是在IP包之前修改而无法查看
性能比起ngix 自然是好
内核不需要对TCP层解析,减少内核调用
在真实服务器回给客户端时候,不需要通过中转,直接回给客户端,减少网络包的数量和开销。
lvs的解决之道,主要是客户端并不对请求mac的地址进行检查。