Load balancing with IPtables

2

I'm running 2 nginx docker containers on the same EC2 instance in AWS. The containers are using the container port 80. The first container has an IP address 172.17.0.2 and is mapped to port 81 of the host and the 2nd container has an IP address of 172.17.0.3 and is mapped to port 82 on the host. I wish to setup load balancing using iptables and not using swarm or kubernetes.

I set the following rules:

iptables -A PREROUTING -t nat -i eth0 -p tcp -d 0.0.0.0/0 --dport 80 -m statistic --mode nth --every 3 --packet 0 -j DNAT --to-destination 172.17.0.2:81
iptables -A PREROUTING -t nat -i eth0 -p tcp -d 0.0.0.0/0 --dport 80 -m statistic --mode nth --every 3 --packet 0 -j DNAT --to-destination 172.17.0.3:82

However, I'm not able to connect on port 80 of the host IP but am able to connect with port 81 and 82.

All my iptable rules can be found here: https://paste.ubuntu.com/p/V9gJZqHYGd/

Output of tcpdump shows that the packets are being replied to, but on the client end a connection refused error is given.

[root@ip-172-31-30-129 ~]# tcpdump -i any port 80 -nn
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes

19:12:37.229013 IP 37.228.249.144.31060 > 172.31.30.129.80: Flags [S], seq 573169062, win 29200, options [mss 1420,sackOK,TS val 439057061 ecr 0,nop,wscale 7], length 0
19:12:37.229117 IP 172.31.30.129.80 > 37.228.249.144.31060: Flags [R.], seq 0, ack 573169063, win 0, length 0

Any help will be really appreciated.

Regards,

Rohan Dsouza

Posted 2019-05-31T19:04:58.580

Reputation: 31

You can’t load balance TCP connections on the packet level. You need to work with connections. – Daniel B – 2019-05-31T19:43:18.037

1

I guess you can. Found this article: https://scalingo.com/articles/2018/04/20/iptables.html

– Rohan Dsouza – 2019-05-31T20:26:13.780

@DanielB The trick here is of course that linux NAT as enabled by iptables uses conntrack (the connection tracker kernel module), so it does work on the connection level (because on the packet level it indeed wouldn't work). – dirkt – 2019-06-01T06:54:55.733

Answers

1

I was making a rather silly mistake with the PORT number associated with the containers. The correct IP tables rules are the following:

iptables -A PREROUTING -t nat -i eth0 -p tcp -d 0.0.0.0/0 --dport 80 -m statistic --mode nth --every 3 --packet 0 -j DNAT --to-destination 172.17.0.2:80
iptables -A PREROUTING -t nat -i eth0 -p tcp -d 0.0.0.0/0 --dport 80 -m statistic --mode nth --every 3 --packet 0 -j DNAT --to-destination 172.17.0.3:80

Thanks.

Rohan Dsouza

Posted 2019-05-31T19:04:58.580

Reputation: 31