首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Docker网络,困惑和困惑

Docker网络,困惑和困惑
EN

Stack Overflow用户
提问于 2020-01-31 19:25:08
回答 2查看 133关注 0票数 0

我有一个简单的python应用程序,它在Elasticsearch实例中存储和搜索它的数据。python应用程序在它自己的容器中运行,就像Elasticsearch一样。Elasticsearch公开了它的默认端口9200和9300,python应用程序公开了5000端口。Docker使用的networktype是用户定义的桥接网络。当我启动这两个容器时,应用程序启动得很好,两个容器都可以通过容器名称看到对方,并且可以很好地通信。

但是从docker主机(linux)不可能连接到暴露的端口5000。因此,一个简单的curl http://localhost:5000/在超时中呈现。本文档中的Docker提示:https://docs.docker.com/network/bridge/没有解决这个问题。

经过许多努力,我尝试了一些完全不同的东西,我尝试从docker主机的外部连接到python应用程序。我很困惑,在世界上的任何地方我都可以做curl http://<fqdn>:5000/,然后我得到了这个应用程序。这意味着,真正的问题解决了,因为我能够为外部世界提供应用程序。(所以,是的,容器内的应用程序侦听0.0.0.0,因为这是其他人报告的90%的网络问题的解决方案。)

但这仍然让我感到困惑,是什么导致了这种奇怪的行为?在我的开发机器(Windows10、WSL、Docker桌面、Linux容器)上,我能够连接到localhost:5000、127.0.0.1:5000等上的服务。在我的Linux (生产)机器上,除了从docker主机连接到容器之外,一切都可以正常工作。

我希望有人能阐明这一点,我试图理解为什么会发生这种情况。

一些相关信息

Docker主机:

代码语言:javascript
复制
#  ifconfig -a
br-77127ce4b631: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
[snip] 
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
[snip]
ens3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 1xx.1xx.199.134  netmask 255.255.255.0  broadcast 1xx.1xx.199.255

# docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                                            NAMES
1e7f2f7a271b        pplbase_api           "flask run --host=0.…"   20 hours ago        Up 19 hours         0.0.0.0:5000->5000/tcp                           pplbase_api_1
fdfa10b1ce99        elasticsearch:7.5.1   "/usr/local/bin/dock…"   21 hours ago        Up 19 hours         0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   pplbase_elastic_1

# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
[snip]
77127ce4b631        pplbase_pplbase     bridge              local

# iptables -L -n
[snip]
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:5000
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
DOCKER-USER  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION-STAGE-1  all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0

Chain DOCKER (2 references)
target     prot opt source               destination
ACCEPT     tcp  --  0.0.0.0/0            172.18.0.2           tcp dpt:9300
ACCEPT     tcp  --  0.0.0.0/0            172.18.0.2           tcp dpt:9200
ACCEPT     tcp  --  0.0.0.0/0            172.18.0.3           tcp dpt:5000

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0
DOCKER-ISOLATION-STAGE-2  all  --  0.0.0.0/0            0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target     prot opt source               destination
DROP       all  --  0.0.0.0/0            0.0.0.0/0
DROP       all  --  0.0.0.0/0            0.0.0.0/0
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  0.0.0.0/0            0.0.0.0/0

Docker撰写文件:

代码语言:javascript
复制
version: '3'
services:
  api:
    build: .
    links:
      - elastic
    ports:
      - "5000:5000"
    networks:
      - pplbase
    environment:
      - ELASTIC_HOSTS=elastic localhost
      - FLASK_APP=app.py
      - FLASK_ENV=development
      - FLASK_DEBUG=0
    tty: true


  elastic:
    image: "elasticsearch:7.5.1"
    ports:
      - "9200:9200"
      - "9300:9300"
    networks:
      - pplbase
    environment:
      - discovery.type=single-node
    volumes:
      - ${PPLBASE_STORE}:/usr/share/elasticsearch/data

networks:
  pplbase:
    driver: bridge

经过更多的挖掘,这个谜语变得越来越大。使用netcat时,我可以建立连接

代码语言:javascript
复制
Connection to 127.0.0.1 5000 port [tcp/*] succeeded!

在未连接任何客户端时使用netstat进行检查,请参见:

代码语言:javascript
复制
tcp6       0      0 :::5000                 :::*                    LISTEN      27824/docker-proxy

尝试从dockerhost连接时,会建立连接:

代码语言:javascript
复制
tcp        0      1 172.20.0.1:56866        172.20.0.3:5000         SYN_SENT    27824/docker-proxy
tcp6       0      0 :::5000                 :::*                    LISTEN      27824/docker-proxy
tcp6       0      0 ::1:58900               ::1:5000                ESTABLISHED 31642/links
tcp6     592      0 ::1:5000                ::1:58900               ESTABLISHED 27824/docker-proxy

所以我现在怀疑码头主机上有什么网络巫毒。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-04 21:50:26

因此,当我在这个问题上努力的时候,慢慢地朝着一个解决方案前进,我发现我的上一个建议毕竟是正确的。在防火墙( iptables )中,我记录了所有丢弃的数据包,是的,扩展坞网桥(不是docker0,而是br- )和容器(veth)之间的数据包正在被iptables丢弃。添加允许来自接口的流量的规则解决了该问题。

在我的例子中:sudo iptables -I INPUT 3 -s 172.20.0.3 -d 172.20.0.1 -j ACCEPT,其中172.20.0.0/32是Docker生成的桥接网络。

票数 0
EN

Stack Overflow用户

发布于 2020-01-31 21:37:17

Flask实例正在0.0.0.0:5000上运行。你试过了吗:curl http://0.0.0.0:5000/

可能是您的主机配置使用127.0.0.1而不是0.0.0.0映射本地主机

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60002968

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档