從 Docker 容器內部,如何連接到機器的本機?
P粉787820396
P粉787820396 2023-08-23 11:55:48
0
2
530
<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>
P粉787820396
P粉787820396

全部回覆(2)
P粉517090748

適用於所有平台

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 中啟用此功能,請將以下行新增至容器定義:

extra_hosts:
    - "host.docker.internal:host-gateway"

根據一些使用者的說法,特殊的 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

#
P粉019353247

編輯:

如果您使用Docker-for-macDocker-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 檔案中新增了以下程式碼片段:

extra_hosts:
    - "host.docker.internal:host-gateway"

否則,請閱讀下文


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 您將得到如下所示的輸出:

[vagrant@docker:~] $ sudo ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::5484:7aff:fefe:9799/64 scope link
       valid_lft forever preferred_lft forever

因此,我的 docker 主機在 docker0 網路介面上的 IP 位址為 172.17.42.1

現在啟動一個新容器並在其上取得shell:docker run --rm -it ubuntu:trusty bash 並在容器中輸入ip addr show eth0了解其主網路介面是如何設定的:

root@e77f6a1b3740:/# ip addr show eth0
863: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 66:32:13:f0:f1:e3 brd ff:ff:ff:ff:ff:ff
    inet 172.17.1.192/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::6432:13ff:fef0:f1e3/64 scope link
       valid_lft forever preferred_lft forever

這裡我的容器的 IP 位址是 172.17.1.192。現在查看路由表:

root@e77f6a1b3740:/# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.17.42.1     0.0.0.0         UG    0      0        0 eth0
172.17.0.0      *               255.255.0.0     U     0      0        0 eth0

因此,docker 主機的 IP 位址 172.17.42.1 被設定為預設路由,並且可以從您的容器存取。

root@e77f6a1b3740:/# ping 172.17.42.1
PING 172.17.42.1 (172.17.42.1) 56(84) bytes of data.
64 bytes from 172.17.42.1: icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from 172.17.42.1: icmp_seq=2 ttl=64 time=0.201 ms
64 bytes from 172.17.42.1: icmp_seq=3 ttl=64 time=0.116 ms

docker run --network="host"

或者,您可以執行 Docker 容器,並將 網路設定設為 主機。這樣的容器將與 docker 主機共用網路堆疊,從容器的角度來看,localhost(或127.0.0.1)將引用 docker 主機。 p>

請注意,在 docker 容器中開啟的任何連接埠都會在 docker 主機上開啟。這不需要 -p 或 -P docker run#選項

我的 docker 主機上的 IP 設定:

[vagrant@docker:~] $ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
       valid_lft forever preferred_lft forever

以及來自 主機 模式下的 docker 容器:

[vagrant@docker:~] $ docker run --rm -it --network=host ubuntu:trusty ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
       valid_lft forever preferred_lft forever

正如您所看到的,docker 主機和 docker 容器共用完全相同的網路接口,因此具有相同的 IP 位址。


從容器連接到 MySQL

橋接模式

要從橋接模式的容器存取在 docker 主機上執行的 MySQL,您需要確保 MySQL 服務正在偵聽 172.17.42.1 IP 位址上的連線.

為此,請確保您的 MySQL 設定檔 (my.cnf) 中有 bind-address = 172.17.42.1bind-address = 0.0.0.0 )。

如果需要使用網關的IP位址設定環境變量,可以在容器中執行以下程式碼:

export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print }')

然後在您的應用程式中,使用 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 來自您的容器:

[vagrant@docker:~] $ docker run --rm -it --network=host mysql mysql -h 127.0.0.1 -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

注意:請使用mysql -h 127.0.0.1,而不是mysql -h localhost;否則MySQL 用戶端會嘗試使用unix 套接字進行連接。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!