【问题标题】:From inside of a Docker container, how do I connect to the localhost of the machine?从 Docker 容器内部,如何连接到机器的本地主机?
【发布时间】:2014-08-10 18:18:04
【问题描述】:

所以我在 docker 容器中运行了一个 Nginx,我在 localhost 上运行了一个 mysql,我想从我的 Nginx 中连接到 MySql。 MySql 运行在 localhost 上,不对外暴露端口,所以绑定在 localhost 上,而不是绑定在机器的 ip 地址上。

有没有办法从这个 docker 容器内连接到这个 MySql 或本地主机上的任何其他程序?

这个问题与“如何从 docker 容器内获取 docker 主机的 IP 地址”不同,因为 docker 主机的 IP 地址可能是网络中的公共 IP 或私有 IP在 docker 容器内可能可以访问,也可能无法访问(如果托管在 AWS 或其他地方,我的意思是公共 IP)。即使您拥有 docker 主机的 IP 地址,这并不意味着您可以从容器内连接到 docker 主机,因为您的 Docker 网络的 IP 地址可能是覆盖、主机、网桥、macvlan、none 等,这限制了该 IP 地址。

【问题讨论】:

标签: nginx docker reverse-proxy docker-networking


【解决方案1】:

您可以简单地在主机上执行ifconfig 来检查您的主机IP,然后从您的容器内连接到该IP,这对我来说非常适合。

【讨论】:

  • 为我工作。我用了ifconfig命令,取了第一个inet ip,看来是对的
【解决方案2】:

连接到网关地址。

❯ docker network inspect bridge | grep Gateway
                    "Gateway": "172.17.0.1"

确保主机上的进程正在侦听此接口或所有接口,并在 docker 之后启动。如果使用 systemd,您可以添加以下内容以确保它在 docker 之后启动。

[Unit]
After=docker.service

示例

❯ python -m http.server &> /dev/null &
[1] 149976

❯ docker run --rm python python -c  "from urllib.request import urlopen;print(b'Directory listing for' in urlopen('http://172.17.0.1:8000').read())" 
True

【讨论】:

    【解决方案3】:

    主机上的服务器正在监听 5000 端口;它将返回一个字符串response from host作为响应

    echo "response from host" | nc -l -p 5000

    docker默认运行在桥接模式(比在主机网络模式下运行更安全); docker 中的进程获取主机上不是 127.0.0.1 的第一个网络接口的 ipv4 地址;这个 ipv4 地址通过环境变量 HOSTIP 传递给 docker;在 docker 里面有一个 nc 命令连接到主机 ip 和端口 5000 上的服务器;该命令还读取服务器的响应。

    HOST=$(ifconfig | grep 'inet ' | grep -v 127.0.0.1 | awk '{ print $2 }' | head -1 | sed -n 's/[^0-9]*\([0-9\.]*\)/\1/p'); docker run -e HOSTIP="${HOST}" --rm -it alpine /bin/sh -c 'echo "greetings from container" | nc $HOSTIP 5000 -v'

    计算第一个列出的接口的 ipv4 地址的表达式确实适用于 osx 和 linux:

    HOST=$(ifconfig | grep 'inet ' | grep -v 127.0.0.1 | awk '{ print $2 }' | head -1 | sed -n 's/[^0-9]*\([0-9\.]*\)/\1/p')

    更通用:您可以在另一个 docker 容器中运行服务器,如下所示:

    docker run --expose 5000 -p :5000:5000 --rm -it alpine /bin/sh -c 'echo "response from host" | nc -l -p 5000'

    --暴露5000 docker容器可以接受5000端口的连接

    -p :5000:5000 主机端的 docker 引擎正在侦听任何接口上的 5000 端口,并将连接转发到容器网络上的 5000 端口(运行 nc)。

    【讨论】:

      【解决方案4】:

      尽管答案很长,令人困惑,但答案很短。如果你的 docker bridge 网络是 172.17.0.0/16,请执行以下操作:

      1. 将您的容器绑定到 172.17.0.1,例如。 -p 172.17.0.1:8080:8080(无论你的 Docker 桥接网络中的网关是什么)
      2. 只需访问 172.17.0.1 端口 8080 例如。 curl http://172.17.0.1:8080/ 来自其他容器

      【讨论】:

        【解决方案5】:

        7 年来这个问题被问到,要么是 docker 改变了,要么没有人尝试过这种方式。所以我会附上我自己的答案。

        我发现所有答案都使用复杂的方法。今天正好需要这个,找到了2个很简单的方法:

        • 在您的主机上使用ipconfigifconfig 并记下所有IP 地址。容器至少可以使用其中的两个。

          • 我在 WiFi LAN 适配器上有一个固定的本地网络地址:192.168.1.101。这可能是10.0.1.101。结果会因您的路由器而异
          • 我在windows上使用WSL,它有自己的vEthernet地址:172.19.192.1
        • 使用host.docker.internal。大多数答案都有这种或另一种形式,具体取决于操作系统。顾名思义,它现在被 docker 全局使用。

        第三种选择是使用机器的 WAN 地址,或者换句话说,由服务提供商提供的 IP。但是,如果 IP 不是静态的,并且需要路由和防火墙设置,这可能不起作用。

        【讨论】:

          【解决方案6】:

          如果您使用 --net=host 运行,则 localhost 应该可以正常工作。如果您使用默认网络,请使用静态 IP 172.17.0.1。

          看到这个 - https://stackoverflow.com/a/48547074/14120621

          【讨论】:

            猜你喜欢
            相关资源
            最近更新 更多