Я реализую службу высокой доступности (HA) с поддержкой активности (VRRP). Предполагается, что этот HA будет работать только для приложения, работающего на порту 443, поэтому мы не переключаем весь сервер, а только приложение должно переключаться.
Чтобы это сработало, я должен заставить все серверы в подсети отправлять данные на виртуальный IP-адрес (VIP) вместо реального IP-адреса сервера, когда запрошенный порт - 443. Для этого примера представьте себе следующее:
Основной сервер - частный IP: 10.101.151.59
Вторичный сервер - частный IP: 10.101.151.9
Виртуальный IP-адрес действителен для обоих серверов: 10.101.251.120
Чтобы сила связь с VIP, когда трафик идет на порт 443, я использовал следующее правило для каждого из серверов в подсети:
iptables -t nat -A OUTPUT -p tcp -d 10.101.151.59 --dport 443 -j DNAT --to-destination 10.101.251.120:443;
Это правило отлично работает, когда VIP не принадлежит серверу, инициирующему запрос. Однако представьте себе ситуацию, когда правило не работает:
1) Приложение вылетает на основном сервере.
2) Происходит отработка отказа, и вторичный сервер начинает получать / обрабатывать запросы, и ему будет принадлежать VIP.
Если это приложение, которое сейчас запущено на вторичном сервере, пытается связаться с самим собой, он отправит запрос на реальный IP-адрес основного сервера, потому что этот IP-адрес собирается автоматически посредством разрешения имен..
Теоретически я ожидал, что этот трафик будет соответствовать правилу iptables, определенному выше.
Однако, как только виртуальный IP-адрес принадлежит самому вторичному серверу, Iptables придется преобразовать реальный IP-адрес в один из локальных IP-адресов сервера, что потребует обратной связи. Проблема в том, что он просто не работает.
На практике трафик действительно идет на основной сервер, и кажется, что это правило никогда не активируется. Поскольку основной сервер не работает, я просто получаю отказ в соединении.
Итак, вопрос: Почему я не вижу эффекта от этого правила, если целевой виртуальный IP-адрес принадлежит тому же серверу, который инициировал запрос? Это потому, что в этом общении может быть задействована петля? будет ли это иметь значение, если задействована обратная петля?
Я знаю, что весь трафик, инициированный FW HOST, будет проходить через цепочку OUTBOUND, поэтому не уверен, почему этого не происходит, очевидно, сначала выполняется маршрутизация. Я читал, что ядро может блокировать перенаправление локального трафика, поэтому я попробовал следующее:
sysctl -w net.ipv4.conf.all.route_localnet=1
Но этого было мало. Я что-нибудь упускаю?
Я использую Red Hat Enterprise Linux Server версии 6.6 (Сантьяго).
Спасибо. Если вопрос не ясен, дайте мне знать.