После установки докера у вас по умолчанию 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
будет направлен в вашу мостовую сеть через порт 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. Я думаю, что этот блог также полезен, чтобы лучше понять его.
--net=host
в Dockerfile?docker build --network=host
. Указанная хост-сеть для сборки докеров предназначена только для загрузки пакетов, необходимых для сборки образа. Если вы хотите запустить свой контейнер в сети хоста, вам все равно необходимо определить параметр --network = host.network_mode: "host"
(ref - docs.docker.com/compose/compose-file/#network_mode )Эта
--net=host
опция используется для того, чтобы программы внутри контейнера Docker выглядели так, как будто они работают на самом хосте, с точки зрения сети. Это дает контейнеру больший доступ к сети, чем обычно.Обычно вам необходимо перенаправить порты с хост-машины в контейнер, но когда контейнеры совместно используют сеть хоста, любая сетевая активность происходит непосредственно на хост-машине - так же, как если бы программа выполнялась локально на хосте, а не внутри контейнер.
Хотя это означает, что вам больше не нужно открывать порты и сопоставлять их с портами контейнера, это означает, что вам нужно отредактировать свои файлы Docker, чтобы настроить порты, которые прослушивает каждый контейнер, чтобы избежать конфликтов, поскольку у вас не может быть двух контейнеров, работающих на одном и том же порт хоста. Однако настоящая причина этого варианта - запуск приложений, которым необходим сетевой доступ, который трудно перенаправить в контейнер на уровне порта.
Например, если вы хотите запустить DHCP-сервер, вам необходимо иметь возможность прослушивать широковещательный трафик в сети и извлекать MAC-адрес из пакета. Эта информация теряется во время процесса перенаправления портов, поэтому единственный способ запустить DHCP-сервер внутри Docker - запустить контейнер как
--net=host
.Вообще говоря,
--net=host
он нужен только тогда, когда вы запускаете программы с очень специфическими, необычными сетевыми потребностями.Наконец, с точки зрения безопасности, контейнеры Docker могут прослушивать множество портов, даже если они объявляют (раскрывают) только один порт. Обычно это нормально, поскольку вы перенаправляете только один ожидаемый порт, однако, если вы используете,
--net=host
вы получите все порты контейнера, прослушивающие хост, даже те, которые не указаны в Dockerfile. Это означает, что вам нужно будет внимательно проверить контейнер (особенно, если он не ваш, например, официальный, предоставленный программным проектом), чтобы случайно не выставить дополнительные сервисы на машине.источник
--net=host
контейнеры будут видеть трафик, но, конечно, только одна программа одновременно может прослушивать данный порт независимо от того, в каком контейнере вы ее запускаете, в этой настройке ).источник
host
), если есть возможность запускать несколько контейнеров на одном хосте. В других случаях (когда изоляция сети не требуется) я бы предпочел--net=host
.