-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
I think describing it as steps to reproduce is the easiest way:
Prerequisites:
- Have two public IP addresses on a Node. Described now as IP A and IP B
Steps to reproduce:
- Check if IP A and IP B are reachable (just to make sure)
ping Aping B - Create two Source-Engine servers (TF2). TF2 Server 1 gets IP A assigned, the other one IP B.
- Start both servers.
Console TF2 Server 1:
Connection to Steam servers successful.
Public IP is IP A
Console TF2 Server 2:
Connection to Steam servers successful.
Public IP is IP A
The last output was no typo, even when starting Server 2, which was assigned IP B, it shows public IP is IP A. This problem makes it unable to get the second server to show up in the server list, also it doesn't let you connect (the last one could depend on the networking setup however).
Troubleshooting
Typing in netstat -ant into the ssh console, to show bindings shows:
tcp 0 0 A:27015 0.0.0.0:* LISTEN
tcp 0 0 B:27015 0.0.0.0:* LISTEN
So bindings/allocations were correct.
I looked deeper in the problem. Docker uses NAT to port forward ports into the internal docker subnet. However for SNAT it simply puts a MASQUERADE rule into the iptables. So the servers will always use the first server IP as outgoing IP address. Using SNAT would solve the problem.
There were even merge requests on docker to fix such kind of issues, but they were not included: moby/moby#8731
Suggestion
Don't let docker handle the IP Port forwarding configuration. Instead, create custom rules.
E.g. for SNAT (ports should be also specified, left out for easy understanding): iptables -t nat -A POSTROUTING -s DOCKERIPOFGAMESERVER -j SNAT --to ALLOCATIONIP