搜尋

首頁  >  問答  >  主體

從 Docker 容器內部,如何連接到機器的本機?

<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粉787820396P粉787820396506 天前632

全部回覆(2)我來回復

  • P粉517090748

    P粉5170907482023-08-24 11:07:24

    適用於所有平台

    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

    #

    回覆
    0
  • P粉019353247

    P粉0193532472023-08-24 09:26:22

    編輯:

    如果您使用Docker-for-macDocker-for-Windows 18.03 ,使用主機host.docker.internal (而不是 127.0.0.1< /code> 在您的連接字串中)。

    如果您使用的是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,根據文件


    關於 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 套接字進行連接。

    回覆
    0
  • 取消回覆