macOS 10.12上的两个Docker容器之间的通信 [英] Communication between two Docker containers on macOS 10.12

查看:988
本文介绍了macOS 10.12上的两个Docker容器之间的通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在与macOS 10.12上的Docker 1.12.5一起工作,并且正在设置一个开发环境,我有一个应用程序图像和一个共享的 redis 图像它有一些预先填充的配置变量。



即使遵循几个教程(并阅读了解如何 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网络上。这包括三个步骤:


  1. 创建Docker网络

  2. 提供容器名称

  3. 将您的容器附加到您创建的网络上

完成后,容器可以互相交谈使用他们的名字,就像他们是主机名。



有不止一种方式来皮肤这只猫...我会在这个答案中看两个,但可能有一个很少有其他方式做,我不熟悉(比如使用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 separate redis 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:

  1. Create a Docker network
  2. Give your containers names
  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆