1.1 LVS/NAT模式工作原理
LVS(Linux Virtual Server)的网络地址转换(NAT)模式是一种在网络层(第四层)实现负载均衡的方法。在NAT模式中,Director Server(DS)充当所有服务器节点的网关,既是客户端请求的入口,也是Real Server响应客户端的出口。以下是LVS NAT模式的工作原理:
-
VIP和DIP:DS拥有两个IP地址,一个是外部的VIP(虚拟IP),作为整个集群的对外服务地址;另一个是内部的DIP(Director IP),与后端的Real Server(RS)位于同一个物理网络中。RS通常使用私有IP地址。
-
请求处理:客户端发送的请求数据包(源IP为CIP,即客户端IP;目标IP为VIP)首先到达DS。DS的内核空间检查到目标IP是VIP,IPVS模块判断请求的服务是否属于集群服务。
-
负载均衡:如果是集群服务,DS使用预设的负载均衡算法选择一个RS,并修改请求数据包的目标IP地址为选定的RS的IP(RIP),同时修改源MAC地址为DS的MAC地址,目标MAC地址为RS的MAC地址,然后将数据包发送给RS。
-
RS处理:RS接收到请求后,处理它并准备响应。RS将响应数据包的源IP设置为RIP,目标IP设置为CIP。
-
响应路由:RS将响应数据包发送回DS,DS再次修改数据包,将源IP更改为VIP,然后转发给客户端。
-
NAT转换:在整个过程中,DS作为NAT设备,负责将请求数据包的源IP从客户端IP转换为DS的VIP,并将响应数据包的源IP从RS的私有IP转换回VIP。
1.2 LVS/NAT模式特点
特点 | 描述 |
---|---|
地址转换 | 使用NAT技术将请求的目标IP修改为RS的IP。 |
流量转发 | 请求经LVS处理,响应直接从RS返回给客户端。 |
网关角色 | LVS作为RS的默认网关。 |
IP地址管理 | RS使用私有IP,VIP作为集群的公共IP。 |
性能考虑 | LVS可能成为瓶颈,因为所有流量都经过它。 |
安全性 | 隐藏RS的真实IP,提高安全性。 |
易于配置 | 灵活的配置,LVS和RS不需要在同一个物理网络。 |
适用性 | 适用于多种网络环境,尤其是在RS分布广泛时。 |
健康检查 | LVS提供对RS的健康检查功能。 |
可扩展性 | 通过增加RS数量水平扩展服务能力。 |
透明性 | 对客户端透明,客户端不知道负载均衡的存在。 |
协议支持 | 支持TCP、UDP等协议,适用于多种应用。 |
重点:在LVS中,NAT模式的请求和响应都经过负载调度器,而DR模式的请求经过负载调度器,但响应直接从真实服务器返回给客户端,不经过负载调度器。
1.3 LVS/NAT模式基本配置
机器名称 | IP地址 | 子网掩码 | 说明 |
---|---|---|---|
LVS | 192.168.110.31 | 255.255.255.0 | 负载均衡器 |
RS1 | 192.168.110.32 | 255.255.255.0 | 真实服务器1 |
RS2 | 192.168.110.33 | 255.255.255.0 | 真实服务器2 |
Client | 10.10.10.24 | 255.255.255.0 | 客户端 |
VIP的配置:
VIP名称 | IP地址 | 子网掩码 | 配置位置 |
---|---|---|---|
VIP | 10.10.10.10 | 255.255.255.0 | LVS的ens224 |
1.3.1 网络配置
1.3.1.1 LVS网络配置
手动添加一块网卡!
[root@LVS ~]# nmcli connection add type ethernet ifname ens224 con-name ens224 Connection 'ens224' (862fd4d0-b355-4837-9c0e-b44f65083edb) successfully added. [root@LVS ~]# nmcli connection modify ens224 ipv4.addresses 10.10.10.10/24 ipv4.method manual [root@LVS ~]# nmcli connection up ens224 Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/3) [root@LVS ~]# nmcli connection show NAME UUID TYPE DEVICE ens160 8c508417-bf3f-4c7d-b1f4-671fd135dd99 ethernet ens160 ens224 862fd4d0-b355-4837-9c0e-b44f65083edb ethernet ens224 Wired connection 1 d3eafb69-d94d-36f8-b2ba-fa612d252638 ethernet -- [root@LVS ~]# ip address show ens224 #作为VIP 3: ens224: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 00:0c:29:d1:a9:f5 brd ff:ff:ff:ff:ff:ff altname enp19s0 inet 10.10.10.10/24 brd 10.10.10.255 scope global noprefixroute ens224 valid_lft forever preferred_lft forever inet6 fe80::1c9c:5880:bcb6:4c2e/64 scope link noprefixroute valid_lft forever preferred_lft forever [root@LVS ~]# ip address show ens160 #作为网关 2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 00:0c:29:d1:a9:eb brd ff:ff:ff:ff:ff:ff altname enp3s0 inet 192.168.110.31/24 brd 192.168.110.255 scope global noprefixroute ens160 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fed1:a9eb/64 scope link noprefixroute valid_lft forever preferred_lft forever
1.3.1.2 配置RS网关
1、LVS-RS1
[root@LVS-RS1 ~]# nmcli connection modify ens160 ipv4.gateway 192.168.110.31 #网关为LVS的ens160 [root@LVS-RS1 ~]# nmcli connection up ens160 Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/2) [root@LVS-RS1 ~]# nmcli connection show ens160 | grep IP4.GATEWAY IP4.GATEWAY: 192.168.110.31
2、LVS-RS2
[root@LVS-RS2 ~]# nmcli connection modify ens160 ipv4.gateway 192.168.110.31 [root@LVS-RS2 ~]# nmcli connection up ens160 Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/2) [root@LVS-RS2 ~]# nmcli connection show ens160 | grep IP4.GATEWAY IP4.GATEWAY: 192.168.110.31
1.3.1.3 配置客户端地址(SSH连接会断)
[root@Client ~]# nmcli connection modify ens160 ipv4.addresses 10.10.10.24/24 [root@Client ~]# nmcli connection up ens160 [root@LVS ~]# ssh 10.10.10.24 #复制一个LVS的会话,ssh连接 The authenticity of host '10.10.10.24 (10.10.10.24)' can't be established. ECDSA key fingerprint is SHA256:VZC8CrnTIve72qGMS4toH88Px76O0yQw6TVoFKQtsuY. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes Warning: Permanently added '10.10.10.24' (ECDSA) to the list of known hosts. root@10.10.10.24's password: Activate the web console with: systemctl enable --now cockpit.socket Last login: Fri Apr 26 14:53:04 2024 [root@Client ~]# ip address show ens160 2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 00:0c:29:ed:bb:87 brd ff:ff:ff:ff:ff:ff altname enp3s0 inet 10.10.10.24/24 brd 10.10.10.255 scope global noprefixroute ens160 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:feed:bb87/64 scope link noprefixroute valid_lft forever preferred_lft forever
1.3.2 LVS/NAT配置
1.3.2.1 开启路由转发(临时开启)
[root@LVS ~]# cat /proc/sys/net/ipv4/ip_forward 0 [root@LVS ~]# echo 1 > /proc/sys/net/ipv4/ip_forward [root@LVS ~]# cat /proc/sys/net/ipv4/ip_forward 1
1.3.2.2 LVS配置
[root@LVS ~]# ipvsadm -At 10.10.10.10:80 -s rr [root@LVS ~]# ipvsadm -at 10.10.10.10:80 -r 192.168.110.32 -m #注意-m为指定为nat模式 [root@LVS ~]# ipvsadm -at 10.10.10.10:80 -r 192.168.110.33 -m [root@LVS ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.10.10.10:80 rr -> 192.168.110.32:80 Masq 1 0 0 -> 192.168.110.33:80 Masq 1 0 0
1.3.2.3 客户端访问
[root@Client ~]# for ((i=1;i<=6;i++)); do curl http://10.10.10.10; done
This is LVS test IP=192.168.110.33 Host=LVS-RS2
This is LVS test IP=192.168.110.32 Host=LVS-RS1
This is LVS test IP=192.168.110.33 Host=LVS-RS2
This is LVS test IP=192.168.110.32 Host=LVS-RS1
This is LVS test IP=192.168.110.33 Host=LVS-RS2
This is LVS test IP=192.168.110.32 Host=LVS-RS1
1.3.2.4 修改调度算法
[root@LVS ~]# ipvsadm -Et 10.10.10.10:80 -s wrr [root@LVS ~]# ipvsadm -et 10.10.10.10:80 -r 192.168.110.32 -m -w 1 #-w为指定权重比 [root@LVS ~]# ipvsadm -et 10.10.10.10:80 -r 192.168.110.33 -m -w 2 [root@LVS ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.10.10.10:80 wrr -> 192.168.110.32:80 Masq 1 0 0 -> 192.168.110.33:80 Masq 2 0 0 #客户端访问测试 [root@Client ~]# for ((i=1;i<=6;i++)); do curl http://10.10.10.10; done This is LVS test IP=192.168.110.33 Host=LVS-RS2 This is LVS test IP=192.168.110.32 Host=LVS-RS1 This is LVS test IP=192.168.110.33 Host=LVS-RS2 This is LVS test IP=192.168.110.33 Host=LVS-RS2 This is LVS test IP=192.168.110.32 Host=LVS-RS1 This is LVS test IP=192.168.110.33 Host=LVS-RS2
1.4 配置LVS/NAT服务脚本
1.4.1 清除环境
[root@LVS ~]# ipvsadm -C #清楚服务器列表 [root@LVS ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn
1.4.2 服务脚本
[root@LVS ~]# vim /etc/init.d/LVS_DR #!/bin/bash # Startup script handle the initialisation of LVS # chkconfig: - 28 72 # description: Initialise the Linux Virtual Server for DR # Provides: ipvsadm # Required-Start: $local_fs $network $named # Required-Stop: $local_fs $remote_fs $network # Short-Description: Initialise the Linux Virtual Server # Description: The Linux Virtual Server is a highly scalable and highly # available server built on a cluster of real servers, with the load # balancer running on Linux. LOCK=/var/lock/ipvsadm.lock VIP=10.10.10.10 RIP1=192.168.110.32 RIP2=192.168.110.33 . /etc/rc.d/init.d/functions start() { PID=`ipvsadm -Ln | grep ${VIP} | wc -l` if [ $PID -gt 0 ]; then echo "The LVS-DR Server is already running !" else /sbin/ipvsadm -C /sbin/ipvsadm -At $VIP:80 -s rr /sbin/ipvsadm -at $VIP:80 -r $RIP1:80 -m /sbin/ipvsadm -at $VIP:80 -r $RIP2:80 -m /bin/touch $LOCK echo "starting LVS-DR Server is ok !" fi } stop() { /sbin/ipvsadm -C rm -rf $LOCK echo "stopping LVS-DR server is ok !" } status() { if [ -e $LOCK ]; then echo "The LVS-DR Server is already running !" else echo "The LVS-DR Server is not running !" fi } case "$1" in start) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) echo "Usage: $1 {start|stop|restart|status}" exit 1 esac exit 0 [root@LVS ~]# chmod +x /etc/init.d/LVS_DR [root@LVS ~]# chkconfig --add LVS_DR #添加为系统服务 [root@LVS ~]# systemctl start LVS_DR.service [root@LVS ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.10.10.10:80 rr -> 192.168.110.32:80 Masq 1 0 0 -> 192.168.110.33:80 Masq 1 0 0 [root@LVS ~]# systemctl stop LVS_DR.service #停止 [root@LVS ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn
1.4.3 客户端访问
[root@Client ~]# for ((i=1;i<=6;i++)); do curl http://10.10.10.10; done
This is LVS test IP=192.168.110.33 Host=LVS-RS2
This is LVS test IP=192.168.110.32 Host=LVS-RS1
This is LVS test IP=192.168.110.33 Host=LVS-RS2
This is LVS test IP=192.168.110.32 Host=LVS-RS1
This is LVS test IP=192.168.110.33 Host=LVS-RS2
This is LVS test IP=192.168.110.32 Host=LVS-RS1