Мой сценарий: я хотел бы, чтобы мои службы на основе докеров знали, какой IP вызывает их из Интернета (требование моего приложения).
Я использую облачный VPS, debian jessie, с докером 1.12.2.
я использую nc
в подробном режиме, чтобы открыть порт 8080
.
docker run --rm -p "8080:8080" centos bash -c "yum install -y nc && nc -vv -kl -p 8080"
Скажем, у VPS есть домен example.com
, и с другой моей машины, у которой, скажем, есть IP dead:::::beef
Я звоню
nc example.com 8080
В сервер говорит:
Ncat: Version 6.40 ( http://nmap.org/ncat )
Ncat: Listening on :::8080
Ncat: Listening on 0.0.0.0:8080
Ncat: Connection from 172.17.0.1.
Ncat: Connection from 172.17.0.1:49799.
172.17.0.1
на сервер в локальной сети и, конечно, не имеет никакого отношения к моему клиенту. По факту:
docker0 Link encap:Ethernet HWaddr ....
inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
Если я запустил контейнер в режиме сети хоста
docker run --rm --net=host -p "8080:8080" centos bash -c "yum install -y nc && nc -vv -kl -p 8080"
и снова позвони на мой сервер
nc example.com 8080
Получаю ожидаемый результат:
Ncat: Connection from dead:::::beef.
Ncat: Connection from dead:::::beef:55650.
Мои вопросы:
nc
запущенный в контейнере, таким образом, видит только то, что вызов исходит от IP-адреса демона докеров.Согласно документация, драйвер по умолчанию (т.е. когда вы не указываете --net=host
в docker run
, это bridge
сетевой драйвер.
Дело не в «маскировке» IP-адресов докерами, а в том, как bridged
и host
сетевые режимы различаются.
Что касается Docker, мостовая сеть использует программный мост, который позволяет контейнерам, подключенным к одной и той же мостовой сети, обмениваться данными, обеспечивая изоляцию от контейнеров, которые не подключены к этой сети моста. Драйвер моста Docker автоматически устанавливает правила на главном компьютере, чтобы контейнеры в разных сетях моста не могли напрямую взаимодействовать друг с другом.
Docker создает изолированную сеть, чтобы каждый контейнер в мостовой сети мог обмениваться данными, в вашем случае это docker0
. Таким образом, по умолчанию контейнеры на вашем хосте докеров обмениваются данными в этой сети.
Как вы, возможно, уже догадались, да 172.17.0.1
это маршрут по умолчанию на docker0
сеть, но он не действует как маршрутизатор, который пересылает пакеты к месту назначения, поэтому вы видите его как источник вывода netcat.
Фактически, вы можете проверить это, запустив ss -tulnp
на вашем докер-хосте. Вы должны увидеть, что процесс, прослушивающий порт 8080, - это докер.
С другой стороны, используя хозяин сетевой драйвер означает, что между контейнером и хостом нет изоляции. Вы можете проверить это, запустив ss -tulnp
на вашем докер-хосте; вы должны увидеть, как процесс прослушивает сокет вместо докера (в вашем случае вы должны увидеть nc
).