
我正在編寫一個綁定到多個本地端口(包括80
和443
)的伺服器。每當我使用其容器優化作業系統 (COS) 和 Docker 容器在 Google 電腦引擎 (GCE) 上運行它時,連接埠都會綁定到 IPv6,而不是 IPv4。
$ netstat -tuln
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:36265 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp6 0 0 :::80 :::* LISTEN
tcp6 0 0 :::443 :::* LISTEN
udp 0 0 10.128.0.33:68 0.0.0.0:*
這是一個重要的區別,因為我的程式中有一個邏輯嘗試使用 的 IPv4 位址直接連接到本機介面127.0.0.1
。
如何指定我的 GCE 實例使用 IPv4 連接埠?
答案1
編輯
需要注意的一件重要事情(如評論中指出的)- 雖然它可能綁定到同時使用 IPv4 和 IPv6 的接口,但 IPv6 路由無法在 Google Cloud 上運行(內部尚不支援)。
因此,事實證明,這是一個與 Docker 的網路方式混淆的“功能”,它仍然應該允許 IPv4 連接以及 IPv6。
看這個 StackOverflow 答案更多細節。為了後代,我引用了下面的答案:
…github.com/docker/docker/issues/2174是關於在 中僅顯示與 IPv6 的綁定
netstat
,但這不是問題。如 github 問題所述:設定代理程式時,Docker 請求環回位址“127.0.0.1”,Linux 意識到這是 IPv6 中存在的位址(如 ::0)並在兩者上開啟(但它正式是 IPv6 套接字)。當您執行 netstat 時,它會看到這一點並告訴您它是 IPv6 - 但它仍在偵聽 IPv4。如果您稍微調整了一下設置,您可能已經禁用了 Linux 的這個技巧 - 透過設定 net.ipv6.bindv6only = 1。
換句話說,僅僅因為您將其視為僅 IPv6,因此它仍然能夠在 IPv4 上進行通信,除非您使用 net.ipv6.bindv6only 設定將 IPv6 設定為僅綁定在 IPv6 上。需要明確的是,net.ipv6.bindv6only 應該是 0 - 您可以運行
sysctl net.ipv6.bindv6only
來驗證。