Docker сеть, озадачен и озадачен - PullRequest
0 голосов
/ 31 января 2020

У меня есть простое python приложение, которое хранит и ищет свои данные в экземпляре Elasticsearch. Приложение python работает в своем собственном контейнере, как и Elasticsearch. Elasticsearch предоставляет порты по умолчанию 9200 и 9300, приложение python предоставляет порт 5000. Тип сети, используемый для Docker, - это пользовательская мостовая сеть. Когда я запускаю оба контейнера, приложение хорошо запускается, оба контейнера видят друг друга по имени контейнера и нормально общаются.

Но с хоста 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% проблем сети, о которых сообщают другие.)

Но это все еще оставляет меня озадаченным, что вызывает это странное поведение? На моей машине разработки (Windows 10, WSL, Docker рабочий стол, Linux контейнеры) я могу подключиться к службе на локальном хосте: 5000, 127.0.0.1:5000 et c. На моей Linux (производственной) машине все работает, кроме подключения от хоста docker к контейнерам.

Я надеюсь, что кто-то может пролить свет на это, я пытаюсь понять, почему это происходит.

Некоторая релевантная информация

Docker хост:

#  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 составить файл:

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 я могу установить sh соединение

Connection to 127.0.0.1 5000 port [tcp/*] succeeded!

Проверка с помощью netstat, когда клиенты не подключены, см .:

tcp6       0      0 :::5000                 :::*                    LISTEN      27824/docker-proxy

При попытке установить соединение с Dockerhost, соединение сделано:

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

Итак, я подозреваю, что теперь некоторые сети Voodoo на хосте docker.

Ответы [ 2 ]

0 голосов
/ 04 февраля 2020

Поэтому, когда я работал над этой проблемой, постепенно к решению я обнаружил, что мое последнее предложение было правильным. В брандмауэре (iptables) я зарегистрировал все отброшенные пакеты, и да, пакеты между docker -бриджем (не docker0, но br- и контейнером (veth) были отброшены iptables. Добавление правила, разрешающего traffi c от интерфейсов к потоку решена проблема.

В моем случае: sudo iptables -I INPUT 3 -s 172.20.0.3 -d 172.20.0.1 -j ACCEPT Где 172.20.0.0/32 - это сеть с мостовым соединением, созданная Docker.

0 голосов
/ 31 января 2020

Экземпляр Flask работает на 0.0.0.0:5000. Вы пробовали: curl http://0.0.0.0:5000/?

Возможно, ваша конфигурация хоста сопоставляет localhost с 127.0.0.1 вместо 0.0.0.0

...