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-сервер отвечал на сообщения?

РЕДАКТИРОВАТЬ: эта дискуссия может быть актуальной.

1 ответ

Решение

Мне пришлось столкнуться с аналогичной проблемой для одного из моих проектов для выпускников университетов: балансировка нагрузки 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-адрес, а клиент ожидает ответа от балансировщика нагрузки.