Как работает публикация портов из контейнера докеров в модуль кубернетов?

Во время работы над руководством Начало работы, Часть 3: Развертывание в Kubernetes я споткнулся шаблон Pod в определении развертывания файла манифеста. Не указаны порты ни в модуле, ни в разделе контейнера.

Это привело меня к моему первоначальному вопросу: как публикация портов работает из контейнера докеров в модуле?

Следующая цитата звучит так, будто kubernetes получает представление о запущенном контейнере после запуска и получает порт от службы, прослушивающей 0.0.0.0:PORT, и сопоставляет его с тем же портом в среде пода (сетевое пространство имен).

Отсутствие указания порта здесь НЕ ПРЕДОСТАВЛЯЕТ доступ к этому порту. Любой порт, который прослушивает адрес по умолчанию «0.0.0.0» внутри контейнера, будет доступен из сети. Источник

Если мое предположение идет в правильном направлении, что это означает для модулей с несколькими контейнерами? Кубернетес разрешает только контейнеры с внутренними службами, прослушивающими разные порты? Или можно сопоставить внутренние порты контейнера с разными портами в среде модуля (сетевое пространство имен)?

Согласно следующей цитате, я предполагаю, что сопоставление портов от контейнера к модулю невозможно. На самом деле нет особого смысла указывать две службы в двух контейнерах с одними и теми же портами, просто чтобы изменить их с помощью сопоставления, которое следует сразу после этого.

Открытие порта здесь дает системе дополнительную информацию о сетевых соединениях, используемых контейнером, но в первую очередь носит информационный характер. Источник


ОБНОВЛЕНИЕ 15.10.2019

Как указано в следующей цитате, контейнер докеров по умолчанию не публикует порт для внешнего мира.

По умолчанию, когда вы создаете контейнер, он не публикует ни один из своих портов для внешнего мира. Чтобы сделать порт доступным для служб за пределами Docker или для контейнеров Docker, которые не подключены к сети контейнера, используйте флаг --publish или -p. Источник

Это означает, что kubernetes должен каким-то образом настроить контейнер докеров, работающий внутри модуля, чтобы порты контейнера публиковались в модуле.

Что касается следующей цитаты, возможно ли, что Kubernetes запускает контейнеры докеров, используя конфигурацию --network host? Предполагается, что модуль является хостом докеров в кубернетах.

Если вы используете сетевой режим хоста для контейнера, сетевой стек этого контейнера не изолирован от хоста Docker [...] Например, если вы запускаете контейнер, который привязывается к порту 80, и вы используете сеть хоста, приложение контейнера доступен на порту 80 на IP-адресе хоста. Источник


person Chris    schedule 10.10.2019    source источник


Ответы (1)


Контейнеры, работающие в модуле, похожи на процессы, выполняемые на узле, подключенном к сети. Pod получает сетевой адрес, и все контейнеры используют один и тот же сетевой адрес. Они могут разговаривать друг с другом, используя localhost.

Контейнер, работающий в модуле, может прослушивать любой порт по этому адресу. Если в модуле запущено несколько контейнеров, они не могут связываться с одним и тем же портом, только один из них может. Обратите внимание, что публикация этих портов не требуется. Контейнер может прослушивать любой порт, и трафик будет доставлен ему, если клиент подключится к этому порту модуля.

Таким образом, сопоставление портов от контейнера к модулю невозможно.

Открытые порты контейнеров / подов в основном информационные, и инструменты используют их для создания ресурсов.

person Burak Serdar    schedule 10.10.2019
comment
Спасибо за ваш ответ. Вы укрепили мое понимание того, что происходит в Pod и как работает Pod-Conteiner-Interaction. Но из чистой перспективы контейнера Docker, где публикация порта необходима для адресации службы, запущенной в контейнере, все еще не ясно, как kubernetes делает внутреннюю службу контекера (в соответствии с ее портом) доступной изнутри Pod (соответственно внешней части Pod). ). - person Chris; 13.10.2019
comment
@Chris, поправьте меня, если я ошибаюсь, но, насколько я знаю, вам вообще не нужно открывать порты. Модуль может иметь несколько контейнеров, все они используют одно и то же пространство имен, поэтому, когда внешний процесс подключается к порту на модуле, этот трафик доставляется в связанный контейнер, прослушивающий этот порт. У модуля есть собственный IP-адрес, и каждый контейнер привязывается к определенному набору портов на этом IP-адресе. Вы по-прежнему можете подключиться к любому порту на этом модуле, даже если он не открыт, с помощью модуля ip: pod. Это не имеет ничего общего с k8s, так работают контейнеры и пространства имен. - person Burak Serdar; 13.10.2019
comment
насколько я знаю, вы должны явно публиковать порты контейнера докеров (например, docker run -p 80:80 ...). В противном случае у вас не было бы доступа к внутреннему сервису. Мой вопрос касается того, что происходит в фоновом режиме в кубернетах при запуске пода. - person Chris; 15.10.2019
comment
@Chris -p сопоставит порты контейнера с портами хоста. без флага -p вы все равно можете подключиться к портам контейнера с помощью containerip: port. -p позволит вам получить доступ, используя localhost: port. - person Burak Serdar; 15.10.2019
comment
Я протестировал это с помощью образа / контейнера Начало работы, часть 2: Создание контейнера для приложения. Сначала я попробовал контейнер с публикацией портов, как указано. Затем я удалил часть --publish 8000: 8080 и попытался получить доступ к внутренней службе с помощью CONTAINER_IP: PORT. Это не сработало. - person Chris; 17.10.2019
comment
Я тестировал это на Ubuntu 18.04.3 LTS. - person Chris; 17.10.2019
comment
@Chris, когда я говорю exposing ports, я имею в виду выражение EXPOSE в Dockerfile. Я следил за этой частью 2, построил тот же контейнер и запустил изображение без --publish, и я могу нормально подключиться с: curl 172.17.0.2:8080. Обратите внимание, что IP - это IP-адрес контейнера, который вы получаете с помощью docker inspect, а порт - 8080, а не 8000. - person Burak Serdar; 17.10.2019
comment
это странно. Я действительно это сделал. Я осмотрел контейнер и попытался подключиться к IP-адресу контейнера и порту 8080. - person Chris; 17.10.2019
comment
@Chris, можно ли подключиться к containerip: 8080 при публикации порта? - person Burak Serdar; 17.10.2019
comment
нет, я не могу подключиться к CONTAINER_IP: 8080 или CONTAINER_IP: 8000 при публикации порта. Я могу подключиться только через localhost: 8000. Моя версия докера - 19.03.3. Операционная система - Ubuntu 18.04.3 LTS, работающая на виртуальной машине VirtualBox. - person Chris; 18.10.2019
comment
@Chris, в этом случае я предполагаю, что ваша сетевая настройка отличается от моей, в которой используется мост. Кажется, у вас вообще нет доступа к сети докеров. Если у вас есть доступ к сети докеров, вы сможете подключить эти порты. - person Burak Serdar; 18.10.2019
comment
извините за задержку, мой компьютер сломался. Когда я публикую порты, я могу получить доступ к службам в контейнерах докеров. Я также могу получить доступ к службам в контейнерах докеров без публикации портов, когда я запускаю контейнер с установленной конфигурацией --network host. - person Chris; 23.10.2019
comment
В сети хоста контейнеры находятся в той же сети, что и хост. Если вы не укажете --network, тогда он должен создавать мост между хост-сетью и контейнерной сетью. Посмотрите, настроены ли у вас маршруты на вашем хосте для доступа к сети контейнеров, когда вы начинаете с сети по умолчанию. Если у вас нет маршрута к контейнерной сети, вы не можете получить доступ к портам. - person Burak Serdar; 23.10.2019
comment
ты был совершенно прав. Я установил новую виртуальную машину и переустановил докер. Теперь я могу получить доступ к службе в контейнере через CONTAINER_IP: 8080. - person Chris; 23.10.2019