Flask Docker - 2 Containers Communication - ConnectionError: HTTPConnectionPool: Max retries exceeded with url:

Flask Docker - 2 Containers Communication - ConnectionError: HTTPConnectionPool: Max retries exceeded with url:

所以...我正在测试 2 个容器中的 2 个 Flask 应用程序之间的通信。我的想法是让 WebApp 向 DataService 应用程序发送 GET 请求并显示结果。我运行从独立的容器中安装这两项服务。

当我访问我的 WebApp 路由时,出现错误:“ConnectionError: HTTPConnectionPool: Max retries exceeded with url”。

相关代码见下方:

应用 1:数据服务

from flask import Flask, json

app = Flask(__name__)

@app.route("/data")
def index():
    data = {"id": "testID", "value": "testValue"}
    return json.dumps(data)

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

App2:网络服务

from flask import Flask
import requests

app = Flask(__name__)

@app.route('/app')
def index():
    r = requests.get('http://0.0.0.0:5001/data')
    return r.text

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

我不使用 docker-compose,所以我正在独立构建 2 个容器。

App1 和 App2 Dockerfile 完全一样:

FROM ubuntu:16.04
MAINTAINER me "my@email.com"
RUN apt-get update -y && \
    apt-get install -y python-pip python-dev
COPY ./requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip install -r requirements.txt
COPY . /app
ENTRYPOINT ["python"]
CMD ["main.py"]

I 运行 容器并将 WebService 分配给端口 5000,将 DataService 分配给端口 5001。

sudo docker run -d -p 5000:5000 web
sudo docker run -d -p 5001:5000 data

如果我直接从浏览器 (http://0.0.0.0:5001/data) I get the expected result, but when I try to access it from the WebApp route (http://0.0.0.0:5000/app) 转到我的 DataService 路由,我会收到以下错误:

ConnectionError: HTTPConnectionPool(host='0.0.0.0', port=5001): Max retries exceeded with url: /data (由NewConnectionError('引起: 建立新连接失败:[Errno 111] 连接被拒绝',))

我尝试在来自 webapp 服务的请求 URL 中使用容器名称,但出现了同样的错误。像这样:

def index():
    r = requests.get('http://data_service_container_name:5001/data')
    return r.text

有什么想法吗?

提前致谢!

您启动两个容器的方式 (docker run -d -p 5000:5000 ...) 会将两个容器附加到默认桥接网络。

如果您发出 docker network inspect bridge 命令,您将在容器部分下找到 2 个容器。

在默认桥接网络上,容器可以通过容器 IP 相互查看。这意味着如果您将容器 IP 放入您的请求 URL,那么您的请求应该通过。如果你 docker container inspect <container_name> 运行 容器,你可以获得数据容器的容器 IP。

更好的选择是创建您自己的用户定义网络。只需发出 docker network create mynetwork,您就会在 docker network ls.

中看到一个新网络

在用户定义的网络上,容器可以通过容器名称(和 IP)相互查看。所以这一次,如果您使用 docker run -d -p 5000:5000 --network mynetwork ... 之类的命令启动容器,那么您可以在请求中使用容器名称 URL.

您甚至可以使用 docker run -d -p 5000:5000 --network mynetwork --name data_container ... 之类的命令为数据容器定义容器名称。

为了使它更 Docker 喜欢,我建议使用 Compose。这种情况下不需要定义容器名,因为compose启动的容器可以通过服务名相互访问。 Compose 将自动创建自定义桥接网络,但您也可以定义自己的网络。