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 将自动创建自定义桥接网络,但您也可以定义自己的网络。
所以...我正在测试 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('
我尝试在来自 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 将自动创建自定义桥接网络,但您也可以定义自己的网络。