【发布时间】:2021-04-14 23:03:58
【问题描述】:
我有一个 Django REST 服务和另一个用作应用程序代理的 Flask 服务。两者都是使用自己的 Docker 容器运行的不同项目。 我可以在 Flask 服务使用的 Django 服务上发布产品,但是,我无法通过 Flask 访问 Django 服务。 这些容器在同一个网络上运行,我已经尝试过Thomasleveil's 的建议,包括docker-host by qoomon。 请求收到的错误与我尝试转发流量之前的错误相同。不同的是,现在当我发出请求时,它会一直挂起一段时间,直到失败。
错误如下:
requests.exceptions.ConnectionError: HTTPConnectionPool(host='172.17.0.1', port=8000): Max retries exceeded with url: /api/user (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f0039388340>: Failed to establish a new connection: [Errno 110] Connection timed out'))
我试图发出的请求是 /api/products/1/like 的 POST。目前,不需要实体。
这是我使用 Flask 进行 POST 的方式,其中 IP 是 Docker IP:
@app.route("/api/products/<int:id>/like", methods=["POST"])
def like(id):
req = requests.get("http://172.17.0.1:8000/api/user")
json = req.json()
try:
product_user = ProductUser(user_id=json["id"], product=id)
db.session.add(product_user)
db.session.commit()
publish("product_liked", id)
except:
abort(400, "You already liked this product")
return jsonify({
"message": "success"
})
Django 的 docker compose 文件(请忽略服务 tcp_message_emitter):
version: '3.8'
services:
backend:
build:
context: .
dockerfile: Dockerfile
command: "python manage.py runserver 0.0.0.0:8000"
ports:
- 8000:8000
volumes:
- .:/app
depends_on:
- db
queue:
build:
context: .
dockerfile: Dockerfile
command: "python consumer.py"
depends_on:
- db
db:
image: mysql:5.7.22
restart: always
environment:
MYSQL_DATABASE: admin
MYSQL_USER: root
MYSQL_PASSWORD: root
MYSQL_ROOT_PASSWORD: root
volumes:
- .dbdata:/var/lib/mysql
ports:
- 33066:3306
dockerhost:
image: qoomon/docker-host
cap_add:
- NET_ADMIN
- NET_RAW
restart: on-failure
networks:
- backend
tcp_message_emitter:
image: alpine
depends_on:
- dockerhost
command: [ "sh", "-c", "while :; do date; sleep 1; done | nc 'dockerhost' 2323 -v"]
networks:
- backend
networks:
backend:
driver: bridge
Flask 的 docker compose 文件:
version: '3.8'
services:
backend:
build:
context: .
dockerfile: Dockerfile
command: "python main.py"
ports:
- 8001:5000
volumes:
- .:/app
depends_on:
- db
queue:
build:
context: .
dockerfile: Dockerfile
command: "python consumer.py"
depends_on:
- db
db:
image: mysql:5.7.22
restart: always
environment:
MYSQL_DATABASE: main
MYSQL_USER: root
MYSQL_PASSWORD: root
MYSQL_ROOT_PASSWORD: root
volumes:
- .dbdata:/var/lib/mysql
ports:
- 33067:3306
此时,我知道我遗漏了一些细节或配置错误。
您可以在这里查看 repo:https://github.com/lfbatista/ms-ecommerce
任何帮助将不胜感激。
【问题讨论】:
-
IP地址172.17.0.1从哪里来?你能像Communication between multiple docker-compose projects 中描述的那样在同一个网络上运行这两个 Compose 文件吗?
-
172.17.0.1 是我在使用镜像 docker-host 时获得的 Django 的 Docker IP。您可以获得运行
docker network inspect bridge --format='{{( index .IPAM.Config 0).Gateway}}'的IP。我会试试你的建议。 -
您可能需要查看
django_default网络(即 Compose 为 Django-application Compose 文件创建的default网络)。它将不同于“默认桥接网络”(如果您拆除并重新创建这些容器集,它将不会保持不变)。 -
您不应该在代码中硬编码容器 IP 地址。这就是名称解析的用途。如果您将所有容器放在同一个网络上,它们将能够通过名称相互引用。
-
@DavidMaze 如果我在我的 Django docker compose 文件上设置一个新网络,就像在 [多个 docker-compose 项目之间的通信](stackoverflow.com/questions/38088279/…) 中那样,我将失去与 MySQL 的连接。事实上,使用
django_default网络似乎是正确的道路。问题是我无法获取容器的 IP。我从上面的命令得到的 IP 是来自default网络的 IP。
标签: python docker networking rabbitmq microservices