【问题标题】:Connection between flask applications running on different containers在不同容器上运行的烧瓶应用程序之间的连接
【发布时间】:2019-09-15 16:56:01
【问题描述】:

我有 2 个烧瓶应用程序在不同的容器上运行。当我尝试从一个容器向另一个容器发出 API 请求时,出现以下错误:

HTTPConnectionPool(host='0.0.0.0', port=5001): Max retries exceeded with url: / (Caused by NewConnectionError(': 无法建立新连接: [Errno 111] Connection refused'))

烧瓶应用程序1:

app.route("/", methods=["GET"])
@cross_origin(supports_credentials=True)
def ads():
    r=requests.get('http://0.0.0.0:5001/',verify=False)
    return jsonify(r.text)

烧瓶应用程序2:

app.route("/", methods=["GET"])
@cross_origin(supports_credentials=True)
def add2():
    return jsonify('Success!')

app1 的 Docker 文件:

FROM alpine:latest
RUN apk add --no-cache python3-dev \
    && pip3 install --upgrade pip
WORKDIR /
COPY . .
RUN pip3 --no-cache-dir install -r requirements.txt                                                                            
EXPOSE 5000
ENTRYPOINT  ["python3"]
CMD ["app.py","--host", "0.0.0.0"]

app2 的 Docker 文件:

FROM alpine:latest
RUN apk add --no-cache python3-dev \
    && pip3 install --upgrade pip
WORKDIR /
COPY . .
RUN pip3 --no-cache-dir install -r requirements.txt                                                                            
EXPOSE 5001
ENTRYPOINT  ["python3"]
CMD ["app.py","--host", "0.0.0.0"]

使用的docker命令有:

docker run -p 5000:5000 app1
docker run -p 5001:5001 app2

如何在不使用 docker-compose 的情况下解决此错误?

【问题讨论】:

  • 0.0.0.0 不是有效 IP,您需要获取另一个容器的主机名才能与之通信
  • @FranciscoCouzo 我在本地机器上运行这两个容器。我也尝试了 localhost 而不是 0.0.0.0,但仍然遇到相同的错误
  • @Chetanrns,无论您是否在本地计算机上运行它们都无关紧要。您永远无法向0.0.0.0 提出请求。

标签: python docker flask python-requests linux-containers


【解决方案1】:

您需要create some non-default Docker network 并将两个容器附加到它。

停止并删除这两个容器。 (这是一项非常常规的任务,尤其是对于这种更改;您应该确保没有数据实际上存储在容器文件系统中,因为它会丢失。)然后创建网络并创建两个容器,附加到它,使用明确的名称:

docker network create app
docker run --net app --name app1 -p 5000:5000 app1
docker run --net app --name app2 -p 5001:5001 app2

现在这两个容器将能够使用它们的--name 作为主机名来访问其他容器。你可以打电话给例如

requests.get('http://app2:5001/')

为了支持在 Docker 和非 Docker 世界中工作,我建议将此值设为可配置。您可以将其默认为 localhost 类型的地址,您可以使用该地址在 Docker 之外运行这两个容器。

app2_url = os.environ.get('APP2_URL', 'http://localhost:5001')
requests.get(app2_url)
docker run ... -e APP2_URL='http://app2:5001/' app1

(当你开始构建这样的 docker run 命令时,Docker Compose 开始看起来很有吸引力;它主要是相同内容的声明性 YAML 格式。但实际上并不是必需的。)

【讨论】:

    【解决方案2】:

    尝试使用您的 IPv4 地址。它会工作

    app.route("/", methods=["GET"])
    @cross_origin(supports_credentials=True)
    def ads():
        r=requests.get('192.168.10.7:5001/',verify=False)
        return jsonify(r.text)
    

    您可以在您的机器上找到您的 ipv4, The IPv4 Address

    或者您可以使用 ifconfig

    从终端获取

    【讨论】:

    • 特别是在 Docker 上下文中,IP 地址很难定期查找和更改;试图找到它们根本不是最佳做法。 (更好的答案会解释如何找到它以及为什么它是必要的。)
    • 你的方法是对的,但他问我如何调用其他容器,他正在尝试使用 localhost 等。这就是为什么我告诉他使用你的 ipv4
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 2019-12-04
    • 2022-01-25
    • 1970-01-01
    • 2016-12-09
    • 2019-07-13
    • 2018-12-13
    相关资源
    最近更新 更多