使用 iptables 在多个 AWS 弹性网络接口之间进行负载平衡

使用 iptables 在多个 AWS 弹性网络接口之间进行负载平衡

环境: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 地址)。这困扰了我一段时间。

相关内容