这主要是一个docker网络问题,并不是特定于pyzmq或zeromq。尝试从容器连接到主机的任何事情都会遇到同样的问题。
要清楚,在这个例子中,你有一个 服务器 在主机上运行(zmq_sub.py,它调用bind),并且您希望从在docker容器(zmq_pub.py)内运行的客户端连接到它。
由于docker容器是连接器,因此您无需进行任何Docker端口的公开或转发。 EXPOSE和转发端口仅用于连接 至 一个容器(即 bind 在容器中调用,而不是进行出站连接 从 一个容器,这就是这里发生的事情。
bind
这里的主要内容是,当涉及到与docker联网时,您应该将每个容器视为本地网络上的单独机器。为了可以从其他容器或主机连接,服务应该 捆绑 到所有接口(或至少一个可访问的接口)。绑定在容器中的localhost意味着只有其他进程 在那个容器里 应该能够与它交谈。同样,在主机上绑定localhost意味着docker容器不能连接。
所以第一个改变是你的绑定网址应该是:
url = 'tcp://0.0.0.0:5550' ... socket.bind(url)
或者选择与docker虚拟网络对应的IP地址。
然后,你的 connect 从容器中看,url需要是主机的ip。这可以通过 ifconfig 。通常任何IP地址都可以,但如果你有 docker0 网络,这将是合乎逻辑的选择。
connect
ifconfig
docker0
我遇到了同样的问题 这个帖子 。
你的问题是容器localhost( 127.0.0.1 )与其他容器或主机localhost有所不同。
127.0.0.1
所以要克服这个问题,请使用 tcp://*:5550 在里面 .bind() 代替 127.0.0.1 或机器IP。
tcp://*:5550
.bind()
然后,你应该创建一个公开IP并声明在容器和主机之间分配IP(我使用docker-compose在上面提到的SO帖子上做这个)。我认为在您的情况下,您将尝试以下内容:
EXPOSE 5550
和
sudo docker run -p 5550:5550 -it foo/bar