Что действительно делает опция --net = host в команде Docker?

Я немного начинаю Докер. Я не мог найти четкого описания того, что этот параметр делает в команде запуска docker в глубоком и немного запутанном.

Можем ли мы использовать его для доступа к приложениям, работающим на контейнерах докеров, без указания порта? В качестве примера, если я запустил webapp, развернутый через изображение докеров в порту 8080, используя команду -p 8080:8080 в команде запуска docker, я знаю, что мне нужно будет получить к ней доступ на порт 8080 на контейнерах Docker ip/theWebAppName. Но я не могу представить, как работает --net=host.

Ответ 1

После установки докеров вы имеете по умолчанию 3 сети:

docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
f3be8b1ef7ce        bridge              bridge              local
fbff927877c1        host                host                local
023bb5940080        none                null                local

Я пытаюсь сохранить это просто. Поэтому, если вы запускаете контейнер по умолчанию, он будет создан внутри сети моста (docker0).

$ docker run -d jenkins
1498e581cdba        jenkins             "/bin/tini -- /usr..."   3 minutes ago       Up 3 minutes        8080/tcp, 50000/tcp   friendly_bell

В dockerfile jenkins отображаются порты 8080 и 50000. Эти порты открыты для контейнера в сети моста. Таким образом, все внутри этой сети моста может получить доступ к контейнеру на порту 8080 и 50000. Все в сети моста находится в закрытом диапазоне "Subnet": "172.17.0.0/16",. Если вы хотите получить к ним доступ извне, вам нужно сопоставить порты с -p 8080:8080. Это отобразит порт вашего контейнера в порт вашего реального сервера (хост-сети). Таким образом, доступ к вашему серверу на 8080 будет маршрутизироваться в ваш bridgenetwork на порту 8080.

Теперь у вас также есть хост-сеть. Что не позволяет контейнеризировать сети. Поэтому, если вы запустите контейнер в сети хоста, он будет выглядеть так (это первый):

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
1efd834949b2        jenkins             "/bin/tini -- /usr..."   6 minutes ago       Up 6 minutes                              eloquent_panini
1498e581cdba        jenkins             "/bin/tini -- /usr..."   10 minutes ago      Up 10 minutes       8080/tcp, 50000/tcp   friendly_bell

Разница с портами. Теперь ваш контейнер находится внутри вашей сети хоста. Поэтому, если вы откроете порт 8080 на своем хосте, вы сразу же получите контейнер.

$ sudo iptables -I INPUT 5 -p tcp -m tcp --dport 8080 -j ACCEPT

Я открыл порт 8080 в своем брандмауэре, и когда я теперь подключаюсь к своему серверу на порту 8080, я получаю доступ к моим jenkins. Я думаю, этот блог также полезен, чтобы понять его лучше.

Ответ 2

Опция --net=host используется для того, чтобы программы внутри контейнера Docker выглядели так, как будто они работают на самом хосте, с точки зрения сети. Он обеспечивает контейнеру больший доступ к сети, чем он может получить.

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

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

Например, если вы хотите запустить сервер DHCP, вам нужно иметь возможность прослушивать широковещательный трафик в сети и извлекать MAC-адрес из пакета. Эта информация теряется в процессе переадресации портов, поэтому единственный способ запустить DHCP-сервер в Docker - запустить контейнер как --net=host.

Вообще говоря, --net=host нужен только тогда, когда вы запускаете программы с очень специфическими, необычными сетевыми потребностями.

Наконец, с точки зрения безопасности контейнеры Docker могут прослушивать множество портов, даже если они объявляют (выставляют) только один порт. Обычно это нормально, поскольку вы перенаправляете только один ожидаемый порт, однако если вы используете --host=net, вы получите все порты контейнера, прослушивающие хост, даже те, которые не перечислены в Dockerfile. Это означает, что вам необходимо внимательно проверить контейнер (особенно если он не ваш, например, официальный, предоставленный программным проектом), чтобы убедиться, что вы случайно не предоставили дополнительные услуги на машине.

Ответ 3

  1. Вы можете создать свою собственную новую сеть, например --net = "anyname"
  2. это сделано, чтобы изолировать сервисы от другого контейнера.
  3. Предположим, что один и тот же сервис работает в разных контейнерах, но отображение портов остается тем же, первый контейнер запускается нормально, но тот же сервис из второго контейнера не удастся. поэтому, чтобы избежать этого, либо измените сопоставления портов, либо создайте сеть.