- 本篇不讲原理,原理可以直接看官方文档,因此没必要做过多赘述。
LVS中文文档(原理)
LVS英文文档(原理及配置)
2. 本文测试的是LVS+Apache(yum安装,不详细阐述)
0、ipvsadm 用法
ipvsadm——Linux Virtual Server 管理工具
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask]
ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight] [-x upper] [-y lower]
更多模式man ipvsadm
01.命令
-A 增加一个虚拟服务。服务地址由三元组唯一定义:IP地址,端口号和协议。
-D 删除一个虚拟服务以及任何关联的真实服务器
-C 清除虚拟服务表(virtual server table)
-R 从标准输入恢复虚拟服务规则
-S --save 将Linux虚拟服务转储为stdout(可以被-R 使用)
-a 给虚拟服务增加一个真实服务
-d 从虚拟服务上删除一个真实服务
-L,-l 如果没有指定参数,则列出虚拟服务表。如果一个服务器地址被指定,则仅仅显示这个服务;如果指定 -c 选项,则列出连接表。-
-Z 将服务或所有服务中的数据包,字节和速率计数器清零。
--set
--start-daemon
--stop-daemon
这里讲下什么是增加一个虚拟服务。因为我们负载均衡时,可能需要负载几种服务,如Web服务,SSH服务等,一个服务对应一个虚拟服务表。也就是说,这些虚拟服务是独立的
02.参数
-t, --tcp-service 使用TCP服务(服务地址由三元组唯一定义:IP地址,端口号和协议,这里就是TCP协议)
-u, --udp-service 使用UDP服务
-f, --fwmark-service 使用一个大于0的firewall-mark 来表示虚拟服务,而不是用三元组模式
-s, --scheduler 指定调度器
-p, --persistent [timeout] 指定虚拟服务是持久的。如果指定此选项,来自一个客户端的多个请求都会被重定向到第一次处理该请求的真实服务器。此外,可以以秒为单位指定持久会话的超时,否则将使用默认值300秒。此选项对于SSL或FTP协议这种客户端始终需要连接到同一真实服务器 这个性质很重要。
-r 指定真实服务器IP(加端口)
-w 指定权重
-c 输出当前连接。同 -L 一起使用
-n IP地址和端口等以数字形式输出,而不是以默认的主机名和端口名输出
还有一些其他参数直接查看ipvsadm的man手册。
调度器种类
上面参数中指出-s参数可以指定调度策略,调度策略是一个用于将TCP和UDP数据分配给真实服务器的算法,调度算法由内核直接实现。这里说下有哪些可用的调度策略 :
rr Round Robin(循环):在可用的真实服务器之间平等分配作业。
wrr Weighted Round Robin:根据真实服务的权重比例来分配任务。权重高的会最先收到任务并且比权重低的真实服务器收到更多的任务。权重相同则平均分批任务
lc
wlc
lblc
lblcr
dh
sh
sed
nq
03. 包转发策略
LVS有3种包转发策略,分别是directing routing模式,tun模式以及 NAT模式。下面列出了这些模式在命令行中的指定方式。
-g, --gatewaying directing routing模式
-i, --ipip 使用tun(隧道)模式
-m, --masquerading 使用NAT模式
ipvsadm和LVS的基础基本就这么多了(),更加详细的可直接查看官方文档。下面开始实际配置3种包转发模式。
一、LVS NAT模式
当用户访问服务器集群提供的服务时,目的地为虚拟IP地址(负载均衡器的外部IP地址)的请求包到达负载均衡器。负载平衡器检查数据包的目标地址和端口号。如果根据虚拟服务器规则表匹配虚拟服务器服务,则通过调度算法从集群中选择真实服务器,并将连接添加到记录所建立的连接的散列表中。然后,将分组的目的地地址和端口重写为所选服务器的目的地地址和端口,并将分组转发到服务器。当输入分组属于此连接并且可以在散列表中找到所选择的服务器时,该分组将被重写并转发到所选择的服务器。当回复分组返回时,负载平衡器将分组的源地址和端口重写为虚拟服务的源地址和端口。连接终止或超时后,连接记录将在哈希表中删除。NAT一般用于IP不够用的情况,如果IP够用,可不用NAT,而是用下面的DR模式。
NAT工作模式的负载均衡结构表:
备注:我的两个真实服务器都是httpd服务器
1.1 基础环境需求
- 安装ipvsadm工具
yum install ipvsadm -y
- 要保证网络通常
1.2 LVS调度服务器配置
[root@logan ~]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:E9:F0:0D
inet addr:192.168.159.240 Bcast:192.168.159.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fee9:f00d/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:4171 errors:0 dropped:0 overruns:0 frame:0
TX packets:2540 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:439197 (428.9 KiB) TX bytes:306358 (299.1 KiB)
eth0:0 Link encap:Ethernet HWaddr 00:0C:29:E9:F0:0D
inet addr:172.16.0.1 Bcast:172.16.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
1. 开启路由转发
echo 1 > /proc/sys/net/ipv4/ip_forward
注意,这里只能是在系统运行时修改后生效。重启后就会丢失,因此必须直接写/etc/sysctl.conf文件使其永久生效如下:
net.ipv4.ip_forward = 1
2.添加一个虚拟服务并将它连接到一个调度程序
ipvsadm -A -t 192.168.159.240:80 -s wlc
3.添加真实服务IP并选择转发方式
ipvsadm -a -t 192.168.159.240:80 -r 172.16.0.2:80 -m
ipvsadm -a -t 192.168.159.240:80 -r 172.16.0.3:80 -m
4.启动LVS并保存规则
/sbin/ipvsadm
/etc/init.d/ipvsadm save
5.查看转发情况
ipvsadm -Ln
以上步骤,也可以使用 ipvsadm -R 完成
[root@logan ~]# echo "-A -t 192.168.159.240:http -s wlc
> -a -t 192.168.159.240:http -r 172.16.0.2:http -m -w 1
> -a -t 192.168.159.240:http -r 172.16.0.3:http -m -w 1" | ipvsadm -R
1.3 检查均衡是否生效
- 使用ipvsadm -L查看虚拟服务列表
[root@logan ~]# ipvsadm -L
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.159.240:http wlc
-> 172.16.0.2:http Masq 1 0 0
-> 172.16.0.3:http Masq 1 0 0
- 模拟访问,之后查看当前连接
[root@logan ~]# ipvsadm -l -c
IPVS connection entries
pro expire state source virtual destination
TCP 01:33 TIME_WAIT 192.168.159.1:65130 192.168.159.240:http 172.16.0.3:http
TCP 00:42 SYN_RECV 192.168.159.1:65125 192.168.159.240:http 172.16.0.2:http
TCP 01:34 TIME_WAIT 192.168.159.1:65137 192.168.159.240:http 172.16.0.3:http
TCP 00:42 SYN_RECV 192.168.159.1:65133 192.168.159.240:http 172.16.0.2:http
TCP 00:41 SYN_RECV 192.168.159.1:65121 192.168.159.240:http 172.16.0.2:http
TCP 01:32 TIME_WAIT 192.168.159.1:65120 192.168.159.240:http 172.16.0.3:http
TCP 00:43 SYN_RECV 192.168.159.1:65140 192.168.159.240:http 172.16.0.2:http
TCP 01:53 TIME_WAIT 192.168.159.1:65154 192.168.159.240:http 172.16.0.3:http
TCP 01:33 TIME_WAIT 192.168.159.1:65124 192.168.159.240:http 172.16.0.3:http
TCP 01:34 TIME_WAIT 192.168.159.1:65139 192.168.159.240:http 172.16.0.3:http
TCP 00:43 SYN_RECV 192.168.159.1:65138 192.168.159.240:http 172.16.0.2:http
TCP 00:43 SYN_RECV 192.168.159.1:65136 192.168.159.240:http 172.16.0.2:http
TCP 01:33 TIME_WAIT 192.168.159.1:65135 192.168.159.240:http 172.16.0.3:http
从这里可以看出,LVS均衡调度已经生效了。有点需要注意下,就是均衡器本机的80端口是不用开启的。为了以后方便,可以写一个脚本,如下:
#!/bin/bash
#############################
# filename: lvs.sh
# author: yantao
# function: set LVS
# date: 2017/03/15
num=$(rpm -qa ipvsadm | wc -l)
if [ $num -gt 0 ]
then
echo -e "\033[32m ipvsadm installed \033[0m"
else
yum install ipvsadm -y
fi
virtual_ip="192.168.159.240"
real_ip="172.16.0.2 172.16.0.3"
function lvs(){
echo 1 > /proc/sys/net/ipv4/ip_forward
ipvsadm -A -t $virtual_ip:$1 -s wrr
for real_ip in $real_ip
do
ipvsadm -a -t $virtual_ip:$1 -r $real_ip:$1 -m
done
}
echo -e "\033[31m Begin setting LVS................. \033[0m"
lvs "80" #parameter is port number
if [ $? -eq 0 ]
then
echo -e "\033[33m LVS set sucess \033[0m"
ipvsadm
fi
二、LVS DR模式
负载均衡器具有配置虚拟IP地址的接口, 用于接收请求分组并直接将分组路由到所选择的真实服务器。所有真实服务器具有non-arp 别名接口来配置VIP(虚拟IP) 或者把VIP数据包重定向到本地scoket,使得真实服务器可以在本地处理包。负载均衡器和真实服务器必须有一个通过HUB/Switch物理连接的接口。
当用户访问由服务器集群提供的虚拟服务时,分组发往虚拟IP地址(虚拟服务器的IP地址)。负载均衡器(LinuxDirector)检查数据包的目标地址和端口。如果它们匹配虚拟服务,则通过调度算法从集群中选择真实服务器,并且将连接添加至记录连接的hash表中。然后,负载均衡器将其直接转发到所选服务器。当进来的数据包属于此连接并且可以在hash表中找到所选服务器时,该数据包将再次直接路由到同一个服务器。当真实服务器接收到转发的数据包时,服务器发现该数据包是用于其别名接口(alias interface)或本地套接字(local socket)上的地址,因此它处理请求并将结果直接返回给用户。连接终止或超时后,连接记录将从hash中删除。
负载均衡器只需将数据帧的MAC地址更改为所选服务器的MAC地址,并在LAN上重新传输。这是为什么负载均衡器和每个服务器必须通过单个不间断段彼此直接连接LAN的的原因。
备注:以上两段翻译自官网,如有误,请指正。
2.1 DR模式特点及注意事项
- VIP地址为调度服务器和真实服务器组共享
- 调度器配置的VIP对外可见;用于接受虚拟服务的请求
- 所有后端服务器把VIP地址配置在各自的Non-ARP网络设备上,对外不可见,只是用于处理目标地址为VIP的网络请求
- 服务器直接将响应返回给客户端
这里重点提出下 Non-ARP设备,这个意思就是说禁止ARP响应。为什么要禁止ARP响应呢?我们从DR模式的特点可以发现,LVS均衡器和真实服务器共享VIP,也就是说他们都在网卡上配置了VIP。在一些配置中,真实服务器和接受请求数据包的负载均衡器在同一网络上,如果真实服务器上的VIP响应这个请求,就会产生竞争条件,那么谁的都不会响应。数据包在一个时间点发送到负载均衡器的VIP上,另一次又发送到真实服务器上,如此反复,这就会导致整个LVS集群不能正常工作。为了保证只有负载均衡器能响应,因此需要关掉真实服务器的ARP响应。 这样,真实服务器的才不会响应ARP请求。
2.2 DR集群配置
负载均衡器IP | VIP | real server IP |
---|---|---|
192.168.1.100 | 192.168.1.101 | 192.168.1.222 与 192.168.1.223 |
2.2.1 负载均衡器端
- 开启路由转发以及配置VIP
$ echo 1 > /proc/sys/net/ipv4/ip_forward
$ ifconfig eth0:virtual 192.168.1.101 netmask 255.255.255.0
- 增加虚拟httpd服务以及真实服务器
$ echo "-A -t 192.168.1.101:80 -s wrr
> -a -t 192.168.1.101:80 -r 192.168.1.222 -g
> -a -t 192.168.1.101:80 -r 192.168.1.223 -g" | ipvsadm -R
2.2.2 真实服务器端
- 配置VIP以及禁止ARP响应
$ ifconfig eth0:0 192.168.1.101 netmask 255.255.255.255
$ echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
$ echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
$ echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
$ echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce
2.2.3 注意事项
VIP配置在哪个网络接口?
Linux内核2.0.xx系列中不对环回别名和隧道接口做arp响应,这对LVS集群很有好处。 然而,Linux内核2.2.xx执行所有其IP地址的所有arp响应,除了环回地址(127.0.0.0/255.0.0.0)和组播地址。前面说过,要对VIP所在的接口禁止ARP响应。那么,这个接口上的所有IP地址都不会响应ARP请求了,这里就是个大问题。因此,对于只有一个物理网卡的情况下,VIP则要配置在lo口或者虚拟网卡上,除非有多余的物理网卡。比如我这里是设置在 eth0:0 这个虚拟网卡上。网络连通性
注意防火墙配置;网络本身是否通;我的真实服务器的防火墙配置:
iptables -I INPUT 1 -d 192.168.1.101 -p tcp --dport 80 -j ACCEPT
real server上的VIP 子网掩码必须为 255.255.255.255?
关于这个问题,我一开始是挺纠结的。以下是我个人理解:如果把VIP配置在lo口上,假设掩码不是255.255.255.255,而是255.255.255.0,那么这将导致真实服务器接收192.168.1.0 - 192.168.1.255这个范围内all地址的所有数据包,但是我们讲过,除了对VIP开放外应该将lo隐藏起来,因此子网掩码必须为255.255.255.255。此外,还有一个作用是保证同局域网IP不冲突,因为32位的一个网段就是一个IP。我测试的时候发现一个32位,一个24位同样是可以的,只要保证IP不冲突,但是这种建议还是写32位,因为不需要响应一些其他网段的广播之类的。real server VIP不能出外网
这里意思就是VIP和外网IP(存在直接转发给外网IP的情况)不能为一个。理由还是IP冲突的问题。每个real server肯定有同一个VIP,但是这些IP如果还是本机IP,则会产生IP冲突了。因此即使是有多余的物理网卡,我们一般都配置在loopback 接口上,这样既可避免IP冲突,又能避免ARP响应(需修改内核参数,如上)。
最后,我们可以在一台机器上有多个VIP,这样就能为多个网站提供负载。而不是有一个网站就搞一个新机器建立LVS,小流量的网站完全没必要。