У меня установлен UDP-сервер (на виртуальной машине) за балансировщиком сетевой нагрузки Google Cloud. Сервер привязан к 0.0.0.0
. Сервер UDP может получить сообщения, которые были отправлены на балансировщик, но ответы не возвращаются клиенту. Нет сообщений об ошибках, и tcpdump
не показывает ничего необычного. Я убедился, что все правила брандмауэра разрешают этот трафик, а балансировщик нагрузки настроен на пересылку всех портов.
Я ни в коем случае не специалист по сетям, но я подозреваемый что что-то не так с UDP-сервером в том, что адрес, по которому получено сообщение, отличается от того, который используется для ответа (sendto()
).
Я тестирую все это с помощью Python socketserver
модуль в стандартной библиотеке как эхо-сервер:
import SocketServer
class MyUDPHandler(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request[0].strip()
socket = self.request[1]
print "{} wrote:".format(self.client_address[0])
print data
socket.sendto(data.upper(), self.client_address)
if __name__ == "__main__":
HOST, PORT = "0.0.0.0", 5029
server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler)
server.serve_forever()
Виртуальная машина имеет только один сетевой интерфейс с локальным IP-адресом. 10.240.x.x
. Если я привяжу UDPServer к этому локальному IP, сообщения даже не будут получены этим сервером.
Без балансировщика нагрузки все работает нормально, т.е. сообщения возвращаются клиенту правильно.
Вопрос: Что мне делать, чтобы мой UDP-сервер отвечал на сообщения?
РЕДАКТИРОВАТЬ: это обсуждение может быть актуальным.
Мне пришлось столкнуться с аналогичной проблемой в одном из моих студенческих проектов: DNS с балансировкой нагрузки.
/etc/sysctl.conf
net.ipv4.ip_nonlocal_bind = 1
Затем попытайтесь привязать приложение python к общедоступному IP-адресу балансировщика нагрузки.
По сути, ваш сервер отвечает на свой частный IP-адрес, и клиент ожидает ответа от балансировщика нагрузки.