lvs 负载参考说明
# LVS 术语
# DS: Director Server 提供负载均衡器的节点
# RS: Real Server 后端真实的工作服务器
# VIP 向外部直接作为用户请求的目标IP
# DIP: Director Server IP 用于 DR 在内部和 RS 通讯时使用的IP
# RIP: Real Server IP 后端服务器的IP
# CIP: Client IP 访问客户端的IP
# Client --> DNS --> firewalld --> [Core Router] --> keepalived+lvs ---> Nginx/Haproxy/*LB ---> App
# 生产环境中客户端通过域名解析后获得的目标IP为防火墙的IP,并非LVS的VIP地址 ...
# ------------------------------------------------- DR
# DR、RS 均使用相同VIP,但仅DR对VIP的ARP请求响应,所有RS保持ARP静默(网关把对VIP的请求全交给DR)
# 当DR收到后根据调度算法找出对应RS并且将此VIP的数据包中的MAC改为RS的MAC(因为IP一致)并将请求分发给选中的RS
# RS处理后由于IP一致,因此将数据直接返回给C端,"相当于直接从客户端收到这个数据包无异" (DR模型从始至终修改的仅有MAC地址)
# 因 DR 要对二层包头的MAC修改所以 DR、RS 之间必须在相同的广播域/网段(可理解为在同一个LAN下)
# 特点:
# 与TUN相比其不需要隧道结构因此可使用大多数操作系统做为后端节点,但其要求负载均衡器的网卡必须与物理网卡在相同网段
# RS 与 DR 的网关不能相同,接收VIP的网关应该仅知道DR的MAC ...( RS处理后的响应报文不能经过负载均衡节点: DS )
# 即: 所有请求报文由 DR 处理,但响应报文不能经过 DR 。该模式不支持地址转换,也不支持端口映射 ...
# RS 的 loopback 接口配置VIP地址,RS 和 DS 必须在相同网段
# ------------------------------------------------- NAT
# DR 将请求包的目的IP转为某RS的IP并交给其处理,RS 处理后再将其返回 DR
# DR 收到后再把 RS 返回的数据包的源IP改为 VIP 并返回
# 因此进出流量都经过 DR 所以性能不优(该模式下RS的网关需指向DR,因为数据包内的客户端地址 "CIP" 一直未改变)
# 本质上该模式就是个多目标 IP 的 DNAT ...
# 特点:
# 集群中的服务器可使用任何支持 TCP/IP 的系统,而LVS仅需有1个合法 IP 即可
# 当服务器节点过多时大量数据交汇在 LVS 的 DR 节点,导致速度变慢成为性能瓶颈 ...
# 若DIR和RIP在同一广播域,需要和LVS/DR模式一样在所有的RIP上仰制arp,防止arp响应导致arp表混乱
# 若DIR和RIP在不同LAN,如不同网段,就不需要设置arp仰制,只需设置 ip tunnel 即可
# 一般来说 TUN 模式会用来负载调度缓存服务器组,这些缓存服务器放置在不同网络环境,可就近返回数据给客户端
# 在请求对象不能在Cache服务器本地命中的情况下,Cache服务器要向源服务器发请求,将结果取回,最后将结果返回给客户
# ------------------------------------------------- IP-IP
# DR、RS 均使用相同VIP对外服务 ...
# DR 将C端数据包进行封装,增加新的目的IP后发往RS,RS端进行解封装并处理后直接返回C端(不再经过DR)
# 因RS需对LVS发来的包还原所以必须支持 IPTUNNEL 协议,因此RS的内核必须编译支持 IPTUNNEL
# 特点:
# DR 仅负责将请求分发给后端节点从而减少LVS的大量数据交互,该方式可在公网进行不同地域的分发 ...
# 但各后端节点需合法IP并且需要所有节点支持 "IP Tunneling" 协议
# ------------------------------------------------- FULLNAT(需要编译)
# 相对于NAT模式来说,它同时将源与目的IP进行修改,RS认为C端就是DR,该模式解决的是 DR 和 RS 跨VLAN的问题
# 相当于中间人,其可实现端口映射功能 (即源地址也参与转换)
DR 模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3bjmgwag-1626526813572)(./Image/Image_DR.png)]
# *保持VIP的arp静默
# --> GW_1 --> DR(VIP) --> *RS(VIP)
# /
# < ----- GW_2
# ----------------------------------------- Director Server
yum install -y ipvsadm
VIP=192.168.0.38
ifconfig lo:0 down
ifconfig lo:0 ${VIP} broadcast ${VIP} netmask 255.255.255.255 up
route add -host ${VIP} dev eth0:0
echo 1 > /proc/sys/net/ipv4/ip_forward
# 将VIP绑在lo可避免由于物理网卡失效导致VIP不稳定
# 该模式不支持地址转换,也不支持端口映射 ...
ipvsadm -C
ipvsadm -A -t ${VIP}:80 -s wrr
ipvsadm -a -t ${VIP}:80 -r 192.168.0.18:80 -g -w 1
ipvsadm -a -t ${VIP}:80 -r 192.168.0.28:80 -g -w 1
# 查看规则
ipvsadm -ln
# IP Virtual Server version 1.2.1 (size=4096)
# Prot LocalAddress:Port Scheduler Flags
# -> RemoteAddress:Port Forward Weight ActiveConn InActConn
# TCP 192.168.0.38:80 wrr
# -> 192.168.0.18:80 Route 1 0 0
# -> 192.168.0.28:80 Route 1 0 0
# ----------------------------------------- Real Server
cat > ./lvs_rs.sh <<'EOF'
#!/bin/bash
# ----------------------
# Tips:
# DR 与 RS 不能使用相同的网关,接收 VIP 的网关应该仅知道 DR 的 MAC
# 关闭 RS 中loop口的arp回应,其它口无须关闭
# ----------------------
VIP=192.168.0.38
. /etc/rc.d/init.d/functions
case "$1" in
start)
ifconfig lo:0 ${VIP}/32 broadcast ${VIP} up
route add -host ${VIP} dev lo:0
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
echo "RealServer Started"
;;
stop)
ifconfig lo:0 down ??? ....
route del ${VIP} >/dev/null
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
echo "RealServer Stoped"
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
EOF
chmod u+x lvs_rs.sh && ./lvs_rs.sh start
NAT 模式
# ----------------------------------------- Director Server
yum install -y ipvsadm
echo 1 > /proc/sys/net/ipv4/ip_forward
# 设置 NAT(实验环境的设置,当实际环境为NAT时此步骤跳过)
# iptables -t nat -F
# iptables -t nat -X
# iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE
VIP=192.168.0.38
ipvsadm -C
ipvsadm -A -t ${VIP}:80 -s wrr
ipvsadm -a -t ${VIP}:80 -r 192.168.0.18:80 -m -w 1
ipvsadm -a -t ${VIP}:80 -r 192.168.0.28:80 -m -w 1
# 查看规则
ipvsadm -ln
# IP Virtual Server version 1.2.1 (size=4096)
# Prot LocalAddress:Port Scheduler Flags
# -> RemoteAddress:Port Forward Weight ActiveConn InActConn
# TCP 192.168.0.38:80 wrr
# -> 192.168.0.18:80 Masq 1 0 0
# -> 192.168.0.28:80 Masq 1 0 0
# ----------------------------------------- Real Server
# 在后端的若干 RS 中设置其网关IP为 Director 的内网IP即可
TUN 模式
# ----------------------------------------- Director Server
VIP=192.168.0.38
echo 1 > /proc/sys/net/ipv4/ip_forward
modprobe tun
modprobe ipip
ifconfig eth0:0 ${VIP} netmask 255.255.255.255 broadcast ${VIP} up
route add -host ${VIP} dev eth0:0
echo "0" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/conf/all/send_redirects
echo "1" > /proc/sys/net/ipv4/conf/default/send_redirects
echo "1" > /proc/sys/net/ipv4/conf/eth0/send_redirects # 注意修改网卡名称
ipvsadm -A -t ${VIP}:8080 -s rr
ipvsadm -a -t ${VIP}:8080 -r 192.168.80.135 -i
ipvsadm -a -t ${VIP}:8080 -r 192.168.80.136 -i
# ----------------------------------------- Real Server
cat > ./lvs_tun.sh <<'EOF'
#!/bin/bash
# -------------------------
# Tips: 需将 tunl0 改为实际的隧道网卡名称
# -------------------------
VIP=192.168.0.38
. /etc/rc.d/init.d/functions
case "$1" in
start)
echo " start REALServer"
modprobe tun
modprobe ipip # 加载ipip模块后执行 ip addr show 会有默认的tunl0隧道
echo "0" > /proc/sys/net/ipv4/ip_forward
ifconfig tunl0 ${VIP} netmask 255.255.255.255 broadcast ${VIP}
route add -host $VIP dev tunl0
echo "1" > /proc/sys/net/ipv4/conf/tunl0/arp_ignore # 需将 tunl0 改为实际隧道网卡名称
echo "2" > /proc/sys/net/ipv4/conf/tunl0/arp_announce #
echo "0" > /proc/sys/net/ipv4/conf/tunl0/rp_filter #
echo "1" > /proc/sys/net/ipv4/conf/eth0/arp_ignore # 需将 eth0 改为实际网卡名称
echo "2" > /proc/sys/net/ipv4/conf/eth0/arp_announce #
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
# tunl0/rp_filter 默认为1,需改为0,关闭此功能,其用于实现反向过滤,即uRPF: 验证反向数据包的流向以避免伪装IP攻击
# 但在 LVS TUN 中数据包是有问题的,因为从 realserver eth0 出去的包源IP应为 192.168.1.62,而不是VIP
# 所以必须关闭此功能
;;
stop)
ifconfig tunl0 down
modprobe -r tun
modprobe -r ipip
echo "close Directorserver"
echo "0" >/proc/sys/net/ipv4/conf/tunl0/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/tunl0/arp_announce
echo "0" >/proc/sys/net/ipv4/conf/eth0/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/eth0/arp_announce
echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
echo "1" > /proc/sys/net/ipv4/conf/tunl0/rp_filter
echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
EOF
chmod u+x lvs_tun.sh && ./lvs_tun.sh start
支持的后端调度算法
# 静态后端调度算法
rr # 轮询
wrr # 带权的轮询
sh # 源地址哈希,将来自于同一个IP的请求始终发往同一个RS (实现会话绑定,但粒度较粗)
dh # 目标地址哈希,将发往同一个目标IP的请求始终保持到同一个 RS,用于正向代理
# 动态后端调度算法 (根据RS当前的负载状态及调度算法进行调度)
lc # 最小连接数,适用于长连接应用(未考虑到后端服务器的性能问题)
wlc # 带权的最少连接数,调度器可自动问询 RS 的负载情况并动态调整权重(是LVS默认的调度算法)
sed # 最短的期望的延迟(较复杂)
nq # 无需队列,若有台RS的连接数为0就直接分配过去(第一次均匀分配,后续按sed)
lblc # 动态的dh算法,场景: 根据负载情况实现正向代理
lblcr # ...