环境:Amazon EC2 m4.4xlarge,运行 Amazon Linux 2 AMI 2.0
我想使用 iptables 在分配给连接到同一实例的多个 Amazon 弹性网络接口的一组弹性 IP 之间对 https 请求进行负载平衡。
我有一个负载均衡器,它使用 SNAT 后路由方案为单个网络接口工作,该方案在分配给实例的所有 IP 地址之间进行循环。nat 表看起来像
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT tcp -- anywhere anywhere statistic mode nth every 5 tcp dpt:https to:xxx.xxx.xxx.xx5
SNAT tcp -- anywhere anywhere statistic mode nth every 4 tcp dpt:https to:xxx.xxx.xxx.xx4
SNAT tcp -- anywhere anywhere statistic mode nth every 3 tcp dpt:https to:xxx.xxx.xxx.xx3
SNAT tcp -- anywhere anywhere statistic mode nth every 2 tcp dpt:https to:xxx.xxx.xxx.xx2
到目前为止,我在多个 IP 之间进行平衡所采用的方法是标记输出 mangle 表中的数据包,根据防火墙标记将策略路由到网络接口,然后在接口上进行循环。以下是表格:
MANGLE:
Chain OUTPUT (policy ACCEPT 1518K packets, 63M bytes)
pkts bytes target prot opt in out source destination
21 6007 CONNMARK tcp -- any any anywhere anywhere tcp dpt:https CONNMARK restore
4 240 MARK tcp -- any any anywhere anywhere tcp dpt:https connmark match 0x1 MARK set 0x1
4 240 MARK tcp -- any any anywhere anywhere tcp dpt:https connmark match 0x2 MARK set 0x2
4 240 MARK tcp -- any any anywhere anywhere tcp dpt:https connmark match 0x3 MARK set 0x3
12 720 RETURN tcp -- any any anywhere anywhere tcp dpt:https connmark match ! 0x0
3 180 MARK tcp -- any any anywhere anywhere statistic mode nth every 3 tcp dpt:https MARK set 0x3
3 180 CONNMARK tcp -- any any anywhere anywhere statistic mode nth every 3 tcp dpt:https CONNMARK set 0x3
3 180 CONNMARK tcp -- any any anywhere anywhere statistic mode nth every 3 tcp dpt:https CONNMARK save
3 180 RETURN tcp -- any any anywhere anywhere statistic mode nth every 3 tcp dpt:https
3 180 MARK tcp -- any any anywhere anywhere statistic mode nth every 2 tcp dpt:https MARK set 0x2
3 180 CONNMARK tcp -- any any anywhere anywhere statistic mode nth every 2 tcp dpt:https CONNMARK set 0x2
3 180 CONNMARK tcp -- any any anywhere anywhere statistic mode nth every 2 tcp dpt:https CONNMARK save
3 180 RETURN tcp -- any any anywhere anywhere statistic mode nth every 2 tcp dpt:https
3 180 MARK tcp -- any any anywhere anywhere statistic mode nth every 1 tcp dpt:https MARK set 0x1
3 180 CONNMARK tcp -- any any anywhere anywhere statistic mode nth every 1 tcp dpt:https CONNMARK set 0x1
3 180 CONNMARK tcp -- any any anywhere anywhere statistic mode nth every 1 tcp dpt:https CONNMARK save
3 180 RETURN tcp -- any any anywhere anywhere statistic mode nth every 1 tcp dpt:https
NAT
Chain POSTROUTING (policy ACCEPT 44028 packets, 3373K bytes)
pkts bytes target prot opt in out source destination
1 60 SNAT tcp -- any eth0 anywhere anywhere statistic mode nth every 2 tcp dpt:https to:xxx.xxx.xxx.xxx2
1 60 SNAT tcp -- any eth0 anywhere anywhere statistic mode nth every 3 tcp dpt:https to:xxx.xxx.xxx.xxx3
1 60 SNAT tcp -- any eth0 anywhere anywhere statistic mode nth every 4 tcp dpt:https to:xxx.xxx.xxx.xxx4
0 0 SNAT tcp -- any eth0 anywhere anywhere statistic mode nth every 5 tcp dpt:https to:xxx.xxx.xxx.xxx5
0 0 SNAT tcp -- any eth0 anywhere anywhere statistic mode nth every 6 tcp dpt:https to:xxx.xxx.xxx.xxx6
1 60 SNAT tcp -- any eth1 anywhere anywhere statistic mode nth every 2 tcp dpt:https to:xxx.xxx.xxx.xx12
1 60 SNAT tcp -- any eth1 anywhere anywhere statistic mode nth every 3 tcp dpt:https to:xxx.xxx.xxx.xx13
1 60 SNAT tcp -- any eth1 anywhere anywhere statistic mode nth every 4 tcp dpt:https to:xxx.xxx.xxx.xx14
0 0 SNAT tcp -- any eth1 anywhere anywhere statistic mode nth every 5 tcp dpt:https to:xxx.xxx.xxx.xx15
0 0 SNAT tcp -- any eth1 anywhere anywhere statistic mode nth every 6 tcp dpt:https to:xxx.xxx.xxx.xx16
1 60 SNAT tcp -- any eth2 anywhere anywhere statistic mode nth every 2 tcp dpt:https to:xxx.xxx.xxx.xx22
1 60 SNAT tcp -- any eth2 anywhere anywhere statistic mode nth every 3 tcp dpt:https to:xxx.xxx.xxx.xx23
1 60 SNAT tcp -- any eth2 anywhere anywhere statistic mode nth every 4 tcp dpt:https to:xxx.xxx.xxx.xx24
0 0 SNAT tcp -- any eth2 anywhere anywhere statistic mode nth every 5 tcp dpt:https to:xxx.xxx.xxx.xx25
0 0 SNAT tcp -- any eth2 anywhere anywhere statistic mode nth every 6 tcp dpt:https to:xxx.xxx.xxx.xx26
输出ip rule
:
0: from all lookup local
32501: from all fwmark 0x2 lookup if2
32501: from all fwmark 0x1 lookup if1
32602: from xxx.xxx.xxx.x12 lookup 10001
32603: from xxx.xxx.xxx.x13 lookup 10001
32604: from xxx.xxx.xxx.x14 lookup 10001
32605: from xxx.xxx.xxx.x15 lookup 10001
32606: from xxx.xxx.xxx.x16 lookup 10001
32612: from xxx.xxx.xxx.x22 lookup 10002
32613: from xxx.xxx.xxx.x23 lookup 10002
32614: from xxx.xxx.xxx.x24 lookup 10002
32615: from xxx.xxx.xxx.x25 lookup 10002
32616: from xxx.xxx.xxx.x26 lookup 10002
lookup 1000x
附加 ENI 时,所有规则均由亚马逊自动添加。fwmark
规则是我自己添加的。
if1 和 if2 看起来像这样:
default via yyy.yyy.yyy.yyy dev eth2
yyy.yyy.yyy.0/20 dev eth2 scope link
我正在进行的测试成功了,curl https://ifconfig.me
大约 1/3 的请求都成功了。我猜这是因为我们在默认eth0
接口上接收了数据包,默认接口知道如何正确处理数据包。
其余 2/3 的请求只是无限期地挂起。值得注意的是,传出的数据包击中了这些表,并且似乎做了正确的事情(即 SNAT 规则正在更改传出数据包的源 IP 地址)。这困扰了我一段时间。