從 Docker 容器內部,如何連接到機器的本機?
P粉787820396
2023-08-23 11:55:48
<p>我有一個 Nginx 在 docker 容器內運行。我有一個在主機系統上運行的 MySql。我想從我的容器內連接到 MySql。 MySql 僅綁定到本機主機設備。 </p>
<p>有什麼方法可以從這個 docker 容器內連接到這個 MySql 或本地主機上的任何其他程式嗎? </p>
<p>這個問題與「如何從docker容器內取得docker主機的IP位址」不同,因為docker主機的IP位址可能是網路中的公用IP或私有IP,可能或可能無法從docker 容器內存取(我的意思是公共IP,如果託管在AWS 或其他地方)。即使您擁有docker 主機的IP 位址,也不代表您可以從容器內連接到docker 主機,因為您的Docker 網路可能是覆蓋網路、主機網路、橋接網路、macvlan 網路、none 網路等,這限制了容器的可達性該IP 位址。 </p>
適用於所有平台
Docker v 20.10 及更高版本(自 2020 年 12 月 14 日起)
使用您的內部 IP 位址或連接到特殊 DNS 名稱
host.docker.internal
,該名稱將解析為主機使用的內部 IP 位址。這是出於開發目的,不適用於 Docker Desktop 以外的生產環境。
Linux 警告
#要在Linux 上的Docker 中啟用此功能,請將
--add-host=host.docker.internal:host-gateway
新增到您的docker
指令啟用該功能。要在 Linux 上的 Docker Compose 中啟用此功能,請將以下行新增至容器定義:
根據一些使用者的說法,特殊的 DNS 名稱僅在 Docker 的預設
bridge
網路中有效,而在自訂網路中無效。對於舊版 macOS 和 Windows 版本的 Docker
Docker v 18.03 及更高版本(自 2018 年 3 月 21 日起)
#使用您的內部 IP 位址或連接到特殊 DNS 名稱
host.docker.internal
,該名稱將解析為主機使用的內部 IP 位址。Linux 支援待定 https://github.com/docker/for-linux/issues /264
#對於舊版 macOS 版本的 Docker
Docker for Mac v 17.12 至 v 18.02
#與上面相同,但使用
docker.for.mac.host.internal
。Docker for Mac v 17.06 至 v 17.11
#與上面相同,但使用
docker.for.mac.localhost
代替。適用於 Mac 17.05 及更低版本的 Docker
要從 docker 容器存取主機,您必須將 IP 別名附加到您的網路介面。您可以綁定任何您想要的 IP,只要確保您沒有將其用於其他任何地方即可。
sudo ifconfig lo0 別名 123.123.123.123/24
#然後確保您的伺服器正在偵聽上述 IP 或
0.0.0.0
。如果它正在監聽本地主機127.0.0.1
,它將不接受連線。然後只要將你的docker容器指向這個IP就可以存取主機了!
要進行測試,您可以在容器內執行類似
curl -X GET 123.123.123.123:3000
的內容。別名將在每次重新啟動時重置,因此如有必要,請建立啟動腳本。
此處的解決方案和更多文件:https ://docs.docker.com/desktop/networking/#use-cases-and-workarounds-for-all-platforms
#編輯:
如果您使用Docker-for-mac 或Docker-for-Windows 18.03 ,使用主機
host.docker.internal
(而不是127.0.0.1 在您的連接字串中)。
如果您使用的是Docker-for-Linux 20.10.0 ,您也可以使用主機
host.docker.internal
if您使用--add-host host.docker.internal:host-gateway
選項啟動了Docker 容器,或在docker-compose.yml 檔案中新增了以下程式碼片段:否則,請閱讀下文
TLDR
在
docker run
指令中使用--network="host"
,然後docker 容器中的127.0.0.1
將指向您的碼頭工人主機。注意:此模式僅適用於 Linux 版 Docker,根據文件。 p>
關於 docker 容器網路模式的注意事項
Docker 在運行容器時提供不同的網路模式。根據您選擇的模式,您將以不同方式連線到在 docker 主機上執行的 MySQL 資料庫。
docker run --network="bridge"(預設)
Docker 預設會建立一個名為
docker0
的網橋。 docker 主機和 docker 容器在該橋接器上都有一個 IP 位址。在 Docker 主機上,輸入
sudo ip addr show docker0
您將得到如下所示的輸出:因此,我的 docker 主機在
docker0
網路介面上的 IP 位址為172.17.42.1
。現在啟動一個新容器並在其上取得shell:
docker run --rm -it ubuntu:trusty bash
並在容器中輸入ip addr show eth0
了解其主網路介面是如何設定的:這裡我的容器的 IP 位址是
172.17.1.192
。現在查看路由表:因此,docker 主機的 IP 位址
172.17.42.1
被設定為預設路由,並且可以從您的容器存取。docker run --network="host"
或者,您可以執行 Docker 容器,並將 網路設定設為
主機
。這樣的容器將與 docker 主機共用網路堆疊,從容器的角度來看,localhost
(或127.0.0.1
)將引用 docker 主機。 p>請注意,在 docker 容器中開啟的任何連接埠都會在 docker 主機上開啟。這不需要
-p
或 -Pdocker run
#選項。我的 docker 主機上的 IP 設定:
以及來自 主機 模式下的 docker 容器:
正如您所看到的,docker 主機和 docker 容器共用完全相同的網路接口,因此具有相同的 IP 位址。
從容器連接到 MySQL
橋接模式
要從橋接模式的容器存取在 docker 主機上執行的 MySQL,您需要確保 MySQL 服務正在偵聽
172.17.42.1
IP 位址上的連線.為此,請確保您的 MySQL 設定檔 (my.cnf) 中有
bind-address = 172.17.42.1
或bind-address = 0.0.0.0
)。如果需要使用網關的IP位址設定環境變量,可以在容器中執行以下程式碼:
然後在您的應用程式中,使用
DOCKER_HOST_IP
環境變數開啟與 MySQL 的連線。注意:如果您使用
bind-address = 0.0.0.0
,您的MySQL伺服器將偵聽所有網路介面上的連線。這表示您的 MySQL 伺服器可以從 Internet 存取;確保相應地設定防火牆規則。注意2:如果您使用
bind-address = 172.17.42.1
,您的MySQL伺服器將不會偵聽與127.0.0.1
建立的連接>。在 docker 主機上執行的想要連接到 MySQL 的進程必須使用172.17.42.1
IP 位址。主機模式
要從主機模式下的容器存取在docker 主機上執行的MySQL,您可以在MySQL 設定中保留
bind-address = 127.0.0.1
並連線到127.0.0.1
來自您的容器:注意:請使用
mysql -h 127.0.0.1
,而不是mysql -h localhost
;否則MySQL 用戶端會嘗試使用unix 套接字進行連接。