
我正在使用帶有--network host
set 的Docker 容器進行工作,並意識到,如果我綁定到一個容器中的端口,我仍然可以啟動第二個容器,它綁定在同一端口上,而不會出現任何錯誤消息。
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
這與您可以在同一客戶端的單一連接埠上擁有多個會話的方式大致相同。連接使用套接字對(其中包括唯一的客戶端臨時連接埠)來識別自己。主機使用這些唯一的對將流量傳送到正確的進程 ID - 有時甚至在主機連接埠本身已被不同進程綁定之後。它們應該保持活動狀態,直到主機關閉連接埠、結束這些會話、結束該進程 ID 等。
根據作業系統和可用選項,軟體如何允許重新綁定到連接埠存在一些限制。我在此處的答案中找到了一些關於該問題以及綁定過程(在Linux中)的詳細資訊:兩個應用程式可以監聽同一個連接埠嗎?