首页 > 解决方案 > 两个独立的 Flask 应用程序在 docker 容器中通信

问题描述

编辑:

如下所示,我设法让它network_mode: "host"用于两个容器。现在这很好。但是,我觉得这是一个糟糕的 hack,我想更多地了解我在容器上做错了什么而不是 hack。


我在让我的两个 Flask 应用程序在两个单独的 Docker 容器中通信时遇到问题。我已经从 dockerm1容器外部运行 app.py 并且它可以工作,但显然需要做一些不同的事情才能在 docker 容器外部进行通信。

我得到这个回溯:

Traceback (most recent call last):
m1_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
m1_1  |     return self.wsgi_app(environ, start_response)
m1_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
m1_1  |     response = self.handle_exception(e)
m1_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
m1_1  |     reraise(exc_type, exc_value, tb)
m1_1  |   File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
m1_1  |     raise value
m1_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
m1_1  |     response = self.full_dispatch_request()
m1_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
m1_1  |     rv = self.handle_user_exception(e)
m1_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
m1_1  |     reraise(exc_type, exc_value, tb)
m1_1  |   File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
m1_1  |     raise value
m1_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
m1_1  |     rv = self.dispatch_request()
m1_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
m1_1  |     return self.view_functions[rule.endpoint](**req.view_args)
m1_1  |   File "/app/app.py", line 11, in home
m1_1  |     res = requests.get(url)
m1_1  |   File "/usr/local/lib/python3.6/site-packages/requests/api.py", line 75, in get
m1_1  |     return request('get', url, params=params, **kwargs)
m1_1  |   File "/usr/local/lib/python3.6/site-packages/requests/api.py", line 60, in request
m1_1  |     return session.request(method=method, url=url, **kwargs)
m1_1  |   File "/usr/local/lib/python3.6/site-packages/requests/sessions.py", line 533, in request
m1_1  |     resp = self.send(prep, **send_kwargs)
m1_1  |   File "/usr/local/lib/python3.6/site-packages/requests/sessions.py", line 646, in send
m1_1  |     r = adapter.send(request, **kwargs)
m1_1  |   File "/usr/local/lib/python3.6/site-packages/requests/adapters.py", line 516, in send
m1_1  |     raise ConnectionError(e, request=request)
m1_1  | requests.exceptions.ConnectionError: HTTPConnectionPool(host='127.0.0.1', port=8002): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7ff58dd1bd30>: Failed to establish a new connection: [Errno 111] Connection refused',))

来自 m1 的 app.py

from flask import Flask, jsonify
import requests
import json

app = Flask(__name__)


@app.route("/")
def home():
    url = "http://127.0.0.1:8002/"
    res = requests.get(url)
    dictFromServer = res.json()
    return dictFromServer['message']


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

来自 m2 的 app.py

from flask import Flask, jsonify

app = Flask(__name__)


@app.route('/')
def hello_world():
    return jsonify({ 'message': 'Hello From M2'})


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

dockerfile(s)

FROM python:3.6-alpine
WORKDIR /app
COPY requirements.txt /app
COPY app.py /app
RUN pip install -r requirements.txt
EXPOSE 5000
ENTRYPOINT ["python"]
CMD ["app.py"]

码头工人撰写

version: '3'

services:
      m1:
        build: m1
        ports:
          - "8001:5000"
      m2:
        build: m2
        ports:
          - "8002:5000"

标签: pythonrestapidockerflask

解决方案


Docker 容器不使用相同的 IP 地址运行,因此 m1 中的 127.0.0.1 仅解析为 m1 容器。

两个修复:

  1. 两个容器的“network:host”都将使用主机网络堆栈,因此 m1 和 m2 将具有相同的 IP 地址。然后“127.0.0.1”将起作用。

  2. 将“127.0.0.1”替换为“m2”。这将使用内置的 DNS 服务器并为 m2 容器解析正确的 IP 地址。这种方法的另一个好处是两个容器可以使用相同的端口,因为它们具有不同的地址。


推荐阅读