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