Это продолжение предыдущий вопрос я задал, но с другим вопросом/подходом. В случае, если это имеет значение, я использую GKE, но я надеюсь, что есть ответ, не зависящий от облака.
Я пытаюсь запустить контейнер факториоинструменты / факторио
, но у приложения есть некоторые особые требования из-за использования функции списка общедоступных серверов для конкретного приложения, как это видно во многих видеоиграх, в которых используются серверы, размещенные пользователями.
До сих пор мне удавалось наладить работу с хост-сетями и прямыми соединениями для работы со службой NodePort.Однако функция листинга общедоступных серверов приложения остается проблемой для непривилегированных контейнеров.
Вот как Factorio выясняет, как управлять списком общедоступных серверов:
- Контейнер прослушивает один сокет, скажем, UDP-порт 34197.
- Служба NodePort публично направляет этот трафик на 20635.
- Контейнер отправляет эхо-запрос через свой порт прослушивания (34197) на пинг-понг-сервер, а пинг-понг-сервер отвечает IP-адресом и портом, с которого он получил пинг-понг. Вне k8s это будет порт 34197.
- Затем контейнер использует эту информацию для регистрации в списке серверов. IP-адрес, порт, имя сервера и некоторая другая информация.
- В GKE пинг-понг направляется на произвольный неиспользуемый порт (скажем, 40792).
- Контейнер считает, что он прослушивает порт, отличный от того, который я установил (20534), а затем регистрируется в списке общедоступных серверов, используя неправильный порт (40792, потому что так сказал сервер пинг-понга).
- Любая попытка подключения из списка общедоступных серверов завершается неудачно; клиент считает, что сервер прослушивает порт, свидетелем которого является пинг-понг-сервер (40792), но контейнер все время взаимодействовал со своим прослушивающим портом (34197).
(Мне сказали, что этот процесс является разновидностью работы ICE/STUN)
Это означает, что если контейнер прослушивает 34197, но Kubernetes направляет его на 20635 извне, то и входящий, и исходящий трафик должны проходить через 20635 на общедоступной стороне, чтобы встроенная в приложение функция листинга серверов работала.
Если я обойду список общедоступных серверов и подключусь напрямую к общедоступному IP-адресу узла контейнера с портом 20635, он будет работать безупречно. Но это довольно серьезный компромисс для того, чем я занимаюсь.
Сеть хоста обходит всю эту проблему, позволяя контейнеру напрямую открывать любой порт, который он хочет, на хосте.Для хостов, которые уже общедоступны, это означает, что ничто на хосте (особенно не k8s) не может перенаправить трафик контейнера через дополнительные уровни и изменить номера портов. Таким образом, когда контейнер открывает порт 34197, он получает порт 34197. Когда он отправляет на порт 34197, этот трафик отправляется на порт 34197. Сервер пинг-понга видит порт, который он должен видеть. И поскольку это общедоступный порт UDP, не имеет значения, кто первым отправил трафик; трафик это трафик, порт это порт.
Однако, если я правильно понимаю документы, для запуска контейнера в сетевом стеке хоста требуется привилегированный контейнер, который фактически является корневым доступом на хосте, что очень плохо в производстве. Таким образом, для непривилегированных контейнеров должно быть решение, отличное от сети хоста. Я не могу найти это «другое решение».
Я нигде не могу найти документацию о том, как это сделать, или даже доказательства того, что кто-то думает об этом. Как мне заставить это работать?