macOS 10.12上的两个Docker容器之间的通信 [英] Communication between two Docker containers on macOS 10.12
问题描述
即使遵循几个教程(并阅读了解如何 docker0
isn我无法连接两个容器。
我开始使用我的 redis
image :
docker run -d -p 6379:6379(IMAGE ID)
/ pre>
在我的
redis
图像中,我有:CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dffb89854618 d59docker-entrypoint.sh20秒前上19秒0.0.0.0:6379->6379/tcp drunk_williams
和从我的Mac 我可以通过
redis-cli
命令成功连接,而不会出现问题。
然而,当我启动一个简单的
ubuntu
图像,我似乎无法连接到这个单独的redis
image:root @ 2d4eda315f4f:/#ifconfig
eth0链接封装:以太网HWaddr 02:42:ac:11:00:03
inet addr: 172.17.0.3播放:0.0.0.0掩码:255.255.0.0
inet6 addr:fe80 :: 42:acff:fe11:3/64范围:链接
UP BROADCAST RUNNING MULTICAST MTU:1500公制:1
RX数据包:20707错误:0丢弃:0超支:0帧:0
TX数据包:11515错误:0丢弃:0超支:0运营商:0
碰撞:0 txqueuelen:0
RX字节:28252929(28.2 MB)TX字节:635848(635.8 KB)
lo链接encap:本地环回
inet addr:127.0.0.1掩码:255.0.0.0
inet6 addr :: :: 1/128范围:主机
UP LOOPBACK RUNNING MTU:65536公制:1
RX数据包:12错误:0丢弃:0超限:0帧:0
TX数据包:12错误:0丢弃:0超支:0运营商:0
碰撞:0 txqueuelen:1
RX字节:680(680.0 B)TX字节:680(680.0 B)
root @ 2d4eda315f4f:/#telnet localhost 6379
Trying :: 1 ...
尝试127.0.0.1 ...
telnet:无法连接到远程主机:拒绝连接
root @ 2d4eda315f4f:/#telnet 172.17.0.3 6379
尝试172.17.0.3 ...
telnet:无法连接到远程主机:连接拒绝
这是不是没有
docker0
接口在主机中可用?是否有一些简单的解决方法允许这些容器在开发环境中进行通信(在同一台主机上运行时)?
更新:尝试要使用命名容器,我仍然无法连接。
docker run -d --name redis_server redis
结果:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d05820aa985 redisdocker-entrypoint.sh43小时前Up 1秒6379 / tcp redis_server
但是,如果我启动一个新的Ubuntu容器:
root @ e92b47419bc4:/ #redis-cli -h redis_server
无法连接到redis_server的Redis:6379:名称或服务未知
我不知道如何找到/连接到第一个
re
解决方案
每个容器都有自己的localhost
每个服务都在自己的容器中运行。从Ubuntu容器的角度来说,redis不在本地主机上收听。
使用Docker网络
你的容器进行通信,他们应该在同一个Docker网络上。这包括三个步骤:
- 创建Docker网络
- 提供容器名称
- 将您的容器附加到您创建的网络上
完成后,容器可以互相交谈使用他们的名字,就像他们是主机名。
有不止一种方式来皮肤这只猫...我会在这个答案中看两个,但可能有一个很少有其他方式做,我不熟悉(比如使用Kubernetes或Swarm)。
手工执行
您可以使用
docker network
命令为此应用程序创建一个网络。#显示当前的网络列表
docker network ls
#为您的应用程序创建一个网络
docker network create my_redis_app
当您运行redis容器时,请确保它有一个名称,并且在是网络如果你想要(使用
-p
),你可以外部暴露端口(对于macOS),但是这对于其他容器来说与redis是不必要的。docker run -d -p 6379:6379 --name redis_server --network my_redis_app< IMAGE ID>
现在运行Ubuntu容器。如果你喜欢,你可以命名它,但是我不会打扰这个例子,因为这个没有运行任何服务。
docker运行-it --network my_redis_app ubuntu bash
现在从Ubuntu容器里面你应该能够使用名称
redis_server
来达到redis,就好像它是一个DNS名称。
使用撰写
我倾向于使用Compose构建这样的设置,因为将它更容易地写入YAML文件(IMO)。这是上面的一个例子,重新写在docker-compose.yml表单中:
version :'2'
services:
redis:
image:< IMAGE ID>
网络:
- my_redis_app
端口:6379:6379
ubuntu:
图像:ubuntu:最新
网络:
- my_redis_app
网络:
my_redis_app:
驱动程序:桥
,您可以运行
docker-compos up -d redis
,并使用特定的Docker网络将redis服务联机。如果文件不存在,Compose将为您创建网络。
以这种方式运行Ubuntu容器不太有意义...它是交互式的,课程。但是,假设一旦你重新启动,你将添加一些应用程序容器,也许像nginx这样的web代理,只是将其他人放在
服务
下,您可以一起管理它们。
由于
ubuntu
是交互式的,您可以以交互方式运行它:#没有-d,容器以交互方式运行
docker-compose运行ubuntu bash
现在在Ubuntu中,您应该能够使用其名称连接到redis,在这个例子中,这个名字只是
redis
。I'm working with Docker 1.12.5 on macOS 10.12, and am setting up a development environment with with I have an application image, and a shared redis image which has some pre-populated configuration variables.
Even after following a few tutorials (and reading about how
docker0
isn't available on Mac) I'm struggling to connect the two containers.I start my
redis
image using:docker run -d -p 6379:6379 (IMAGE ID)
In my
redis
image, I have: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
And from my Mac I can successfully connect via the
redis-cli
command without issue.However when I start a simple
ubuntu
image, I can't seem to connect to this separateredis
image: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
Is this a result of not having the
docker0
interface available in the host? Is there some straightforward workaround for allowing these containers to communicate (when being run on the same host) in a development environment?Update: Attempting to use named containers, I still can't connect.
docker run -d --name redis_server redis
Results in:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5d05820aa985 redis "docker-entrypoint.sh" 43 hours ago Up 1 seconds 6379/tcp redis_server
But then if I start a new Ubuntu container:
root@e92b47419bc4:/# redis-cli -h redis_server Could not connect to Redis at redis_server:6379: Name or service not known
I'm not sure how to find/connect to the first
redis_server
container.解决方案Each container has its own localhost
Each service runs in its own container. From the perspective of the Ubuntu container, redis is not listening on localhost.
Use Docker networks
To get your containers to communicate, they should be on the same Docker network. This consists of three steps:
- Create a Docker network
- Give your containers names
- Attach your containers to the network you created
With this done, the containers can talk to each other using their names as if they were hostnames.
There's more than one way to skin this cat... I will look at two in this answer, but there are probably a few other ways to do it that I am not familiar with (like using Kubernetes or Swarm, for instance).
Doing it by hand
You can create a network for this application using
docker network
commands.# Show the current list of networks docker network ls # Create a network for your app docker network create my_redis_app
When you run the redis container, make sure it has a name, and is on this network. You can expose the ports externally (to macOS) if you want to (using
-p
), but that is not necessary just for other containers to talk to redis.docker run -d -p 6379:6379 --name redis_server --network my_redis_app <IMAGE ID>
Now run your Ubuntu container. You can name it as well if you like, but I won't bother in this example because this one isn't running any services.
docker run -it --network my_redis_app ubuntu bash
Now from inside the Ubuntu container, you should be able to reach redis using the name
redis_server
, as if it were a DNS name.Doing it using Compose
I tend to build setups like this using Compose, because it's easier to write it into a YAML file (IMO). Here's an example of the above, re-written in docker-compose.yml form:
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
With this in place, you can run
docker-compose up -d redis
and have your redis service online using a specific Docker network. Compose will create the network for you, if it doesn't already exist.It makes less sense to run the Ubuntu container that way... it is interactive, of course. But I assume once you have redis going, you will add some kind of application container, and perhaps a web proxy like nginx... just put the others under
services
as well, and you can manage them all together.Since
ubuntu
is interactive, you can run it interactively:# without -d, container is run interactively docker-compose run ubuntu bash
And now in Ubuntu, you should be able to connect to redis using its name, which in this example is simply
redis
.这篇关于macOS 10.12上的两个Docker容器之间的通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!