侧边栏壁纸
博主头像
张种恩的技术小栈博主等级

行动起来,活在当下

  • 累计撰写 742 篇文章
  • 累计创建 64 个标签
  • 累计收到 39 条评论

目 录CONTENT

文章目录

哦豁~~~iptables也能做负载均衡???

zze
zze
2020-03-11 / 0 评论 / 0 点赞 / 620 阅读 / 4280 字

不定期更新相关视频,抖音点击左上角加号后扫一扫右方侧边栏二维码关注我~正在更新《Shell其实很简单》系列

刚刚整完 Nginx 四层反向代理,突然想到,iptables 也可以在三四层做网络地址及端口转换(此处可参考 【iptables 系列】),那它肯定也能完成反向代理的功能呀~~

干说无用,赶紧来试试。

在 【Nginx(7)之四、七层反向代理实例】中,我们实现了如下架构配置。
image

那本篇文章我们就基于这个配置继续测试 iptables 啦~~~

在这里我们要使用 iptables 做网络地址转换来顶替原来 A 主机的 Nginx 服务来完成四层反向代理的功能,但是这里有一个问题,在上图中 A 主机完成了 B、C 两个主机的请求调度功能,那按我们之前学习的 【iptables 网络地址转换】的知识,我们也只能把指定的请求分配到单个的目标主机上。

由于这个问题的存在,所以我们先来测试一下代理单个主机试试,下面就先以代理 B 主机为例。


1、停止 A 主机中的 Nginx 服务。

$ systemctl stop nginx

2、开启 A 主机的核心转发功能:

$ sysctl -w net.ipv4.ip_forward=1

3、添加如下规则,将目标地址为 10.0.1.200:80 的请求转发到 B 主机(172.16.1.201:80):

$ iptables -t nat -A PREROUTING -d 10.0.1.200 -p tcp --dport 80 -j DNAT --to-destination 172.16.1.201:80

4、完成上述操作后,我们发往 A 主机 80 端口的请求就能到达 B 主机了,但是 B 主机的响应报文还是走默认网关,所以我们这里就需要将 B 主机的默认网关修改为 A 主机的 172.16.1.200 了,如下:

$ ip route add default via 172.16.1.200
$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.16.1.200    0.0.0.0         UG    0      0        0 eth0
172.16.1.0      0.0.0.0         255.255.255.0   U     101    0        0 eth0

5、此时使用浏览器访问 10.0.1.200,会发现已经正常代理 B 主机了:
2020-03-11 20.39.58


现在 A 主机已经能正常代理 B 主机了,现在就是要想办法让 A 主机能同时代理 B、C 主机并且具有分流功能。

有想法就有办法,继续往下看。。


1、我们先将 C 主机的默认网关也改为 A 主机的 172.16.1.200

$ ip route add default via 172.16.1.200
$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.16.1.200    0.0.0.0         UG    0      0        0 eth0
172.16.1.0      0.0.0.0         255.255.255.0   U     101    0        0 eth0

2、在 A 主机中添加如下规则:

$ iptables -t nat -A PREROUTING -d 10.0.1.200 -p tcp --dport 80 -m statistic --mode nth --every 2 --packet 0 -j DNAT --to-destination 172.16.1.201:80
$ iptables -t nat -A PREROUTING -d 10.0.1.200 -p tcp --dport 80 -m statistic --mode nth --every 1 --packet 0 -j DNAT --to-destination 172.16.1.202:80

3、此时我们再多次使用浏览器访问 10.0.1.200,会发现也实现了负载均衡的功能。
2020-03-11 20.39.58


如果此时你观察 B 主机和 C 主机的访问日志,会发现每隔一段时间它们会轮流被访问,即实现了分流的功能。

我们知道 iptables 是可以查看匹配报文的统计信息的,那我们就看一下我们刚刚添加的两条规则的匹配情况:

$ iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 14 packets, 956 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   30  1920 DNAT       tcp  --  *      *       0.0.0.0/0            10.0.1.200           tcp dpt:80 statistic mode nth every 2 to:172.16.1.201:80
   30  1920 DNAT       tcp  --  *      *       0.0.0.0/0            10.0.1.200           tcp dpt:80 statistic mode nth every 1 to:172.16.1.202:80

会发现,不论我们如何访问,它们匹配的报文数(pkts)逐渐趋于持平状态,是不是很神奇~~~

这里我们使用了一个陌生的模块,那就是 statistic-m statistic):

  • 指定模块的模式是 nth--mode nth);
  • 如果有数据包计数器的话,—every n 指的是每 n 个数据包被当前规则匹配,在上述示例中就是第偶数个数据包被第一条规则匹配,第奇数个数据包被第二条规则匹配;
  • —packet 0 指的是第一个数据包;

所以我们就通过此种方式完成了 iptables 四层分流负载均衡的功能。

该模块详细使用请参考 【statistical packet distribution with iptables】。

0

评论区