socket.error:[errno 99]无法分配请求的地址:Flask和Python

4

我遇到了和这里这里相同的问题。

我正在尝试在docker容器内运行一个flask应用程序。当使用'0.0.0.0'时可以正常工作,但使用我的ip地址时会出现错误。

我在公司代理后面。当我使用ipconfig检查我的ip地址时,它显示为:10.***.**.**,而我使用的是docker工具箱,我的容器ip为172.17.0.2,VM IP地址为192.168.99.100。

我有一个flask应用程序在此docker中运行,主机为

if __name__ == "__main__":
    app.run(host= '0.0.0.0')

工作正常。但当我将其更改为我的IP地址时

if __name__ == "__main__":
        app.run(host= '10.***.**')

出现错误:

socket.error:[errno 99] 无法分配请求的地址

我使用一个简单的 Flask 应用程序再次检查了 IP 地址,该应用程序在本地运行(即不使用 Docker)。

 if __name__ == "__main__":
            app.run(host= '10.***.**')

它正常工作。

所以问题只出现在 Docker 中运行时。这是因为我在路由器后面运行 NAT,使用内部 IP 地址。如何使用 NAT 找到此内部 IP 地址?我已经为 Flask 应用程序进行了端口转发,端口为 5000。

> iptables -t nat -A DOCKER -p tcp --dport 5000 -j DNAT --to-destination 172.17.0.2:5000
> iptables -t nat -A POSTROUTING -j MASQUERADE -p tcp --source 172.17.0.2 --destination 172.17.0.2 --dport https
> iptables -A DOCKER -j ACCEPT -p tcp --destination 172.17.0.2 --dport https

看起来这种操作与Docker容器网络驱动不兼容(https://docs.docker.com/network/#network-drivers)。尝试更改一下。其次,为什么需要指定某些IP地址而不是0.0.0.0,它意味着“监听所有接口”?因此,如果需要在LAN上访问应用程序,则可以使用0.0.0.0,而只需从本地主机访问服务,则可以使用127.0.0.1。 - Artsiom Praneuski
我想让其他计算机连接到这个API。我能用“0.0.0.0”或“127.0.0.1”来实现吗? - dhinar1991
2
是的,要让局域网中的其他计算机连接到您的服务,只需在app.run()函数中使用0.0.0.0地址,并将所需端口从docker容器暴露到宿主PC。要暴露端口,您需要1)在Dockerfile中指定EXPOSE指令,并且2)以-p <port_on_host>:<port_in_container>运行容器。在这里,您可以找到简单的示例:https://docs.docker.com/engine/reference/builder/#expose 请告诉我是否可以将此评论作为您问题的答案发布。 - Artsiom Praneuski
我明白了。谢谢。 - dhinar1991
2个回答

3

如果想让局域网中的其他计算机连接到您的服务,请在app.run()函数中使用0.0.0.0地址,并将所需端口从Docker容器暴露到主机PC。

要暴露端口,您需要:

1)在Dockerfile中指定EXPOSE指令

2)使用-p <port_on_host>:<port_in_container>参数运行容器。

例如:

Dockerfile:

FROM ubuntu:17.10

RUN apt-get update && apt-get install -y apache2

EXPOSE 80

ENTRYPOINT ["/usr/sbin/apache2ctl"]
CMD ["-D", "FOREGROUND"]

构建:

docker build -t image_name .

运行:

docker run -d -p 80:80 image_name

检查:

curl http://localhost

注意在运行容器之前确保主机PC上的80端口没有被其他应用程序占用。如果此端口已经被使用,请指定另一个端口,例如8080

docker run -d -p 8080:80 image_name

然后进行检查:

curl http://localhost:8080

文档在这里


0

OSError [Errno 99] - python的答案在这里也适用。

如果使用IP地址可以工作,但使用主机名则不行。

删除/etc/hosts中的重复本地主机应该是解决方案。hosts文件应该类似于以下内容(将IP映射到主机名)

127.0.0.1   localhost
127.0.1.1   your_hostname_here

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

@'Artsiom Praneuski'的回答仅涉及Docker配置,这在Docker容器设置中非常相关,但并未指向Python环境修复(包括容器和普通设置)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接