四层负载均衡Nginx

与LVS NAT不同,Nginx负载均衡不需要VIP,客户端直接访问DIP,在由DIP发送给RIP,处理后数据包会原路返回。

0x00 原理

原理图:

  1. 客户端从CIP向DIP+PORT发出请求。
  2. Nginx(DS)接收到客户端的请求后,将数据包源地址修改为自己的DIP,目的地址修改为RIP+PORT,发送给RS。
  3. RS接收到请求后处理完成返回请求到DS,在由DS返回给客户端。

0x01 部署步骤

环境

  • 4台服务器(Ubuntu 22.04.3)在同一局域网内
  • 1台作为LoadBlancer: 192.168.50.126
  • 3台作为后端的业务服务器(Worker1-3)
    • Worker1: 192.168.50.119
    • Worker2: 192.168.50.116
    • Worker3: 192.168.50.48
    • Client: 192.168.50.128

在LoadBlancer上执行以下操作

未安装Nginx的情况下:
准备编译环境

1
2
sudo apt update
sudo apt install -y build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev

下载Nginx源码包

1
2
3
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -xvzf nginx-1.24.0.tar.gz
cd nginx-1.24.0

编译安装

1
2
3
4
5
6
7
8
9
10
11
12
13
./configure --prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--with-http_ssl_module \
--with-stream \
--with-stream_ssl_module

make && sudo make install

安装完成后,修改nginx.conf文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
sudo nano /etc/nginx/nginx.conf
// 注意stream模块和http同级
stream {
upstream backend_servers { // 这里定义了一个名为backend_servers的upstream服务器池
server 192.168.50.119:80;
server 192.168.50.116:80;
server 192.168.50.48:80;
}

server {
listen 80;
proxy_pass backend_servers; // 将请求转发给backend_servers服务器池
}
}

测试配置文件ok后重启

1
2
sudo nginx -t
sudo systemctl restart nginx

0x02 测试

在客户端执行curl http://192.168.50.126/ 默认Nginx 负载均衡算法是轮询。

修改负载均衡为权重模式

1
2
3
server 192.168.50.119:80 weight=3;
server 192.168.50.116:80 weight=2;
server 192.168.50.48:80 weight=1;


可以看到权重高的服务器处理的请求更多
修改算法为IP HASH 模式,用于客户端保持会话,同时计算IP哈希值,为客户端选择服务器。

1
2
3
4
ip_hash;
server 192.168.50.119:80;
server 192.168.50.116:80;
server 192.168.50.48:80;

验证负载均衡的流量轨迹,在LoadBlancer上抓包

1
tcpdump -i enp1s0 port 80 -n -w dump.pcap

如图可知,整个处理请求过程中建立了两次三次握手,首先客户端和DS建立三次握手后发送http请求,然后DS和RS建立三次握手,DS将请求发给RS,RS处理请求后返回数据包给DS,DS再将数据包返回给客户端。

0x03 思考

  • LVS NAT和Nginx 四层负载均衡都是通过LB转发CIP 和 RIP的数据包,为什么LVS NAT必须SNAT而Nginx不需要

    • 因为LVS NAT整个过程中只建立了一次三次握手,RS接受到的数据包源地址是CIP,目的地址是RS自己。RS返回数据包时由于LB时网关所有流量必经LB,这样LB直接返回给客户端的话会出现问题,因为客户端请求的目的地址是VIP,现在直接返回源地址是RIP,客户端会丢弃这个数据包,所以需要LB对数据包源地址修改为VIP,这样才不会造成路径不对称。而Nginx建立了两次三次握手,不用担心数据包不会返回负载均衡。
作者

HXD

发布于

2024-01-23

更新于

2024-11-22

许可协议

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

评论

You need to set client_id and slot_id to show this AD unit. Please set it in _config.yml.