Назад | Перейти на главную страницу

UDP-сервер за балансировщиком нагрузки Gcloud: получение в порядке, ответ не выполняется

У меня установлен 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 с балансировкой нагрузки.

https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Load_Balancer_Administration/s1-initial-setup-forwarding-VSA.html

/etc/sysctl.conf

 net.ipv4.ip_nonlocal_bind = 1

Затем попытайтесь привязать приложение python к общедоступному IP-адресу балансировщика нагрузки.

По сути, ваш сервер отвечает на свой частный IP-адрес, и клиент ожидает ответа от балансировщика нагрузки.