为什么我不能通过主机将一个docker容器与另一个容器卷曲

pqv*_*vst 14 docker

我真的不明白这里发生了什么.我只是想在已发布的端口上使用主机的公共IP从一个docker容器内部,另一个docker容器,通过主机执行http请求.

这是我的设置.我有我的开发机器.我有一个带有两个容器的docker主机.CONT_A在端口3000上侦听并发布Web服务.

DEV-MACHINE

HOST (Public IP = 111.222.333.444)
  CONT_A (Publish 3000)
  CONT_B
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在我的开发机器上(一台完全不同的机器)

我可以毫无问题地卷曲

curl http://111.222.333.444:3000 --> OK
Run Code Online (Sandbox Code Playgroud)

当我SSH进入HOST

我可以卷曲而没有任何问题

curl http://111.222.333.444:3000 --> OK
Run Code Online (Sandbox Code Playgroud)

当我在CONT_B内执行时

不可能,只是超时.Ping虽然很好......

docker exec -it CONT_B bash
$ curl http://111.222.333.444:3000 --> TIMEOUT
$ ping 111.222.333.444 --> OK
Run Code Online (Sandbox Code Playgroud)

为什么?

Ubuntu 16.04,Docker 1.12.3(默认网络设置)

Rik*_*uta 5

我知道这不是问题的严格答案,但是有更多的Docker-ish方法来解决你的问题.我会忘记发布用于集装箱间通信的端口.而是使用docker swarm创建覆盖网络.您可以在此处找到完整指南,但实质上您可以执行以下操作:

//create network    
docker network create --driver overlay --subnet=10.0.9.0/24 my-net
//Start Container A
docker run -d --name=A --network=my-net producer:latest
//Start Container B
docker run -d --name=B --network=my-net consumer:latest

//Magic has occured
docker exec -it B /bin/bash
> curl A:3000 //MIND BLOWN!
Run Code Online (Sandbox Code Playgroud)

然后在容器内部,您可以只卷曲主机名A,它将为您解决(即使您开始进行缩放等)

如果您不热衷于使用Docker swarm,您仍然可以使用Docker遗留链接:

docker run -d --name B --link A:A consumer:latest
Run Code Online (Sandbox Code Playgroud)

这将链接A容器中任何暴露(未发布)的端口.

最后,如果你开始转向生产......完全忘记链接和覆盖网络...使用Kubernetes :-)更难以初始设置,但他们引入了一堆概念和工具来连接和扩展容器集群a好多了!但这只是我个人的意见.

  • 当您在单个主机上时,它甚至不需要是覆盖网络,默认桥接驱动程序将工作文件. (3认同)

Von*_*onC 5

当前的答案都没有解释为什么 docker 容器的行为如问题中所述

Docker 的作用是为一个或多个容器提供主机资源的轻量级隔离。

默认情况下, Docker网络与主机网络隔离,并使用桥接网络(同样,默认情况下;您有覆盖网络)进行容器间通信。

https://docs.docker.com/engine/tutorials/bridge1.png

以及如何在没有 docker 网络的情况下解决问题。

来自“如何从 Docker 容器内部连接到 Docker 主机?

从 Docker 版本 18.03 开始​​,您可以使用host.docker.internal主机名从 Docker 容器内部连接到 Docker 主机。

这在 Docker for Mac 和Docker for Windows上运行良好,但不幸的是,直到 2020 年 12 月发布 Docker 20.10.0 之前,Linux 上才支持此功能。

从版本 20.10 开始,Docker Engine 现在还支持通过host.docker.internalLinux 与 Docker 主机进行通信。
不幸的是,这在 Linux 上不能开箱即用,因为您需要添加额外的--add-host运行标志:

--add-host=host.docker.internal:host-gateway
Run Code Online (Sandbox Code Playgroud)

这是出于开发目的,不适用于 Windows/Mac 的 Docker Desktop 之外的生产环境。

这样,您不必将网络驱动程序更改为--network=host,您仍然可以通过 访问主机host.docker.internal