两个Docker容器在macOS上的通信10.12

我正在使用MacOS 10.12上的Docker 1.12.5,并且正在使用一个应用程序映像和一个共享的redis映像来设置一个开发环境,这个映像有一些预先填充的configurationvariables。

即使遵循几个教程(并阅读关于docker0在Mac上不可用),我正在努力连接两个容器。

我开始使用我的redis映像:

 docker run -d -p 6379:6379 (IMAGE ID) 

在我的redis映像中,我有:

 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES dffb89854618 d59 "docker-entrypoint.sh" 20 seconds ago Up 19 seconds 0.0.0.0:6379->6379/tcp drunk_williams 

从我的Mac,我可以通过redis-cli命令成功连接,没有问题。

但是,当我启动一个简单的ubuntu映像,我似乎无法连接到这个单独的redis映像:

 root@2d4eda315f4f:/# ifconfig eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:03 inet addr:172.17.0.3 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:20707 errors:0 dropped:0 overruns:0 frame:0 TX packets:11515 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:28252929 (28.2 MB) TX bytes:635848 (635.8 KB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:12 errors:0 dropped:0 overruns:0 frame:0 TX packets:12 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:680 (680.0 B) TX bytes:680 (680.0 B) root@2d4eda315f4f:/# telnet localhost 6379 Trying ::1... Trying 127.0.0.1... telnet: Unable to connect to remote host: Connection refused root@2d4eda315f4f:/# telnet 172.17.0.3 6379 Trying 172.17.0.3... telnet: Unable to connect to remote host: Connection refused 

这是主机中没有docker0接口的结果吗? 是否有一些简单的解决方法允许这些容器在开发环境中进行通信(当在同一主机上运行时)?

更新:试图使用命名容器,我仍然无法连接。

 docker run -d --name redis_server redis 

结果是:

 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5d05820aa985 redis "docker-entrypoint.sh" 43 hours ago Up 1 seconds 6379/tcp redis_server 

但是,如果我启动一个新的Ubuntu容器:

 root@e92b47419bc4:/# redis-cli -h redis_server Could not connect to Redis at redis_server:6379: Name or service not known 

我不知道如何find/连接到第一个redis_server容器。

每个容器都有自己的本地主机

每个服务都在自己的容器中运行。 从Ubuntu容器的angular度来看,redis不在本地主机上监听。

使用Dockernetworking

为了让你的容器进行通信,他们应该在同一个Dockernetworking上。 这包括三个步骤:

  1. 创build一个Dockernetworking
  2. 给你的容器名称
  3. 将您的容器连接到您创build的networking

通过这样做,容器可以使用它们的名字相互交谈,就好像它们是主机名一样。

有不止一种方式来剥皮这只猫…我会在这个答案中看两个,但是可能还有其他一些方法来做到这一点,我不熟悉(比如使用Kubernetes或Swarm)。

手工操作

您可以使用docker network命令为此应用程序创build一个networking。

 # Show the current list of networks docker network ls # Create a network for your app docker network create my_redis_app 

当你运行redis容器时,确保它有一个名字,并且在这个networking上。 如果你想(使用-p ),你可以在外部暴露端口(到macOS),但是这对于其他容器来说是不必要的。

 docker run -d -p 6379:6379 --name redis_server --network my_redis_app <IMAGE ID> 

现在运行你的Ubuntu容器。 如果你喜欢,你可以把它命名,但是我不会在这个例子中打扰,因为这个没有运行任何服务。

 docker run -it --network my_redis_app ubuntu bash 

现在从Ubuntu容器中,您应该能够使用名称redis_server访问redis,就好像它是DNS名称一样。

使用Compose进行

我倾向于使用Compose构build像这样的设置,因为将它写入YAML文件(IMO)更容易。 以上是一个以docker-compose.yml格式重写的例子:

 version: '2' services: redis: image: <IMAGE ID> networks: - my_redis_app ports: 6379:6379 ubuntu: image: ubuntu:latest networks: - my_redis_app networks: my_redis_app: driver: bridge 

有了这个,您可以运行docker-compose up -d redis并使用特定的Dockernetworking在线提供redis服务。 撰写将为您创buildnetworking,如果它不存在。

以这种方式运行Ubuntu容器是没有意义的……当然,它是交互式的。 但是我认为一旦你有了redis,你将会添加一些应用程序容器,或者像nginx这样的web代理,只要把其他的services也放到services中,你就可以一起pipe理它们。

由于ubuntu是交互式的,你可以交互地运行它:

 # without -d, container is run interactively docker-compose run ubuntu bash 

现在在Ubuntu中,你应该能够使用它的名字来连接到redis,在这个例子中, redis是简单的。