Короче говоря: процесс внутри контейнера должен быть привязан к 0.0.0.0, чтобы вообще быть доступным снаружи контейнера;но затем вы можете использовать опцию Docker Compose ports:
, чтобы контролировать, откуда он действительно доступен.Если вы измените его на "127.0.0.1:8000:8000"
, он будет недоступен вне хоста.
Контейнеры Docker работают в изолированной сети .Типичная настройка может выглядеть следующим образом:
^^^
Router
| 192.168.1.1
+--------------------+-- ...
| 192.168.1.2 | 192.168.1.3
/- Host -----------\ Host 2
| 172.17.0.1 |
| | |
| | 172.17.0.2 |
| Container |
\------------------/
В качестве подробности реализации каждый контейнер имеет свой собственный частный IP-адрес.Это в изолированной сети: второй хост на 192.168.1.3/24 не имеет ни малейшего представления, что частная контейнерная сеть на 172.17.0.0/16 даже существует намного меньше, чем маршрутизировать трафик туда.Поскольку каждый контейнер имеет свой собственный частный сетевой стек, каждый контейнер также имеет свое собственное понятие о том, что означает localhost
.
(Сравните эту схему с сервером, работающим непосредственно на хосте. Он доступен на 192.168.1.2,но только из той же сети: клиент на удаленной стороне маршрутизатора не может получить доступ к частной сети 192.168.1.0/24, и снова сервер недоступен из общедоступного Интернета, даже если он связан со «всеми интерфейсами».)
Если вы зададите для процесса контейнера привязку только к 127.0.0.1, его собственному интерфейсу lo0, он не будет принимать входящий трафик от интерфейса eth0 172.17.0.2, что означает, что ничто извне не сможет достичь его..
Если вы зададите для процесса контейнера привязку 0.0.0.0 («все интерфейсы»), то он будет принимать трафик с хоста, отправленный с 172.17.0.1 (возможно, интерфейс docker0).Однако это не то же самое, что принимать трафик из «всей сети»: как уже говорилось, хост 2 по-прежнему не знает, как маршрутизировать трафик туда.
Вы можете использовать docker run -p
или Docker Compose.ports:
опция для ограничения того, на какие интерфейсы Docker будет публиковать порты.Если вы измените ports:
на "127.0.0.1:8000:8000"
, то контейнер будет доступен с порта 8000 на хосте, но только через интерфейс обратной связи хоста;опять же, для хоста 2 нет маршрута для отправки пакетов процессу.