Какова связь между интерфейсами и портами между хост-компьютером и контейнером Docker?

Какова связь между интерфейсами и портами между хост-компьютером и контейнером Docker?

Помещение:

Я пытаюсь взять себя в руки.недавний обучениео сетевых интерфейсах и портах и ​​попытайтесь связать эти новые знания с Docker.

Краткое изложение того, что я узнал по этому вопросу:

  • Каждый компьютер может иметь несколько IP-адресов, по одному для каждого сетевого интерфейса.
  • IP-адреса назначаются интерфейсам, а не компьютерам и т. д.
  • Сокет — это IP+порт.
  • DHCP часто/вероятно назначает IP-адрес интерфейсу.

Как и во многих аспектах работы с программным обеспечением, я сначала делаю вещи в соответствии с "ритуалом", которому я научился, потому что "так это делается". Затем со временем и опытом я начинаю размышлять и исследовать почему и зачем. Поэтому я хотел бы связать это новое обучение с Docker.

"Ритуал", который я узнал, заключается в том, что если контейнерное приложение прослушивает TCP-сокет, вам нужно "открыть" порт этого сокета, чтобы трафик, поступающий на один из интерфейсов хоста на этом порту, "перенаправлялся" в контейнер. Например,
настраивает docker run -d -p 81:80 httpdвсе так, что если я указываю в своем веб-браузере 127.0.0.81, этот HTTP/TCP/IP-трафик "перенаправляется" вhttpdпорт контейнера 80.

Поэтому, когда я открываю в своем веб-браузере адрес 127.0.0.1:81, я вижу сообщение Apache «Это работает!».

Но также: если я укажу в своем веб-браузере адрес 127.0.0.2:81 или 127.0.0.16:81, затем я также вижу сообщение Apache «Это работает!».

Как я узнал из связанных постов, DHCP назначил интерфейсу моей сетевой карты IP-адрес 10.0.0.17, и если я указываю в своем веб-браузере адрес 10.0.0.17:81, то снова вижу сообщение Apache "It works!".
Это также работает, если я указываю в веб-браузере другого ПК в той же сети адрес 10.0.0.17:81.


Вопрос:

Мой основнойвопросявляется: для каких интерфейсов хост-компьютера (IP-адресов) порты перенаправляются с хоста на контейнер, когда вы делаете это docker runс -pаргументом? Согласно отмеченному наблюдению, ответ, по-видимому, "все интерфейсы" — так ли это?

Но если говорить шире: какова связь между интерфейсами и портами между хост-компьютером и контейнером Docker?


Что я пробовал

Я попытался прочитать docker runтекст справки, но его уровень -pне позволяет мне связать его с вопросами, которые я задаю:

-p, --publish list Опубликовать порт(ы) контейнера на хосте

Я попробовал бег, рассматривая его ifconfigв контексте моего ПК и бегущегоhttpdконтейнер.
ifconfigна хост-компьютере:

$ ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:caff:fe23:f0f4  prefixlen 64  scopeid 0x20<link>
        ether 02:42:ca:23:f0:f4  txqueuelen 0  (Ethernet)
        RX packets 3079  bytes 322688 (322.6 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6429  bytes 15942682 (15.9 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 17975  bytes 1557651 (1.5 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 17975  bytes 1557651 (1.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlp1s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.0.17  netmask 255.255.255.0  broadcast 10.0.0.255
        inet6 fe80::5f8c:c301:a6a3:6e35  prefixlen 64  scopeid 0x20<link>
        ether f8:59:71:01:89:cf  txqueuelen 1000  (Ethernet)
        RX packets 1672559  bytes 2237440808 (2.2 GB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 726083  bytes 113598143 (113.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ifconfigв бегеhttpdконтейнер (я установил его с помощью apt-get):

# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.3  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:03  txqueuelen 0  (Ethernet)
        RX packets 1326  bytes 8916833 (8.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 1134  bytes 76866 (75.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Если поставить этот вопрос в контексте вышеприведенного ifconfigвывода, какова связь между этими интерфейсами на хост-компьютере и интерфейсами в контейнере Docker?
здесь, я понимаю, что DHCP назначил 10.0.0.17 сетевой карте на моем хост-компьютере. Но откуда взялся 172.17.0.3?

решение1

[NB: Кажется, у вас здесь три вопроса, по крайней мере один из которых слишком общий, чтобы иметь четкий приемлемый ответ. Обычно SuperUser работает лучше всего, если вы задаете только один узко определенный вопрос на пост Вопроса.]

Мой главный вопрос: для каких интерфейсов хост-компьютера (IP-адресов) порты перенаправляются с хоста на контейнер, когда вы выполняете docker run с аргументом -p? Согласно отмеченному наблюдению, ответ, похоже, "все интерфейсы" — так ли это?

Да.

Но если говорить шире: какова связь между интерфейсами и портами между хост-компьютером и контейнером Docker?

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

Но откуда взялся 172.17.0.3?

Сетевой режим Docker по умолчанию,мостовая сеть, создает программный мост (например, виртуальный коммутатор Ethernet) на хосте и подключает контейнер(ы) к нему через виртуальные сетевые интерфейсы. Как небольшая виртуальная локальная сеть Ethernet внутри хоста. Затем он использует NAT (подобно маршрутизатору домашнего шлюза), чтобы позволить вашим контейнерам достичь сети за пределами хоста. NAT использует подсеть 172.17.0.0/16 в качестве своей частной подсети.

Docker использует эту подсеть, поскольку она является частью частного адресного пространства RFC 1918, как и 192.168.0.0/16, 10.0.0.0/8 и остальные 172.16.0.0/12.

Похоже, что Docker программно настраивает контейнеры со статическими адресами в этой подсети (DHCP просто усложнил бы ситуацию).

Связанный контент