LVS(NAT)模式原理和实战演练
一.LVS简介
LVS(Linux Virtual Server)即Linux虚拟服务器,是1998年5月由章文嵩博士主导的开源项目,是中国国内最早出现的自由软件项目之一。该项目在Linux内核中实现了基于IP的数据请求负载均衡调度方案(侧重点是调度),其体系结构如下图所示,终端互联网用户从外部访问公司的负载均衡服务器,终端用户的Web请求会发送给LVS调度器(即下图中的lvs负载均衡调度器),调度器根据自己预设的算法决定将该请求发送给后端的某台Web服务器,比如,轮询算法可以将外部的请求平均分发给后端的每一台服务器,终端用户访问LVS调度器虽然会被转发到后端真实的服务器,但如果真实服务器连接的是相同的存储,提供的服务也是相同的服务,最终用户不管是访问哪台真实服务器,得到的服务内容都是一样的,整个集群对用户而言都是透明的。最后根据LVS工作模式的不同,真实服务器会选择不同的方式将用户需要的数据发送到终端用户,LVS工作模式分为NAT模式、TUN模式、DR模式,以及fullnat模式(使用较少)。
二.基于NAT的LVS模式
NAT(Network Address Translation)即网络地址转换,其作用是通过数据报头的修改,使得位于企业内部的私有IP地址可以访问外网,以及外部互联网用户可以访问公司内部的私有IP主机。LVS/NAT工作模式拓扑结构如图所示,LVS负载调度器可以使用两块网卡配置不同的IP地址,eth0设备为外网IP与外部互联网用户联通,eth1为公司内网IP与内部网络通过交换设备相互连接。
用户通过互联网DNS服务器解析到公司负载均衡设备上面的外网地址(即下图中的VIP:Virtual IP Address),用户通过访问VIP,即可连接后端的真实服务器RS(Real Server,即下图中的后端web服务器),而这一切对用户而言都是透明的,用户以为自己访问的就是真实服务器,但他并不知道自己访问的VIP仅仅是一个调度器,也不清楚后端的真实服务器到底在哪里、有多少真实服务器。
2.1 lvs(nat)模式的特征:
(1) RIP和DIP应在同一网络中,且都为私网IP地址,RS的网关要指向DIP;
(2) 请求报文和响应报文都必须要经由调度器转发,调度器容易成为系统瓶颈;
(3) 支持端口映射,可修改请求报文的目标端口;
(4) 调度器必须是Linux系统,RS可以是任何系统
2.2 工作流程:
(1).客户端访问集群的VIP,请求WEB资源(请求报文:源地址为CIP,目标地址为VIP);
(2).Director收到客户端的请求报文,会修改请求报文中的目标地址(VIP)为RIP,并且将请求根据相应的调度算法送往后端WEB服务器(请求报文:源地址CIP,目标地址为RIP);
(3).WEB服务器收到请求,检查报文是访问自己的而自己也提供WEB服务,就会响应这个请求报文,并发送给Director(响应报文:源地址RIP,目标地址CIP);
(4).Director收到WEB服务器的响应报文,会根据自己内部的追踪机制,判断出用户访问的是VIP,此时会修改源地址为VIP并响应客户端请求(响应报文:源地址VIP,目标地址CIP)。
在这个过程中的数据包更改情况如下表所示:
数据包走向 |
SRC IP PORT |
DEST IP PORT |
从浏览器发起请求到调度器 |
CIP 浏览器随机端口xxx |
VIP 80/TCP |
达到调度器时更改目标地址 |
CIP 浏览器随机端口xxx |
RIP1 80/TCP |
响应并返回数据包给调度器 |
RIP1 80/TCP |
CIP 浏览器随机端口xxx |
调度器返回数据包给用户 |
VIP 80/TCP |
CIP 浏览器随机端口xxx |
三.LVS(NAT)实战
3.1 实验拓扑图:
3.2 环境准备:
主机名 |
IP地址 |
身份 |
lvs-server |
VIP:192.168.0.200 DIP:10.4.7.200 |
LVS负载均衡调度器 |
Web01 |
RIP:10.4.7.10 |
公司内网web服务器 |
Web02 |
RIP:10.4.7.11 |
公司内网web服务器 |
192 |
CIP:192.168.0.106 |
互联网Client |
关闭selinux和防火墙
[root@lvs-server ~]# sestatus
SELinux status: disabled
3.3 配置LVS服务器:
(1).配置VIP和DIP
[root@lvs-server network-scripts]# cat ifcfg-ens33 #VIP网卡配置,VIP为外网IP,因此要能访问外网
TYPE="Ethernet" PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="none" DEFROUTE="yes" IPV4_FAILURE_FATAL="no" NAME="ens33" DEVICE="ens33" ONBOOT="yes" IPADDR="192.168.0.200" PREFIX="24" GATEWAY="192.168.0.1" DNS2=8.8.8.8 DNS3=114.114.114.114
[root@lvs-server network-scripts]# cat ifcfg-ens37 #DIP网卡配置,DIP为公司内网,配置内网IP地址,并将后端web服务器的网关指向DIP
TYPE="Ethernet" PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="none" DEFROUTE="yes" IPV4_FAILURE_FATAL="no" NAME="ens37" DEVICE="ens37" ONBOOT="yes" IPADDR="10.4.7.200" PREFIX=24
[root@lvs-server network-scripts]# /etc/init.d/network restart
[root@lvs-server network-scripts]# ping www.baidu.com -c 4
PING www.baidu.com (180.101.49.11) 56(84) bytes of data. 64 bytes from 180.101.49.11 (180.101.49.11): icmp_seq=1 ttl=52 time=24.4 ms 64 bytes from 180.101.49.11 (180.101.49.11): icmp_seq=2 ttl=52 time=23.3 ms 64 bytes from 180.101.49.11 (180.101.49.11): icmp_seq=3 ttl=52 time=24.6 ms 64 bytes from 180.101.49.11 (180.101.49.11): icmp_seq=4 ttl=52 time=24.1 ms --- www.baidu.com ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3005ms rtt min/avg/max/mdev = 23.397/24.157/24.690/0.520 ms
(2).打开内核地址转发功能
[root@lvs-server ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
[root@lvs-server ~]# sysctl -p
net.ipv4.ip_forward = 1
(3).安装ipvsadm工具并配置调度规则
[root@lvs-server ~]# yum -y install ipvsadm #ipvsadm是ip_vs内核模块的管理工具,直接操作内核模块,即使生效,跟iptables很相像
[root@lvs-server ~]# yum info ipvsadm
Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile * base: mirror.bit.edu.cn * extras: mirrors.aliyun.com * updates: mirror.bit.edu.cn Installed Packages Name : ipvsadm Arch : x86_64 Version : 1.27 Release : 7.el7 Size : 75 k Repo : installed From repo : base Summary : Utility to administer the Linux Virtual Server URL : https://kernel.org/pub/linux/utils/kernel/ipvsadm/ License : GPLv2+ Description : ipvsadm is used to setup, maintain, and inspect the virtual server : table in the Linux kernel. The Linux Virtual Server can be used to : build scalable network services based on a cluster of two or more : nodes. The active node of the cluster redirects service requests to a : collection of server hosts that will actually perform the : services. Supported Features include: : - two transport layer (layer-4) protocols (TCP and UDP) : - three packet-forwarding methods (NAT, tunneling, and direct routing) #三种转发模式--NAT、TUN、DR : - eight load balancing algorithms (round robin, weighted round robin, #8种调度规则--rr、wrr、lc、wlc、lblc、lblcr、dh、sh : least-connection, weighted least-connection, locality-based : least-connection, locality-based least-connection with : replication, destination-hashing, and source-hashing)
[root@lvs-server ~]# ipvsadm -A -t 192.168.0.200:80 -s rr #详细命令选项,参看文末解释
[root@lvs-server ~]# 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.200:80 rr #TCP协议 VIP:PORT 调度规则rr
[root@lvs-server ~]# ipvsadm -a -t 192.168.0.200:80 -r 10.4.7.10:80 -m
[root@lvs-server ~]# ipvsadm -a -t 192.168.0.200:80 -r 10.4.7.11:80 -m
[root@lvs-server ~]# 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.200:80 rr -> 10.4.7.10:80 Masq 1 0 0 -> 10.4.7.11:80 Masq 1 0 0
[root@lvs-server ~]# systemctl enable ipvsadm #将ipvsadm设置为开机自启动
Created symlink from /etc/systemd/system/multi-user.target.wants/ipvsadm.service to /usr/lib/systemd/system/ipvsadm.service.
自此,LVS均衡调度服务器就配置完成了。
3.4 配置RS服务器
(1).配置RS服务器网卡
注:由于此处web01和web02的配置相同,此处就以web01进行实验演示
[root@web01 network-scripts]# cat ifcfg-ens33
TYPE="Ethernet" PROXY_METHOD="none" BROWSER_ONLY="no" BOOTPROTO="none" DEFROUTE="yes" IPV4_FAILURE_FATAL="no" NAME="ens33" DEVICE="ens33" ONBOOT="yes" IPADDR="10.4.7.10" #web02的IP地址为10.4.7.11 PREFIX="24" GATEWAY="10.4.7.200" #网关指向LVS均很调度器的DIP
[root@web01 network-scripts]# /etc/init.d/network restart #重启完成后,两台RS要能ping通DIP,但不能ping通外网
[root@web01 network-scripts]# ping www.baidu.com #内网地址不能到互联网
ping: www.baidu.com: Name or service not known
[root@web01 network-scripts]# ping 10.4.7.200 -c 4 #能ping通DIP
PING 10.4.7.200 (10.4.7.200) 56(84) bytes of data. 64 bytes from 10.4.7.200: icmp_seq=1 ttl=64 time=0.521 ms 64 bytes from 10.4.7.200: icmp_seq=2 ttl=64 time=0.251 ms 64 bytes from 10.4.7.200: icmp_seq=3 ttl=64 time=0.191 ms 64 bytes from 10.4.7.200: icmp_seq=4 ttl=64 time=0.218 ms --- 10.4.7.200 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 2999ms rtt min/avg/max/mdev = 0.191/0.295/0.521/0.132 ms
(2).安装httpd服务:
[root@web01 ~]# yum -y install httpd
[root@web01 ~]# echo "from web01 ,RIP 10.4.7.10" > /var/www/html/index.html #web02的文件内容为“from web02 ,RIP 10.4.7.11”
[root@web01 ~]# systemctl restart httpd && systemctl enable httpd
此时这两台机器间的httpd服务应该是可以相互访问的:
[root@web01 ~]# curl 10.4.7.11
from web02 ,RIP 10.4.7.11
[root@web02 ~]# curl 10.4.7.10
from web01 ,RIP 10.4.7.10
(3).通过外网客户端访问http访问
[root@192 ~]# curl 192.168.0.200 #由于我们定义的轮询,因此调度器将均衡的将请求调度到后端的两台服务器上
from web02 ,RIP 10.4.7.11
[root@192 ~]# curl 192.168.0.200
from web01 ,RIP 10.4.7.10
[root@192 ~]# curl 192.168.0.200
from web02 ,RIP 10.4.7.11
[root@192 ~]# curl 192.168.0.200
from web01 ,RIP 10.4.7.10
#此时RS上的日志显示如下,从日志的信息可以看出,是CIP访问的服务器,VIP这是起到了调度作用
[root@web01 ~]# tailf -2 /var/log/httpd/access_log
192.168.0.106 - - [05/Mar/2020:22:38:16 +0800] "GET / HTTP/1.1" 200 26 "-" "curl/7.29.0" 192.168.0.106 - - [05/Mar/2020:22:38:18 +0800] "GET / HTTP/1.1" 200 26 "-" "curl/7.29.0"
[root@web02 ~]# tailf -2 /var/log/httpd/access_log
192.168.0.106 - - [05/Mar/2020:22:38:14 +0800] "GET / HTTP/1.1" 200 26 "-" "curl/7.29.0" 192.168.0.106 - - [05/Mar/2020:22:38:17 +0800] "GET / HTTP/1.1" 200 26 "-" "curl/7.29.0"
(4).端口映射
lvs(nat)模式支持端口映射,因此我们可以将后端服务器的http端口设置成非80端口,如下:
[root@web01 ~]# vim /etc/httpd/conf/httpd.conf #修改web01的httpd端口为8080
Listen 8080 #将默认的80修改成8080端口
[root@web01 ~]# systemctl restart httpd
修改lvs服务器上的配置规则:
[root@lvs-server ~]# ipvsadm -d -t 192.168.0.200:80 -r 10.4.7.10:80 #删除之前创建的关于web01的调度规则
[root@lvs-server ~]# 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.200:80 rr
-> 10.4.7.11:80 Masq 1 0 0 #删除后只剩下10.4.7.11这台RS的调度规则
[root@lvs-server ~]# ipvsadm -a -t 192.168.0.200:80 -r 10.4.7.10:8080 -m #冲洗添加web01的规则,将端口指定为8080
[root@lvs-server ~]# 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.200:80 rr -> 10.4.7.10:8080 Masq 1 0 0 #新加规则 -> 10.4.7.11:80 Masq 1 0 0
[root@192 ~]# curl 192.168.0.200 #再次通过CIP访问,访问成功
from web01 ,RIP 10.4.7.10
[root@192 ~]# curl 192.168.0.200
from web02 ,RIP 10.4.7.11
(5).修改调度算法和权重
- 将调度算法修改为加权轮询
[root@lvs-server ~]# 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.200:80 rr #调度算法为轮询 -> 10.4.7.10:8080 Masq 1 0 0 #权重为1 -> 10.4.7.11:80 Masq 1 0 0 #权重为1
[root@lvs-server ~]# ipvsadm -E -t 192.168.0.200:80 -s wrr #修改调度算法为加权轮询--wrr
[root@lvs-server ~]# ipvsadm -d -t 192.168.0.200:80 -r 10.4.7.11:80 #删除web02的调度规则
[root@lvs-server ~]# ipvsadm -a -t 192.168.0.200:80 -r 10.4.7.11:80 -m -w 3 #将web02的权重设置为3,即web02被访问3次后,才将流量指向web01
[root@lvs-server ~]# 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.200:80 wrr -> 10.4.7.10:8080 Masq 1 0 0 -> 10.4.7.11:80 Masq 3 0 0
再次访问,此时将联系显示3次web2的文件内容后,再显示web01的文件内容:
[root@192 ~]# curl 192.168.0.200
from web01 ,RIP 10.4.7.10
[root@192 ~]# curl 192.168.0.200
from web02 ,RIP 10.4.7.11
[root@192 ~]# curl 192.168.0.200
from web02 ,RIP 10.4.7.11
[root@192 ~]# curl 192.168.0.200
from web02 ,RIP 10.4.7.11
- 将调度算法修改为源地址hash(SH):将来自同一个IP的请求始终发往第一次挑中的真实服务器IP
[root@lvs-server ~]# ipvsadm -E -t 192.168.0.200:80 -s sh
[root@lvs-server ~]# 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.200:80 sh
-> 10.4.7.10:8080 Masq 1 0 0
-> 10.4.7.11:80 Masq 3 0 0
再次访问:
[root@192 ~]# curl 192.168.0.200 #此时无论访问多少次,都只有web02响应
from web02 ,RIP 10.4.7.11
[root@lvs-server ~]# 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.200:80 sh
-> 10.4.7.10:8080 Masq 1 0 0
-> 10.4.7.11:80 Masq 3 0 16
- 将调度算法修改为目标地址hash(dh):将发往同一个目标地址的请求始终转发至第一次挑中的真实服务器IP
[root@lvs-server ~]# 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.200:80 dh -> 10.4.7.10:8080 Masq 1 0 0 -> 10.4.7.11:80 Masq 3 0 0
[root@192 ~]# curl 192.168.0.200
from web02 ,RIP 10.4.7.11
[root@lvs-server ~]# 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.200:80 dh
-> 10.4.7.10:8080 Masq 1 0 0
-> 10.4.7.11:80 Masq 3 0 14
(6).ipvsadm命令选项
-A --add-service 在内核的虚拟服务器表中添加一条新的虚拟服务器记录。也就是增加一台新的虚拟服务器(VIP)。
-E --edit-service 编辑内核虚拟服务器表中的一条虚拟服务器记录。
-D --delete-service 删除内核虚拟服务器表中的一条虚拟服务器记录。
-C --clear 清除内核虚拟服务器表中的所有记录。
-R --restore 恢复虚拟服务器规则
-S --save 保存虚拟服务器规则,备份输出为-R 选项可读的格式
-a --add-server 在内核虚拟服务器表的一条记录里添加一条新的真实服务器记录(RIP)。也就是在一个虚拟服务器中增加一台新的真实服务器
-e --edit-server 编辑一条虚拟服务器记录中的某条真实服务器记录
-d --delete-server 删除一条虚拟服务器记录中的某条真实服务器记录
-L|-l --list 显示内核虚拟服务器表
-Z --zero 虚拟服务表计数器清零(清空当前的连接数量等)
--set tcp tcpfin udp 设置连接超时值
--start-daemon 启动同步守护进程。他后面可以是master 或backup,用来说明LVS Router 是master 或是backup。在这个功能上也可以采用keepalived 的VRRP 功能。
--stop-daemon 停止同步守护进程
-h --help 显示帮助信息
-p --persistent [timeout] 持久稳固的服务(持久性连接)。这个选项的意思是来自同一个客户的多次请求,将被同一台真实的服务器处理。timeout 的默认值为360 秒。
-t --tcp-service service-address 说明虚拟服务器提供的是tcp 的服务[vip:port] or [real-server-ip:port]
-f --fwmark-service fwmark 说明是经过iptables 标记过的服务类型。
-u --udp-service service-address 说明虚拟服务器提供的是udp 的服务[vip:port] or [real-server-ip:port]
-s --scheduler scheduler 使用的调度算法,有这样几个选项 rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,默认的调度算法是: wlc.
-M --netmask netmask persistent granularity mask
-r --real-server server-address 真实的服务器[Real-Server:port]
-g --gatewaying 指定LVS 的工作模式为DR直接路由模式(也是LVS 默认的模式)
-i --ipip 指定LVS 的工作模式为隧道模式
-m --masquerading 指定LVS 的工作模式为NAT 模式
-w --weight weight 真实服务器的权值
--mcast-interface interface 指定组播的同步接口
-c --connection 显示LVS 目前的连接 如:ipvsadm -L -c
--timeout 显示tcp tcpfin udp 的timeout 值 如:ipvsadm -L --timeout
--daemon 显示同步守护进程状态
--stats 显示统计信息
--rate 显示速率信息
--sort 对虚拟服务器和真实服务器排序输出
-n --numeric 输出IP地址和端口的数字形式