Почему два контейнера в пространстве имен хостовой сети могут быть привязаны к одному и тому же порту?

Почему два контейнера в пространстве имен хостовой сети могут быть привязаны к одному и тому же порту?

Я работал с контейнерами Docker с помощью --network hostset и понял, что если я привяжусь к порту в одном контейнере, я все равно смогу запустить второй, который привяжется к тому же порту без каких-либо сообщений об ошибках. netstatТогда будет отображаться PID второго контейнера как прослушиваемого вместо PID первого.

Действия по воспроизведению:

[root@test]# cat /etc/os-release
NAME="Red Hat Enterprise Linux"
VERSION="9.2 (Plow)"
...
[root@test]# docker --version
Docker version 23.0.6, build ef23cbc
[root@test]# docker run -d --rm --network host --name container01 debian nc -l -p 80
7bc250856c7ddde57eb48f57ba800391577c728ec856da24bf80a9df8e766c84

[root@test]# netstat -tulpen | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      0          10435480   2162661/nc

[root@test]# docker run -d --rm --network host --name container02 debian nc -l -p 80
10897d7dea695446db48bff9d3b338554a7cd0535f30625f06b6e5f959bf8df2

[root@test]# netstat -tulpen | grep 80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      0          10436217   2162708/nc

[root@test]# ps auxf
root     2162640  0.0  0.5 720496 10608 ?        Sl   11:03   0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 7bc250856c7ddde57eb48f57ba800391
root     2162661  0.0  0.0   3200  1116 ?        Ss   11:03   0:00  \_ nc -l -p 80
root     2162686  0.0  0.5 720496 10028 ?        Sl   11:03   0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 10897d7dea695446db48bff9d3b33855
root     2162708  0.0  0.0   3200  1060 ?        Ss   11:03   0:00  \_ nc -l -p 80

Существующие соединения с первым контейнером продолжают работать даже после запуска второго. Все новые соединения будут переходить на второй.

Конечно, привязка к тому же порту непосредственно на хосте не работает, и контейнер не может привязаться к порту, на котором хост уже находится.

Итак, мой вопрос: что именно отличается для контейнеров, чтобы они могли обойти уже существующую привязку к порту?

решение1

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

Существуют некоторые ограничения на то, как программное обеспечение может разрешить повторную привязку к портам на основе операционной системы и доступных опций. Я нашел некоторые хорошие подробности об этом и процессе привязки (в Linux) в ответах здесь:Могут ли два приложения прослушивать один и тот же порт?

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