前言
在上一篇文章《搭建 DNS+LVS(keepAlived)+OpenResty 服务器(Docker 环境)》中, 我搭建了 dns+lvs+openresty+web 集群; 先来回顾一下架构图:
问题现象
可以看到, 我把 Web 服务器分成了两组, 一组为 web01,web02, 挂在了 openresty01 下, 另外一组: web03,web04,web05 挂在了 openresty02 下; 最后搭建完成, 演示时, 我分别使用了 curl 和浏览器, 在 curl 演示时很正常, 请求能轮流分到每个 Web 容器, 但在浏览器中演示时, 刷新时显示轮流某一组 Web, 而不是在所所有 Web 应用轮流, 我当时以为是浏览器缓存导致, 所以新开了个页签;
我们来看一下:
持久化概念
这两天又深入学习了 lvs 的持久化; 我之前在 keepalived 中配置了持久化时间 (persistence_timeout) 为 0, 再加上负载均衡策略 (lb_algo) 配置成 rr, 就能够轮流 rs, 其实不然, 除了这些之外, 还有连接空闲的超时时间;
1. 把来自同一个客户端 IP 的请求转发到同一个 RS 的持久化时间: persistence_timeout, 通过这个持久化时间, 我们可以实现会话保持
2. 一个连接创建后处于空闲状态的超时时间
- tcp 连接的空闲超时时间
- LVS 收到客户端 FIN 消息的超时时间
- udp 的超时时间
设置超时时间通过 ipvsadm --set tcp tcpfin udp 命令; 查看连接状态使用 ipvsadm -lnc 命令查看
问题分析
经过观察分析, curl 命令请求时, 每次请求都从不同的端口发请求, 所以每次 lvs 都当做一个新的客户端来处理, 而且 curl 请求完后, 就关闭了 tcp 连接; 而浏览器则不然, 每次刷新很可能还是以同一个端口发出请求, 而且 tcp 连接也会保持, 所以 lvs 就会认为是同一个客户端, 每次刷新就会指向同一 rs, 即 openresty,openresty 再将请求轮流分到下一层的 Web 应用;
我们来看一下浏览器刷新的情况:
刷新后看一下 lvs 服务器上连接状态:
可见经过多次刷新(七八次),tcp 连接共有三个, 两个处于连接中状态, 一个处于 FIN_WAIT 状态;
再来看一下 curl 命令执行情况:
再看一下 lvs 服务器上连接状态
可见连接都处于 FIN_WAIT 状态
将 tcp/tcpfin/udp 超时时间都设置为 1s
[root@lvs02 /]# ipvsadm --set 1 1 1
再看来浏览器刷新情况:
可以看见, 请求比较均匀的分到了 Web 应用.
再到 lvs 服务器查看连接状态时, 显示为空, 因为 1s 时间比较短, 很快就超时了;
附
上一篇文章, 我配置的 LVS 模式是 DR, 如果将其改成 NAT, 如何配置?
修改 keepalived 配置文件, lb_kind 配置成 NAT, 再在其下添加一行 nat_mask
255.255.255.0,rs 服务器上不用再绑定 VIP 地址, 抑制 ARP 广播; 需要配置一个默认网关
route add default gateway 192.168.254.100
上一篇文章中, 我提到如果直接在 Mac 本中安装 dokcer, 无法直接从 Mac 中 ping docker 容器的 IP
找到一篇文章解决方法, 使用 openvpn 方式, 我没有实践过, 可作大家参考.
完美解决 MacOS 下不能 ping Docker 容器的问题 https://www.jianshu.com/p/a0933256c829
后来我是在虚拟机中安装的 docker,Mac 中能 ping 通过虚拟机, 虚拟机能 ping 通 docker, 但 Mac 不能 ping 通过 docker, 如何解决?
在 Mac 中添加一条静态路由, 将 docker 容器的 ip 都转到虚拟机 IP
sudo route -n add -net 192.168.254.0/24 192.168.253.129 也可以: sudo route -n add -net 192.168.254.0 -netmask 255.255.255.0 192.168.253.129, 效果一样
参考: https://www.jianshu.com/p/31b4a8266f0c
来源: https://www.cnblogs.com/mycodingworld/p/lvs_persisitence.html