python - 两个独立的 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"
解决方案
Docker 容器不使用相同的 IP 地址运行,因此 m1 中的 127.0.0.1 仅解析为 m1 容器。
两个修复:
两个容器的“network:host”都将使用主机网络堆栈,因此 m1 和 m2 将具有相同的 IP 地址。然后“127.0.0.1”将起作用。
将“127.0.0.1”替换为“m2”。这将使用内置的 DNS 服务器并为 m2 容器解析正确的 IP 地址。这种方法的另一个好处是两个容器可以使用相同的端口,因为它们具有不同的地址。
推荐阅读
- docker - 如何调试 DNS 不适用于 Docker 容器?
- python - 根据 Python 中的查找值替换所有文件中的列名
- decompiling - 任何人都可以识别此代码片段的编程语言吗?
- r - 使用前 50 行计算 R 中的运行平均值
- android-studio - 设置为不将 gmail 发送到特定的 gmail
- amazon-web-services - HashiCorp Vault 创建用户以登录 AWS 管理控制台
- javascript - 从 API 中提取数据
- java - Spring-Boot WebFlux getFormData fails to parse real x-www-form-urlencoded data?
- node.js - 使用 socks5 时的 Request-Promise 库错误:- RequestError:错误:getaddrinfo ENOTFOUND
- c++ - C2011 'class' 类型重新定义