Assume we have two servers A and B with 'real' and external IPs and we can switch the so called 'failover ip' (W.X.Y.Z) to point to a specific external IP of A or B. This works from the 'outside' and was easily done. As a background: the failover ip is configured as a new entry in /etc/network/interfaces :
auto eth0:0
iface eth0:0 inet static
address W.X.Y.Z
netmask 255.255.255.224
Now let us assume W.X.Y.Z is configured dynamically to use hardware A. Now I call 'curl domain.com' from B and it uses the correct failover ip W.X.Y.Z but then resolves somehow to the wrong external IP B (or localhost?) instead of using the configured one A:
Trying W.X.Y.Z ...
* connect to W.X.Y.Z port 443 failed: Connection refused
* Failed to connect to domain.com port 443: Connection refused
* Closing connection 0
curl: (7) Failed to connect to domain.com port 443: Connection refused
When I start the local nginx it can successfully curl domain.com
Do I need to configure DNS locally somehow? How can I find out more about the DNS chain?
Using mtr just prints domain.com if trying this from server B
Is this related to this question?
The failover IP is W.X.Y.Z and is also the A record of domain.com
The /etc/hosts file for both nodes serverA and serverB looks like:
127.0.0.1 localhost
127.0.1.1 luminarhost
xxx serverA
xxx serverB
The /etc/network/interfaces of serverA
### Hetzner Online AG - installimage
# Loopback device:
auto lo
iface lo inet loopback
# device: eth0
auto eth0
iface eth0 inet static
address xxx
broadcast xxx
netmask xxx
gateway xxx
# default route to access subnet
up route add -net xxx netmask 255.255.255.224 gw xxx eth0
iface eth0 inet6 static
address xxx
netmask xxx
gateway xxx
# failover ip
auto eth0:0
iface eth0:0 inet static
address W.X.Y.Z
netmask 255.255.255.224
and of serverB it is:
### Hetzner Online AG - installimage
# Loopback device:
auto lo
iface lo inet loopback
# device: eth0
auto eth0
iface eth0 inet static
address xxx
broadcast xxx
netmask xxx
gateway xxx
# default route to access subnet
up route add -net xxx netmask 255.255.255.192 gw xxx eth0
iface eth0 inet6 static
address xxx
netmask xxx
gateway xxx
# failover ip
auto eth0:0
iface eth0:0 inet static
address W.X.Y.Z
netmask 255.255.255.224
As promised, here goes my answer:
Full disclosure: I'm not working for Hetzner, but worked for different companies in the past and present who used to colocate hardware at Hetzner.
In case the location inside your profile is correct, and you need support: I'm based in the same city, and could offer a hand, or two.
For all the people who never dealt with Hetzner: They're filtering network access etc., which means, especially regarding their failover IPs (IPs which are usable on different machines to provide some sort of high availability), that they're sending traffic directed to a specific IP to a specific MAC.
If one wants to change the target (the machine) the traffic is directed to, one has to sent a
POST
request to an API which is served viaHTTPS
. The API then validates authentication (which is a username and a corresponding password) and the request, and, if valid, propagates this new config to various routers in the network. This technique is similar to the one used by OVH, a big provider based in France.auto eth0:0
, will set up your failover IP at the interfaceeth0:0
, as soon as the network gets started, normally at boot time. You've got two machines, with the same configuration, so this leads to the situation, that the same IP is active on two different machines (which isn't a no-go, but leads to the situation you're currently dealing with). Just a note: The syntax you're using, aliasing the same interface multiple times, is deprecated (but still working). The "new way" is described inside the Debian wiki (this link) as well, which just assigns multiple IPs to one interface.curl
inside your test case does the following: It resolves the given domain name to an IP, and then tries to connect to this IP at port 443. Because this IP is in any case assigned locally and therefore reachable, the packets never get send out to the network. Ifnginx
(like in your test case) is not running locally at this time, you're just getting connection refused, which is totally fine and valid: "The IP is local, so lets send the traffic there". It will never send the packets to some router, which maybe has the information: "The traffic directed to this IP should go to this machine".auto eth0:0
(but leave the rest of the configuration ofeth0:0
in place) from/etc/network/interfaces
. Doing this, will not assign the IP to the machine. Doing this would be your task (a task of a script), which doesifup eth0:0
(and, again maybe, speaks to the API to ensure the traffic gets routed to the correct machine).We faced the exact same issue of self-looping like @gf_ mentioned.
Following library worked flawlessly to achieve the same.
https://github.com/mrkamel/heartbeat
You can add and delete the floating IP to a remote node by using the hooks/after and hooks/before feature of the above library.
Example hooks/before/sendmail script that sends a slack notifcation and adds floating ip to the machine its switching to.
Example hooks/after/sendmail script that sends a slack notifcation and deletes floating ip that it moved away from
Note:
1. The machine where you are running the heartbeat and the machines where floating IPs are assigned should have password less login using ssh key exchange at first place (Check id_rsa sharing).
2. slacktee.sh library is used to send slack notifications simply.