Как реализовать внешний ingress-сервис для доступа к контейнерам под управлением Docker?
Hi All!
Сразу оговорюсь, что c Docker работаю недавно и возможно многих вещей еще не знаю или не понимаю и путаюсь в терминах, т.ч. прошу не судить строго.
Суть проблемы в следующем. Есть комп на нем установлен Docker и поднято некоторое количество контейнеров, как самостоятельно через docker run, так и группой через docker compose с собственной сетью и т.д. Сейчас экспериментируем с Docker Swarm Mode, чтобы делать подобное уже на нескольких компах. Хотелось бы "изолировать" все это хозяйство так, чтобы была одна точка входа (ingress-сервис, если я все правильно понял), которая бы обеспечила доступ ко всем этим "внутренним" сервисам на основе dns-имени. Видится это как-то так, при старте контейнера "описываются некоторые метаданные", которые определяют его "dns-имя" и порты, а ingress-сервис автоматически эту информацию обрабатывает и перенаправляет трафик "из вне" в конкретному контейнеру.
Сразу оговорюсь, что я читал о Traefik proxy или Nginx в режиме обратного proxy, но все это работает только для протоколов http или https (в последнем не совсем уверен), когда в самом протоколе есть ключевой параметр Host, который и позволяет "разрулить проблему".
Я же говорю о любом сервисе, например, smtp. Пусть есть два совершенно разных docker-контейнера, каждый из которых открывает наружу порт 25/tcp, но один контейнер это server1, а второй server2. Соответственно, хотелось бы иметь возможность снаружи указать адрес server1.docker.company.tld порт 25/tcp или server2.docker.company.tld порт 25/tcp и чтобы "внешний клиент" "понял", что нужно обратиться на ingress-сервис, а тот в свою очередь понял, что нужно направить весь этот трафик в контейнер server1 или server2 соответственно.
Если честно, то я сам пока не представляю, возможно ли решение проблемы при такой постановке в принципе... Тут нужно как-то реализовать связку "динамического" dns-сервера и ip-маршрутизатора, которые бы перенаправляли трафик к нужным контейнерам.
Сейчас мне приходится для каждого нового контейнера "придумывать" очередной новый порт, чтобы пробросить наружу. Это конечно работает, но выглядит коряво, плюс я уже сам начинаю путаться какой порт куда пробросил.
"server1.docker.company.tld порт 25/tcp и server2.docker.company.tld порт 25/tcp" - при отсутствии возможности разделения запросов, аналогичного заголовку Host в HTTP, эти два сервиса должны резолвиться в разные IP-адреса, либо слушать на разных портах. Либо (но так делают относительно редко) нужна маршрутизация на основании источника. В любом случае - это требует сетевой инфраструктуры.
Что бы "не придумывать каждый раз новый порт", используют инстансы соответствующих сервисов, выставленные наружу и умеющие маршрутизировать запросы уже на уровне приложения. Для HTTP это ингресс, для SMTP - сервер входящей почты и т. д. От этого никуда не денешься.
Вы не правильно поняли - во-первых ingress это сущность кластера kubernetes и к docker отношения не имеет, даже как термин.
Во-вторых - и traefik и nginx и большинство load balancers\reverse proxy умеют проксировать любой tcp трафик, а не только http. Их можно использовать и для smtp трафика в том числе.
Вы не правильно поняли - во-первых ingress это сущность кластера kubernetes и к docker отношения не имеет, даже как термин.
Вы совершенно правы, я просто хотел как-то описать некий сервис, который находится на границе "внешней" и "внутренней" сетей и перенаправляет внешний трафик к конкретному контейнеру docker...
Во-вторых - и traefik и nginx и большинство load balancers\reverse proxy умеют проксировать любой tcp трафик, а не только http. Их можно использовать и для smtp трафика в том числе.
Я тоже на это надеялся, но могу представить, как с помощью того же traefik реализовать тот кейс, который описан в исходном вопросе (с двумя smtp-сервисами внутри docker окружения). Вы можете подробнее описать, как сделать такие настройки?
Дмитрий Иванов, для smtp возможно удобнее использовать smtp relay сервер, но можно и балансировщиком\реверспрокси. Подход стандартный - форвард пакетов с smtp порта по DNS имени на разные почтовые серверы в контейренах, плюс дополнительные настройки SPF\PTR\DKIM\DMARC, если это необходимо.
Alexey Dmitriev, Про "smtp relay сервер" идея понятна... А вот со вторым вариантом "балансировщиком\реверспрокси", можно поподробнее?
Вот установлен этот "балансировщик" на "внешнем интерфейсе" и виден, как ip X.X.X.X. Пусть в DNS есть две записи о server1.docker.company.tld и server2.docker.company.tld, обе указывают на ip X.X.X.X (или как?).
Далее, есть какой-то клиент, который хочет соединиться с smtp-сервером server1.docker.company.tld по порту 25/tcp. Этот клиент, вначале обращается к DNS-серверу для разрешения имени и получает ip-адрес X.X.X.X в ответ. После этого пытается установить tcp-соединение с ip-адресом X.X.X.X и портом 25/tcp. Как "балансировщик" в таком случае поймет, что эту попытку соединения нужно отфорвардить именно на server1.docker.company.tld? Или я вас неправильно понял?
Дмитрий Иванов, это хороший вопрос - к сожалению, я не знаю передается ли какая-то информация об имени домена в smtp трафике и соответственно сможет ли ли прокси делать редирект по этому имени на разные серверы.
Поэтому возможно для smtp остается только relay