1 实验架构

        实验环境:RS1、RS2为真实的两台apache服务器,测试时为了测试效果在/var/www/html/index.html内写入不同内容。LVS与这两台RS1、RS2在一个大二层内。具体的修改内容信息不进行详细说明,仅说明思路。

  1. LVS服务器上起子接口,配置虚拟ip地址。内核配置文件中配置arp相关的选项参数,ipvsadm配置到RS真实服务器的信息,以及所用的调度算法;
  2. RS1、RS2上内核配置文件设置相关的arp配置信息,起loopback0:0的子接口,并配置到虚ip的路由信息,开启apache服务;
  3. 客户端进行测试,验证调度算法以及现实效果;

2 ipvsadm

     罗列以下常见的命令(centos6):

  • ipvsadm -v # 查看当前 ipvs 集群内容
  • ipvsadm -A-t 虚拟 IP:80 -s rr # 添加 ipvs TCP 集群
  • ipvsadm -a -t 虚拟 IP:80 -r 网站 1:80 -g # 添加 ipvsadm 集群子节点
  • ipvsadm -a -t 虚拟 IP:80 -r 网站 2:80 -g
  • ipvsadm -Ln
  • service ipvsadm save # 保存 ipvs 集群内容至文件,进行持久化存储。centos7里的命令与6不同,使用ipvsadm --save > /etc/sysconfig/ipvsadm进行保存到配置文件(/etc/sysconfig/ipvsadm)。
  • chkconfig ipvsadm on # 设置为开机自启(centos7是systemctl enable ipvsadm.service)

3 LVS-DR模式实验过程

        实验环境如下,共使用四台主机设备,客户端、LVS、两台后端服务器。

Linux中lvs_IP

        图中标注出来回流量走向,入向流量用黑色线表示,回流量用红色曲线表示。

 LVS机器设置:

cd /etc/sysconfig/network-scripts/
cp ifcfg-eth0 ifcfg-eth0:0 # 拷贝 eth0 网卡子接口充当集群入口接口
vim ifcfg-eth0:0
DEVICE=eth0:0
IPADDR=虚拟 IP
NETMASK=255.255.255.0
ifup eth0:0
vim /etc/sysctl.conf # 关闭网卡重定向功能
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
sysctl -p
modprobe ip_vs # 重载 ipvs 模块
rpm -ivh ipvsadm-1.26l......... # 安装 ipvsadm 命令行工具
ipvsadm -v # 查看当前 ipvs 集群内容
ipvsadm -A-t 虚拟 IP:80 -s rr # 添加 ipvs TCP 集群
ipvsadm -a -t 虚拟 IP:80 -r 网站 1:80 -g # 添加 ipvsadm 集群子节点
ipvsadm -a -t 虚拟 IP:80 -r 网站 2:80 -g
ipvsadm -Ln
service ipvsadm save # 保存 ipvs 集群内容至文件,进行持久化存储
chkconfig ipvsadm on # 设置为开机自启

真实服务器:

service NetworkManager stop # 关闭网卡守护进程
cd /etc/sysconfig/network-scripts/
cp ifcfg-lo ifcfg-lo:0
vim ifcfg-lo:0 # 拷贝回环网卡子接口
DEVICE=lo:0
IPADDR=虚拟 IP
NETMASK=255.255.255.255
vim /etc/sysctl.conf# 关闭对应 ARP 响应及公告功能
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
#载入sysctl配置文件
sysctl -p
#配置网卡
ifup lo: 0
route add -host 虚拟 IP dev lo:0 # 添加路由记录,当访问 VIP 交给 lo:0 网卡接受
#设置apache服务器:
[root@vm6 ~]# cat /var/www/html/index.html 
this is server 2
#
service httpd start

以上配置完成后进行客户端测试:(负载调度算法是轮询)

Linux中lvs_Linux中lvs_02

4 LVS NAT模式实验过程

实验环境如下,总共4台主机,客户端、LVS、两台服务器。

Linux中lvs_Linux中lvs_03

         对于LVS NAT的这种方式,进出流量相对于DR模式来说都会经过LVS,入向时做一次LVS DNAT,回包时做SNAT。通过实验结果,查看ipvsadm stats结果也是如此:

Linux中lvs_IP_04

 real server上开启httpd服务器,配置不同的index.html。回程路由需要控制好。

LVS上配置:

负载调度器
vi /etc/sysctl.conf # 开启路由转发功能
[root@vm4 ~]# cat /etc/sysctl.conf 
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.ipv4.ip_forward =1
#net.ipv4.conf.default.rp_filter=1
#net.ipv4.conf.default.accept_source_route = 0
#kernel.sysrq=0
#kernel.core_uses_pid=1
#net.ipv4.tcp_syncookies = 1
#kernel.msgmnb = 65536
#kernel.msgmax = 65536
#kernel.shmmax = 68719476736
#kernel.shmall = 4294967296

配置SNAT:
iptables -t nat -A POSTROUTING -s 10.10.1.0/28 -o  enp0s3 -j SNAT --to-source 192.168.1.250

保存iptables:
[root@vm4 ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables: [  确定  ]

查看是否生效:
[root@vm4 ~]# iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       all  --  10.10.1.0/28         0.0.0.0/0            to:192.168.1.250

创建集群:
ipvsadm -A-t 20.20.20.11:80 -s rr # 添加 ipvsadm TCP 集群
ipvsadm -a -t 20.20.20.11:80 -r 10.10.10.12:80 -m # 添加 ipvsadm 节点
ipvsadm -Ln
service ipvsadm save # 保存 ipvs 集群设置到文件进行持久化
chkconfig ipvsadm on 自启动

 真实服务器上配置并开启apache服务:

路由都配置好

[root@vm6 ~]# echo "2222" >> /var/www/html/index.html
[root@vm6 ~]# 
[root@vm6 ~]# 
[root@vm6 ~]# curl localhost:8080
2222

[root@vm5 ~]# echo "11111" >> /var/www/html/index.html
[root@vm5 ~]# 
[root@vm5 ~]# 
[root@vm5 ~]# curl localhost:80
1111

 客户端测试:

Linux中lvs_运维_05

ipvsadm命令详解可以参考:

https://blog.51cto.com/u_10978134/2122118


5 负载均衡集群相关调度算法

       主要分为两大类:(1)静态调度算法:只根据算法本身去调度,不考虑服务器本身;(2)动态调度算法:除了考虑算法本身,还要考虑服务器状态;

5.1 静态调度算法

  • RR 轮询:将每次用户的请求分配给后端的服务器,从第一台服务器开始到第 N 台结束,然后循环;
  • WRR 加权轮询:按照权重的比例实现在多台主机之间进行调度;
  • SH(source hash)源地址散列:将同一个 IP 的用户请求,发送给同一个服务器;
  • DH(destination hash)目标地址散列:将同一个目标地址的用户请求发送给同一个真实服务器(提高缓存的命中率);

       一般用户需要频繁的访问一个web网站时,需要输入用户名/密码。没有其他技术时需要频繁的输入用户名密码,该问题后续由用户本地终端的cookie和服务端的session解决:

Linux中lvs_IP_06

       但是,cookie存放这些数据的话容易被一些别有用心的人通过cookie分析器盗走相关的用户名密码信息。对于这种问题下:

Linux中lvs_运维_07

        如上,使用SH算法就比较适合这种场景,对于同一个源的访问始终定位到那台已有该用户session的NGINX机器上,从而避免反复输入用户名密码。

       下面这种情况就比较适合于DH算法,对于同一个目标访问始终分配到已有缓存的SQUID机器上,避免SQUID对后端进行反复数据交互。

Linux中lvs_运维_08

 5.2 动态调度算法

  • LC(lest-connection)最少连接:将新的连接请求,分配给连接数最少的服务器 活动连接 × 256 + 非活动连接;
  • WLC 加权最少连接:特殊的最少连接算法,权重越大承担的请求数越多 (活动连接 × 256 + 非活动连接 ) / 权重;
  • SED 最短期望延迟:特殊的 WLC 算法 (活动连接 + 1) * 256 / 权重;
  • NQ 永不排队:特殊的 SED 算法,无需等待,如果有真实服务器的连接数等于 0 那就直接分配不需要运算;
  • LBLC 特殊的 DH 算法:即能提高缓存命中率,又要考虑服务器性能;
  • LBLCR LBLC+缓存:尽可能提高负载均衡和缓存命中率的折中方案;

6 持久连接

        为什么需要持久连接呢?这是由于对于我们日常在公网上比较多的https连接,频繁的新建会比较消耗服务器的性能,对于一些频繁需要访问的设置一个较长的expire也会相应优化流量的分配和机器负载。

Linux中lvs_IP_09

 

 (1)PCC (持久客户端连接):每客户端持久;将来自于同一个客户端的所有请求统统定向至此前选定的 RS ;也就是只要 IP相同,分配的服务器始终相同。

example :ipvsadm -A  -t 172.16.0.8:0 -s wlc -p 120

(2)PPC (持久端口连接):每端口持久;将来自于同一个客户端对同一个服务( ( 端口) ) 的请求,始终定向至此前选定的RS。

example :ipvsadm -A -t 172.16.0.8:80 -s rr -p 120

(3)PFMC :持久防火墙标记连接;将来自于同一客户端对指定服务( ( 端口) ) 的请求,始终定向至此选定的 RS ;不过它可以将两个毫不相干的端口定义为一个集群服务。

# iptables -t mangle -A PREROUTING -d 172.16.0.8 -p tcp --dport 80 -j MARK --set-mark 10
# iptables -t mangle -A PREROUTING -d 172.16.0.8 -p tcp --dport 443 -j MARK --set-mark 10
# service iptables save
# ipvsadm -A -f 10 -s wlc -p 120