Экспонировать каждый модуль в statefulset в Интернете без собственного прокси
У меня есть StatefulSet со стручками server-0
, server-1
и т. д. Я хочу предоставить их напрямую в Интернет с помощью таких URL-адресов, как server-0.mydomain.com или mydomain.com/server-0.
Я хочу иметь возможность масштабировать StatefulSet и автоматически иметь доступ к новым модулям из Интернета. Например, если я увеличу масштаб, чтобы включить server-2
Я хочу, чтобы mydomain.com/server-2 направлял запросы к новому модулю, когда он будет готов. Я не хочу также масштабировать какой-либо другой ресурс или создавать другую Службу для достижения этого эффекта.
Я мог бы добиться этого с помощью собственной прокси-службы, которая просто проверяет путь запроса и перенаправляет его в нужный модуль, но это кажется подверженным ошибкам и расточительным.
Есть ли способ заставить Ingress автоматически маршрутизировать различные модули в StatefulSet, или какой-либо другой встроенный метод, который позволит избежать пользовательского кода?
2 ответа
Я не думаю, что вы можете сделать это. Будучи частью одного и того же StatefulSet, все модули, вплоть до pod-x, предназначены для службы. Так как вы не можете определить, какой модуль будет получать запрос, вы не можете принудительно отправить pod-1.yourapp.com или yourapp.com/pod-1. Он будет отправлен в службу, и служба может отправить его в pod-4.
Даже если бы вы могли, вам нужно было бы динамически обновлять ваши правила входа, что может легко привести к простоям в несколько минут.
С пользовательским прокси я тоже это вижу. Обратите внимание, что это должно было бы в основном заменить службу позади стручков. Если ваш входной контроллер знает, что ему нужно доставить пакет в службу, теперь вы должны заставить его доставить свой прокси-сервер. Но как?
Услуга Kubernetes - это набор правил iptables (или IPVS), которые перенаправляют пакет с ServiceIP в качестве адреса назначения на ОДИН ИЗ ПАК, имеющих одинаковую метку.
из сервисной документации Kubernetes
Сервис устанавливает правила iptables, которые выбирают бэкэнд Pod. По умолчанию выбор бэкэнда является случайным.
Который относится к тому факту, что служба не может различать разные модули в одном наборе.
Если вы хотите принудительно выбрать конкретный Pod из набора, изменив iprules (довольно просто) или добавив прокси-сервер любого типа, проблематично: допустим, вы настроили pod-1
а также pod-2
(1.1.1.1
а также 1.1.1.2
соответственно), и вы настроили правила iptables для запросов DNAT с назначением pod-1.myserver.com
в 1.1.1.1
и то же самое для pod-2. (вы можете спросить, почему IP, и это просто потому, что это единственный способ различить эти модули). Этот подход не будет работать всякий раз, когда модуль перезапускается, скажем, сбой модуля 1, Kubernetes не будет воссоздавать тот же модуль с тем же IP и name, вместо этого создаст pod-3 с другим IP и обновит iptables соответственно. В результате все пакеты, идущие к 1.1.1.1, будут отброшены, пока вы не обновите прокси или iptables снова.
Фактически, это одна из причин, по которой мы используем сервис для доступа к модулям вместо прямого доступа к ним, поскольку IP-адрес модуля может меняться, а IP-адрес службы - нет.
Однако, так как эта очень специфическая часть kubernetes была моей работой в течение последних 4 месяцев, я разработал скрипт на python для редактирования iptables и выбора конкретного модуля, поэтому я пришел к выводу, что эта работа была дорогостоящей и отнимающей много времени и будет навязывать Когда сервер меняется на несколько секунд, когда меняются модули, вы можете взглянуть на код, он определенно работает, но его не рекомендуется.
Эта проблема - проблема kubernetes, и решение - изменить исходный код Kube-прокси, который является моей текущей работой.
Я предлагаю вам прочитать мой ответ, объясняющий, как именно работают сервисы kubernetes в этом вопросе: какой сервис выполняет балансировку нагрузки между узлами kubernetes?