【问题标题】:Host unreachable inside Docker containerDocker 容器内的主机无法访问
【发布时间】:2021-06-14 08:13:37
【问题描述】:

我在主机 183.83.83.83 上有一个 docker 容器 子域 mycontainer.example.com 的 A 记录指向这个 IP。

curl 到 183.83.83.83mycontainer.example.com 会给出 HTTP 状态 200 和正确的网站。

但是,来自该主机上每个容器内部的相同 curl(到上面的 IP 或主机名)无法连接:

curl: (7) Failed to connect to mycontainer.example.com port 80: Host is unreachable

从另一个主机的 Docker 容器或主机本身尝试此操作时不会发生这种情况。

这里出了什么问题?

编辑:更多细节: 主机运行一个Nginx-proxy container,它将对mycontainer.example.com 的所有请求代理到我的前端容器(通过一个小节点网络服务器运行一个React 应用程序)。前端容器应该代理从mycontainer.example.com/apimycontainer.example.com:1337/api/v1 的所有API 请求。但是它无法代理 API 请求,因为我从该主机上运行的所有容器中收到错误 Host is unreachable

【问题讨论】:

  • 从您的容器中,您可以尝试stackoverflow.com/a/24716645/6309 并尝试卷曲该命令的结果吗?
  • 结果是172.17.0.1
  • 即网桥IP地址。也许您可以按照我在stackoverflow.com/a/38178195/6309 中的建议使用 --host 代替?
  • 我需要能够通过其公共 IP 访问它。我在我的问题中更详细地描述了这个问题。
  • 我能够通过代理到容器名称而不是公共主机名(使用 Rancher)来解决它。

标签: curl docker


【解决方案1】:

我知道这是一个老问题,但对于任何来到这里的人来说,至少在 Linux 上,解决方案是通过修改主机的 iptables 来允许传入的网络数据包从 docker bridge 网络托管,如下所示:

sudo iptables -I INPUT -i docker0 -j ACCEPT

它转换为接受来自 docker bridge 网络(假设它是 docker0)的主机上的所有传入网络数据包,即来自 docker 容器的流量。

以下是详细信息:

-I INPUT means to insert a netfilter rule for incoming packets to host
-i docker0 means packets from docker0 interface of the host
-j ACCEPT means accept all packets since a protocol is not defined it implies that packets of any protocol are welcome.

请参阅iptables --helpnetfilter 网站了解更多详情。

【讨论】:

    【解决方案2】:

    当前使用 FirewallD 的方法是执行以下命令:

    firewall-cmd --permanent --zone=trusted --change-interface=docker0
    firewall-cmd --reload
    

    【讨论】:

    • 谢谢,这个解决方案解决了我的连接问题。
    【解决方案3】:

    Fedora 32 将防火墙的后端从 iptables 切换到 nftables。我没有找到如何使用 nftables 解决问题,但是我找到了如何切换回 iptables。

    虽然以下命令看起来不是最佳实践,但它们对我有用。

    sudo sed -i 's/FirewallBackend=nftables/FirewallBackend=iptables/g' /etc/firewalld/firewalld.conf
    sudo systemctl restart firewalld docker
    

    来源:https://dev.to/ozorest/fedora-32-how-to-solve-docker-internal-network-issue-22me

    【讨论】:

      【解决方案4】:

      这是我的解决方案:

      if command -v firewall-cmd > /dev/null; then
        NIC=$(ip addr | grep {{docker.network.host.ip}} | awk '{ print $7 }')
        echo "Trusting NIC \"${NIC}\"..."
      
           sudo firewall-cmd --permanent --zone=trusted --change-interface=${NIC} \
        && sudo firewall-cmd --reload \
        && sudo systemctl restart firewalld \
        || exit $?
      fi
      

      【讨论】:

        【解决方案5】:

        我在尝试更改 docker-compose 网络时遇到了这个问题,为了修复我删除了所有未使用的网络。

        docker network ls

        不要删除那些:

        NETWORK ID     NAME                DRIVER    SCOPE
        970599083e1f   bridge              bridge    local
        dddff9d5ec3e   host                host      local
        15a80e0436c2   none                null      local
        

        docker network rm <ID|NAME>

        【讨论】:

        • docker network prune "删除所有未被至少一个容器使用的自定义网络"。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多