【问题标题】:What is linux equivalent of "host.docker.internal" [duplicate]什么是“host.docker.internal”的linux等价物
【发布时间】:2018-07-10 19:07:20
【问题描述】:

在 Mac 和 Windows 上,可以在容器内使用 docker.for.mac.host.internal(替换 docker.for.mac.localhost)和 docker.for.win.host.internal(替换 docker.for.win.localhost host.docker.internal(Docker 18.03+)。

有没有一种适用于 Linux 的工具,无需传递环境变量或使用各种 CLI 命令提取它即可开箱即用?

【问题讨论】:

  • 在 18.03 中有一个 docker.host.internal,但它对我不起作用。
  • 有一个开放的PR 将“host.docker.internal”功能添加到Linux。等到它被接受,现在作为一种解决方法,您可以使用 special container 添加统一的“dockerhost”主机,您可以从 docker 使用它。
  • 需要注意的是,docker-for-windows是一个特定的产品线,一般不会涵盖windows上的docker。例如,我在 Windows 上使用 docker,使用 docker-toolbox (OG),这样它与我的其余设置的冲突较少,我不需要 HyperV。在这个线程中有一个使用 grep、awk 和 netstat 的答案,这对我有用;虽然一般来说,混合网络环境也可以使用 LAN 或 WAN 级别的主机名来解决,而不是机器主机名。这比在 docker VM 上进行黑客攻击更明确、更灵活/可组合

标签: docker docker-for-windows docker-for-mac docker-desktop


【解决方案1】:

取决于你想要做什么。如果您使用--net=host 运行,localhost 应该可以正常工作。如果您使用默认网络,请使用静态 IP 172.17.0.1。我怀疑两者的行为都不会与那些域完全相同。

【讨论】:

  • 哇! 172.17.0.1 确实有效!我在文档或任何抱怨host.docker.internal 不起作用的论坛中都找不到这个。是否保证此 IP 始终链接到主机?
  • 您可以编辑您的 /etc/hosts 并添加 172.17.0.1 docker.host.internal
  • 我可以证明 172.17.0.1-trick 这适用于 GitHub Actions!
  • @JulesColle 只要您在默认网络上,它就是“保证”。 172.17.0.1 不是魔术,只是网络bridge 的网关,恰好是主机。除非另有说明,否则所有容器都将连接到 bridgeSee here
  • 这不适用于所有情况。如果您有其他网络,将创建一个新接口:172.17.0.1、172.18.0.1、172.19.0.1 等等(尝试ifconfig 列出所有接口)。您必须手动获取网络的 IP。
【解决方案2】:

对于 linux 系统,您可以 - 从 docker 引擎的主要版本 20.04 开始 - 现在还可以通过 host.docker.internal 与主机通信。这不会自动运行,但您需要提供以下运行标志:

--add-host=host.docker.internal:host-gateway

在此处查看答案:https://stackoverflow.com/a/61424570/3757139

另请参阅下面的此答案以添加到 docker-compose 文件 - https://stackoverflow.com/a/67158212/243392

【讨论】:

  • 有没有办法在 daemon.json 中启用它?我正在考虑 Rancher 和 Kubernetes 的测试环境,我不想在其中处理众多容器中的每一个。
  • 在 CentOS 上运行--add-host=host.docker.internal:host-gateway 时收到错误invalid argument "host.docker.internal:host-gateway" for "--add-host" flag: invalid IP address in add-host: "host-gateway" 您是否需要将host-gateway 替换为实际主机IP?
  • 神奇的 IP 号码起作用了:`--add-host=host.docker.internal:172.17.0.1 `
  • 这也适用于我。在我的例子中,172.17.0.1 是桥接网络的网关地址。如果有人有不同的网络设置,他们可以通过 docker inspect 来获得。
  • 只有较新的 docker 版本有神奇的字符串 host-gateway,它转换为 docker 默认的网桥网络 ip(或使用 docker 桌面时主机的虚拟 IP)。你可以测试运行:docker run --rm --add-host=host.docker.internal:host-gateway ubuntu:18.04 cat /etc/hosts,然后看看它是否有效并在hosts文件中显示ip(里面应该有172.17.0.1 host.docker.internal这样的行)。
【解决方案3】:

如果您使用的是Docker Compose + Linux,则必须手动添加它(至少现在是这样)。在您的 docker-compose.yaml 文件上使用 extra_hosts

version: '3.7'

services:

  fpm:
    build:
      context: .
    extra_hosts:
      - "host.docker.internal:host-gateway"

文档 - https://docs.docker.com/compose/compose-file/compose-file-v3/#extra_hosts

不要忘记更新 Docker,因为这只适用于 Docker v20.10+

来源:https://github.com/docker/for-linux/issues/264#issuecomment-784985736

【讨论】:

  • 太棒了!最后我也可以在 linux 上使用 xdebug 了 :-)
  • @funder7 大声笑,是的,我这样做是为了使用 xdebug :)
  • 如果我想访问主机上的 3000 端口,这是我从容器中访问它的方式:http://host.docker.internal:3000/ 吗?
  • 这样做添加的主机条目似乎在错误的子网中
【解决方案4】:

一种解决方案是使用特殊容器将流量重定向到主机。你可以在这里找到这样的容器:https://github.com/qoomon/docker-host。这个想法是从容器中获取默认路由并将其安装为传入连接的 NAT 网关。

一个虚构的示例用法:

docker-host:
  image: qoomon/docker-host
  cap_add: [ 'NET_ADMIN', 'NET_RAW' ]
  restart: on-failure
  environment:
    - PORTS=999

some-service:
  image: ...
  environment:
    SERVER_URL: "http://docker-host:999"
  command: ...
  depends_on:
    - docker-host

【讨论】:

    【解决方案5】:

    这是我的解决方案:

    IP_ADDRESS=$(ip addr show | grep "\binet\b.*\bdocker0\b" | awk '{print $2}' | cut -d '/' -f 1)
    

    然后在 docker-compose 中:

    extra_hosts:
      docker.host: ${IP_ADDRESS}
    

    【讨论】:

    • 在我的 Ubuntu VM 上,这是 172.17.0.1,与上述答案相符。
    • 在 Linux/Debian docker 上使用这个 cmd 我什么也得不到。更好的是:/sbin/ip route|awk '/default/ { print $3 }'
    • 上述ip route 示例打印网关,而不是docker0 io。以下应该可以工作:# ip route | awk '/docker0/ {print $9}'
    【解决方案6】:

    对于 linux,主机没有默认的 DNS 名称。这可以通过运行命令来验证:

    docker run -it alpine cat /etc/hosts
    

    已请求此功能,但未实现。您可以查看此issue。如前所述,您可以使用以下命令从容器中查找主机的 IP。

    netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'
    

    或者,您可以通过docker run --add-host dockerHost:<ip-address> ... 将主机 ip 提供给运行命令

    【讨论】:

    • 这绝不是等价的。拥有可以用 dns 解决的东西让您能够将其放入配置文件中,而无需评估或 sed'ing 或其他时髦的东西。
    • grep | awk 往往只是 awk:awk '/^0\.0\.0\.0/{print $2}' :)
    • 好吧,我想说声谢谢。这适用于我使用 docker-machine 的 Windows 设置(我知道 OG)。通常我会运行一个直通 nginx,这样我就可以通过单个容器与 docker 对话,但与主机对话似乎是非常特定于操作系统/设置的。它对我有用,我为此欣喜若狂。谢谢!
    【解决方案7】:

    https://github.com/docker/for-linux/issues/264

    IP=$(ip -4 route list match 0/0 | awk '{print $3}')
    echo "Host ip is $IP"
    echo "$IP   host.docker.internal" | sudo tee -a /etc/hosts
    

    它会将host.docker.internal 添加到您的主机。然后就可以在 xdebug config 中使用了。

    这是docker-compose.yml中的环境变量示例

    XDEBUG_CONFIG: remote_host=host.docker.internal remote_autostart=On remote_enable=On idekey=XDEBUG remote_log=/tmp/xdebug.log remote_port=9999
    

    【讨论】:

      【解决方案8】:

      使用 docker0 接口 ip,比如 172.17.0.1,可能是一个很好的解决方法。

      只需确保您需要访问的服务侦听外部连接即可。一个典型的例子是默认绑定到 127.0.0.1 的 Mysql,导致无法访问,直到您允许外部连接(例如绑定到 0.0.0.0)

      【讨论】:

        【解决方案9】:

        host.docker.internal 仅存在于 Windows WSL 中,因为 Docker Desktop for Windows 在特殊的 WSL VM Docker-Desktop 中运行 Docker 守护程序。它有自己的 localhost 和自己的 WSL2 接口来与 Windows 通信。此 VM 没有静态 IP。每次创建 VM 时都会生成 IP,并通过生成的 /etc/hosts 中的 host.docker.internal 将其传递给每个发行版。尽管没有网桥或真正的 v-switch,但在 VM 内部网络的 eth0 上打开的所有端口都映射到主机本地网络,但不在主机的 ETH0 上。 没有真正的网桥和端口映射 - 无需配置。 在 WSL VM 内部,它的 localhost 与 Linux 机器的 localhost 相同。 WSL VM 中的 2 个进程可以通过 localhost 进行通信。跨发行版 IPC 必须使用 host.docker.internal。可以在 WSL VM 中创建桥接器 - Docker 可以做到。

        【讨论】:

          【解决方案10】:

          tldr;通过静态IP172.17.0.1访问主机

          向主机发起 HTTP 请求:

          1. 运行以下命令获取静态IP:ip addr show | grep "\binet\b.*\bdocker0\b" | awk '{print $2}' | cut -d '/' -f 1

          2. 将新 IP 添加到允许的主机

          3. 使用刚刚在您的请求中找到的 IP 地址:req = requests.get('http://172.17.0.1:8000/api/YOUR_ENDPOINT')

          【讨论】:

            【解决方案11】:

            对于 linux,我可以使用我尝试连接的服务名称,例如我的一个容器(php-fpm)正在尝试连接到 mysql,所以我使用 mysql 作为主机名,因为这是我的 docker-compose 中的服务名称

            【讨论】:

            • 这个问题是关于连接到主机系统,而不是同一个 docker-compose 环境中的另一个服务。
            • 两件事:a)它是对潜在问题的正确答案(而不是使用 /etc/hosts 破解 DNS 解析)和 b)使用 docker 的内部来做简单的事情,比如访问暴露的端口是并且一直是不鼓励的。这就是 docker-compose 中的 -p 或“公开”所做的。我知道这个问题有点不同,但它源于另一个错误,通过模拟 /etc/hosts 刚刚被覆盖 - 未修复。
            猜你喜欢
            • 2010-12-28
            • 1970-01-01
            • 1970-01-01
            • 2017-04-03
            • 2011-03-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-11-20
            相关资源
            最近更新 更多