端口未暴露但在内部docker网络上仍可访问

时间:2019-06-29 01:26:12

标签: python docker flask docker-compose

(我有一个暴露端口的反问题,并且无法访问。)

就我而言,我在同一网络上有2个容器。一个是运行Python Flask应用程序的Alpine Python。另一个是Ubuntu 18.04的准系统。服务的初始化基本上是这样的:

docker-compose.yml

version: '3'

services:
  pythonflask:
    build: someDockerfile # from python:3.6-alpine
    restart: unless-stopped

  ubuntucontainer:
    build: someOtherDockerfile #from ubuntu:18.04
    depends_on:
      - pythonflask
    restart: unless-stopped

Python Flask应用程序在端口5000上运行。 请注意, docker-compose.yml 文件中缺少expose: - 5000。 问题是,从ubuntucontainer内对http://pythonflask:5000进行卷曲时,我能够获得正确的响应

步骤:

$ docker exec -it ubuntucontainer /bin/bash

...然后在容器中...

root@ubuntucontainer:/# curl http://pythonflask:5000/

...正确地从Flask应用返回了我的回复。

但是从运行docker的机器上:

$ curl http://localhost:5000/

不返回任何内容(按预期)。

当我测试不同的端口时,它们每次都会自动暴露。这是做什么的?

2 个答案:

答案 0 :(得分:3)

通过将容器放置在相同的docker网络上并通过容器ip和端口(而不是主机发布的端口)进行通信,可以实现容器之间的连接。那么暴露会做什么呢?

暴露是文档

图像创建者使用docker中的Expose来记录应用程序将在容器内侦听的预期端口。除了某些工具和使用此元数据文档的Docker中的标记外,它不用于控制容器之间的访问或修改Docker的网络。可以在运行时将应用程序重新配置为侦听其他端口,并且您可以连接到尚未公开的端口。

要在容器之间进行DNS查找,需要用户创建网络,而不是docker的默认网络之一(例如,在名为“ bridge”的默认网桥网络中未启用DNS)。使用DNS,您可以查找容器名称,服务名称(从组成文件中)以及在该网络上为此容器创建的任何网络别名。

等式的另一半是在docker中“发布”。这将创建从主机到容器的映射,以允许外部访问。它是通过在主机上运行并转发新连接的代理过程实现的。由于该实现,即使容器未在该端口上侦听,您也可以在主机上发布端口,尽管在这种情况下尝试连接到该端口时会收到错误消息。

答案 1 :(得分:1)

缺少expose: ...只是意味着您在docker-compose.yml中定义的服务组没有暴露任何端口

在您使用的映像中,仍然存在可通过docker-compose自动创建的网络访问的裸露端口。

这就是为什么您要从另一个容器中取出一个容器的原因。另外,每个容器都可以通过服务名称从内部网络上的docker-compose.yml访问。

您不应从主机(http://localhost:5000)访问flask