Warum können zwei Container im Host-Netzwerk-Namespace beide an denselben Port gebunden werden?

Warum können zwei Container im Host-Netzwerk-Namespace beide an denselben Port gebunden werden?

Ich habe mit Docker-Containern mit Set gearbeitet --network hostund festgestellt, dass ich, wenn ich eine Bindung an einen Port in einem Container herstelle, trotzdem einen zweiten Container starten kann, der an denselben Port gebunden ist, ohne dass eine Fehlermeldung auftritt. netstatAls abhörend wird dann die PID des zweiten Containers anstelle der PID des ersten angezeigt.

Schritte zum Reproduzieren:

[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

Eine bestehende Verbindung zum ersten Container bleibt auch nach dem Start des zweiten Containers bestehen. Alle neuen Verbindungen werden an den zweiten Container weitergeleitet.

Natürlich funktioniert die Bindung an denselben Port direkt auf dem Host nicht und der Container kann auch nicht an einen Port gebunden werden, auf dem der Host bereits gelistet ist.

Meine Frage ist daher: Was genau muss bei den Containern anders sein, damit diese eine bereits bestehende Portanbindung überholen können?

Antwort1

Es ist im Wesentlichen die gleiche Art und Weise, wie Sie mehrere Sitzungen auf einem einzigen Port vom selben Client aus haben können. Verbindungen verwenden einenBuchsenpaar(einschließlich eines einzigartigen temporären Ports auf der Clientseite), um sich zu identifizieren. Der Host verwendet diese einzigartigen Paare, um Datenverkehr an die richtige Prozess-ID zu senden – manchmal sogar, nachdem der Host-Port selbst von einem anderen Prozess gebunden wurde. Sie sollten aktiv bleiben, bis der Host den Port schließt, diese Sitzungen beendet, diese Prozess-ID beendet usw.

Es gibt einige Einschränkungen, wie Software eine erneute Bindung an Ports basierend auf dem Betriebssystem und den verfügbaren Optionen ermöglichen kann. Ich habe in den Antworten hier einige gute Details dazu und zum Bindungsprozess (unter Linux) gefunden:Können zwei Anwendungen auf demselben Port lauschen?

verwandte Informationen