在实际应用中,在Web服务器集群之前总会有一台负载均衡服务器,负载均衡设备的任务就是作为Web服务器流量的入口,挑选最合适的一台Web服务器,将客户端的请求转发给它处理,实现客户端到真实服务端的透明转发:

LVS
LVS是Linux Virtual Server的简称,也就是Linux虚拟服务器, 是由章文嵩博士发起的自由软件项目,现在LVS已经是 Linux标准内核的一部分,从Linux2.4内核以后,已经完全内置了LVS的各个功能模块.
LVS是四层负载均衡,也就是说建立在OSI模型的第四层——传输层之上,即熟悉的TCP/UDP,因为LVS是四层负载均衡,因此它相对于其它高层负载均衡的解决办法,比如DNS域名轮流解析、应用层负载的调度、客户端的调度等,它的效率是非常高的。
LVS 调度算法
-
静态调度
- rr(Round Robin):轮询
- wrr(weight):加权
- sh(source hashing):源地址散列
- dh(Destination Hashing):目标地址散列
-
动态调度
- lc(Least-Connection): 最少连接
- wlc(Weighted Least-Connection): 加权最少连接
- sed(Shortest Expected Delay): 最短期望延迟
- nq(never queue): 永不排队
- LBLC(Locality-Based Least Connection): 基于本地的最少连接
- LBLCR(Locality-Based Least Connections withReplication): 基于本地的带复制功能的最少连接
LVS 三种工作模式
CIP:client ip 客户端的ip
VIP:Virtual IP LVS实例IP,一般是暴露在公网中的地址;向外部直接面向用户请求,作为用户请求的目标的IP地址
DS:Director Server 指的是前端负载均衡器节点
RS:Real Server 后端真实的工作服务器
-
NAT 模式
-
DR 模式
- 数据包CIP->VIP发送给LVS
- LVS通过修改MAC地址把数据包直接扔给RS,由于RS也有VIP,所以收下数据包
- RS处理完成后,直接封数据包VIP->CIP,返回给客户端,不经过LVS
特点:
- RS和LVS必须在同一机房中,很显然,ARP欺骗条件要求LVS和DS要在同一个物理局域网内。
- 所有的请求报文经由LVS,但响应报文必须不能经过LVS
- 不支持地址转换,也不支持端口映射(因为这是链路层/2层的处理,不涉及到IP)
- TUN模式
DR模式搭建实战
实验在docker 中进行:
-
环境准备
- 宿主机开启ipvs内核模块,docker和宿主机是公用内核,所以宿主机开启了docker里面自动开启
查看开启是否成功:# modprobe ip_vs # modprobe ip_vs_wrr
# lsmod | grep ip_vs ip_vs_wrr 12697 0 ip_vs 145458 2 ip_vs_wrr
- 准备docker 容器
设置ip# docker run -dit --name node1 --hostname node1 --privileged centos /usr/sbin/init # docker run -dit --name node2 --hostname node2 --privileged centos /usr/sbin/init # docker run -dit --name node3 --hostname node3 --privileged centos /usr/sbin/init
# node1IP=`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' node1` # node2IP=`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' node2` # node3IP=`docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' node3` # nodeVIP='172.17.0.100' # echo ${node1IP}, ${node2IP}, ${node3IP}, ${nodeVIP} 172.17.0.2, 172.17.0.3, 172.17.0.4, 172.17.0.100 # docker exec -it node1 bash -c "echo node1IP=$node1IP >> ~/.bashrc && echo node2IP=$node2IP >> ~/.bashrc && echo node3IP=$node3IP >> ~/.bashrc && echo nodeVIP=$nodeVIP >> ~/.bashrc && source ~/.bashrc" # docker exec -it node2 bash -c "echo node1IP=$node1IP >> ~/.bashrc && echo node2IP=$node2IP >> ~/.bashrc && echo node3IP=$node3IP >> ~/.bashrc && echo nodeVIP=$nodeVIP >> ~/.bashrc && source ~/.bashrc" # docker exec -it node3 bash -c "echo node1IP=$node1IP >> ~/.bashrc && echo node2IP=$node2IP >> ~/.bashrc && echo node3IP=$node3IP >> ~/.bashrc && echo nodeVIP=$nodeVIP >> ~/.bashrc && source ~/.bashrc"
-
RS 实例配置
进入node2和node3配置# yum install -y net-tools nginx // 修改内核参数(实现对内可见、对外隐藏) # echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore # echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore # echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce # echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce // 添加VIP(对内可见、对外隐藏) 注意掩码必须是255.255.255.255 // 因为VIP是绑在环回网卡上(回环网卡离内核更近,数据包优先匹配) // 如果掩码不是4个255,则数据包在返回的时候匹配上了回环网卡,匹配不上真实网关,数据包发送不出去 # ifconfig lo:vip ${nodeVIP} netmask 255.255.255.255 # 启动nginx # systemctl start nginx # 给不同RS添加各自IP用于区分 # echo `ifconfig $name | grep "inet.*broadcast.*" | cut -d' ' -f10` > /usr/share/nginx/html/index.html
-
LVS 实例配置
进入node1配置// 安装ifconfig ipvsadm命令 # yum install -y net-tools ipvsadm // 添加VIP 这里掩码是16还是24根据具体情况而定 # ifconfig eth0:vip ${nodeVIP}/16 // 清空所有规则 # ipvsadm -C // -A添加流量进入规则 # ipvsadm -A -t ${nodeVIP}:80 -s rr // 在上面的进入规则下面添加流量出去(分发给RS)的规则 # ipvsadm -a -t ${nodeVIP}:80 -r ${node2IP} -g -w 1 # ipvsadm -a -t ${nodeVIP}:80 -r ${node3IP} -g -w 1
查看规则
ipvsadm -ln
,输出如下:# ipvsadm -ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.17.0.100:80 rr -> 172.17.0.3:80 Route 1 0 0 -> 172.17.0.4:80 Route 1 0 0
-
测试
在宿主机上运行:# while true; do curl ${nodeVIP}; sleep 1 ;done
image.png
- 宿主机开启ipvs内核模块,docker和宿主机是公用内核,所以宿主机开启了docker里面自动开启
网友评论