从另一个容器中的服务连接到 rabbitmq docker 容器

2022-01-11 00:00:00 python docker rabbitmq nameko

问题描述

我已经做了很多搜索,但我无法解决这个问题.

I've done a lot of searching but I cannot fix this issue.

我有一个基本的 Rabbitmq 容器通过这个命令运行:

I have a basic Rabbitmq container running via this command:

docker run -d --hostname rabbitmqhost --name rabbitmq -p 15672:15672 -p 5672:5672 rabbitmq:3-management

我正在使用 nameko 创建一个连接到该容器的微服务.这是一个基本的微服务模块main.py:

I am using nameko to create a microservice which connects to this container. Here's a basic microservice module main.py:

from nameko.rpc import rpc
class Service_Name(object):
    name = "service_name"

    @rpc
    def service_endpoint(self, arg=None):
        logging.info('service_one endpoint, arg = %s', arg)

此服务运行并使用以下命令从我的主机连接到 rabbitmq:

This service runs and connects to the rabbitmq from my host machine with the command:

nameko run main --broker amqp://guest:guest@localhost

我想将服务放入 Docker 容器(称为 service_one),但是当我这样做并运行之前的 nameko 命令时,我得到 socket.error: [Errno 111] ECONNREFUSED 无论我如何尝试链接这两个容器.

I wanted to put the service into a Docker container (called service_one) but when I do so and run the previous nameko command I get socket.error: [Errno 111] ECONNREFUSED no matter how I try and link the two containers.

正确的方法是什么?目的是将每个服务都放在一个容器中,所有服务都通过rabbit相互交谈.谢谢.

What would be the correct method? The aim is to have each service in a container, all talking to each other through rabbit. Thanks.


解决方案

如果你在容器中运行服务,那么 amqp://guest:guest@localhost 就不行了任何好处;localhost 指的是容器的网络命名空间...所以你当然会得到一个 ECONNREFUSED,因为那里没有任何东西在监听.

If you're running a service inside a container, then amqp://guest:guest@localhost won't do you any good; localhost refers to the network namespace of the container...so of course you get an ECONNREFUSED, because there's nothing listening there.

如果要连接到另一个容器中的服务,则需要使用该容器的 ip 地址,或者解析为该容器 ip 地址的主机名.

If you want to connect to a service in another container, you need to use the ip address of that container, or a hostname that resolves to the ip address of that container.

如果您在 用户定义的网络中运行容器,然后 Docker 维护一个 DNS 服务器,它将容器名称映射到地址.也就是说,如果我先创建一个网络:

If you are running your containers in a user-defined network, then Docker maintains a DNS server that will map container names to addresses. That is, if I first create a network:

docker network create myapp_net

然后在该网络中启动一个 rabbitmq 容器:

And then start a rabbitmq container in that network:

docker run -d --network myapp_net --hostname rabbitmqhost 
   --name rabbitmq -p 15672:15672 -p 5672:5672 rabbitmq:3-management

然后在该网络中启动的其他容器将能够使用主机名 rabbitmq 连接到该容器.

Then other containers started in that network will be able to use the hostname rabbitmq to connect to that container.

对于在默认网络中运行的容器(命令行中没有 --network 参数),您可以使用 --link 选项来实现类似的效果,不过如此处所述,灵活性较差,效果较差.

For containers running in the default network (no --network parameter on the command line), you can use the --link option to achieve a similar, though less flexible, effect, as documented here.

相关文章