路漫漫其修远兮,吾将上下而求索。

导航

LVS(NAT)模式原理和实战演练

 

一.LVS简介

        LVSLinux Virtual Server)即Linux虚拟服务器,是1998年5月由章文嵩博士主导的开源项目,是中国国内最早出现的自由软件项目之一。该项目在Linux内核中实现了基于IP的数据请求负载均衡调度方案(侧重点是调度),其体系结构如下图所示,终端互联网用户从外部访问公司的负载均衡服务器,终端用户的Web请求会发送给LVS调度器(即下图中的lvs负载均衡调度器),调度器根据自己预设的算法决定将该请求发送给后端的某台Web服务器,比如,轮询算法可以将外部的请求平均分发给后端的每一台服务器,终端用户访问LVS调度器虽然会被转发到后端真实的服务器,但如果真实服务器连接的是相同的存储,提供的服务也是相同的服务,最终用户不管是访问哪台真实服务器,得到的服务内容都是一样的,整个集群对用户而言都是透明的。最后根据LVS工作模式的不同,真实服务器会选择不同的方式将用户需要的数据发送到终端用户,LVS工作模式分为NAT模式、TUN模式、DR模式,以及fullnat模式(使用较少)。

 

二.基于NATLVS模式

        NATNetwork 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) RIPDIP应在同一网络中,且都为私网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地址和端口的数字形式

 

posted on 2020-03-06 11:28  rushiy  阅读(538)  评论(0编辑  收藏  举报