traefik hostname работает для веб-приложений, но не для mongodb

Я управляю экземпляром Монго с помощью docker-compose и traefik.

myapp-mongo:
  build: ../images/myapp-mongo
  restart: always
  ports:
    - "27017:27017"
  labels:
    - "traefik.ports=27017,27018"
    - "traefik.backend=myapp-mongo"
    - "traefik.frontend.rule=Host:myapp-mongo.docker.localhost"
  networks:
    - development
  environment:
    - MONGO_USER=${MONGO_USER}
    - MONGO_PASSWD=${MONGO_PASSWD}
    - MONGO_AUTHDB=${MONGO_AUTHDB}

Mongo работает нормально, и я могу подключиться с помощью 127.0.0.1 с моего Mac.

Проблема в том, что я не могу подключиться, используя имя хоста myapp-mongo.docker.localhost, Работает только с использованием IP 127.0.0.1.

Попытка пропинговать IP 127.0.0.1 отвечает нормально, но попытка пропинговать имя хоста не работает.

Я уже добавил 127.0.0.1 proxy.docker.localhost в /etc/hosts чтобы трафик работал.

У всех других веб-приложений имена хостов работают нормально, например, myapp.docker.localhost, Эта проблема возникает только с этим контейнером mongodb.

2 ответа

Решение

Возможно, потому что Træfik является HTTP-прокси и поэтому будет поддерживать только HTTP/HTTPS-соединения.

Я считаю, что @bpatel прав (см. Комментарий, который я оставил к его ответу со ссылкой на беседу на github). На момент написания статьи Traefik поддерживает только HTTP/HTTPS.

Решение с использованием собственных сетей докеров

Тем не менее, вы можете обойти эту проблему! Поскольку вы используете docker, вы можете обойти это, используя имя контейнера в своем коде (при условии, что mongo и ваш код доступа к mongo оба работают в контейнерах в общей сети docker. Это будет иметь место, если контейнеры запускаются с docker-compose). Выполните следующее, чтобы увидеть, правильно ли связаны ваши контейнеры:

  1. бежать docker ps чтобы ваши имена контейнеров работали (под NAMES колонка)
  2. бежать docker network ls чтобы увидеть ваши сетевые имена
  3. бежать docker network inspect <target_network_name> чтобы убедиться, что ваши контейнеры с шага 1 находятся в одной сети.

Я запускаю docker-compose из трех отдельных файлов compose, поэтому вы сможете охватить большинство случаев из следующего (извинения за любые синтаксические ошибки, ниже приведены примеры кода):

Весь docker-compose файл, который запускает traefik (под именем каталога 'proxy')

version: '2'
services:
  traefik:
    image: traefik
    command: --web --docker --docker.domain=docker.localhost --logLevel=DEBUG
    networks:
      - webgateway
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /dev/null:/traefik.toml
networks:
  webgateway:
    driver: bridge

фрагмент из моего файла docker-compose, который раскручивает монго

version: '2'
services:
  database:
    image: mongo
    ports:
      - "27017:27017"
    networks:
      - web
networks:
  web:
    external:
      name: proxy_webgateway

фрагмент из docker-compose с кодом доступа к монго

version: '2'
services:
  topicOntologyBuilder:
    image: topic-ontology-builder
    labels:
      - "traefik.backend=topicOntologyBuilder"
      - "traefik.port=80"
      - "traefik.frontend.rule=Host:topic-ontology.docker.localhost"
    networks:
      - web
    volumes:
      - ./:/home
networks:
  web:
    external:
      name: proxy_webgateway

Связь в коде

Не уверен, какой язык вы используете, вот как выглядел следующий js-код для подключения к mongo (внутри контейнера 'topicOntologyBuilder`, при этом в качестве прокси используется traefik (опять же, это работает, потому что мы максимально из докерских сетей):

var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://<MONGO_CONTAINER_NAME>/<DB_NAME>', function(err, db) {
    //insert code here to interact with mongo
})

Почему это работает

Это работает, потому что docker делает некоторые умные вещи DNS внутри контейнеров, чтобы каждый контейнер знал IP других контейнеров, просматривая его в своей записи DNS по именам контейнеров.

Дополнительная информация

Если ваши контейнеры находятся на отдельных компьютерах / виртуальных машинах, вам, вероятно, захочется поиграть с инструментом обнаружения сервисов (Consul хорошо работает с Traefik) или сделать что-то необычное с оверлейной сетью докеров, которая характерна для контейнеров в кластере.

При использовании необработанных сетей докеров вы можете назначить псевдонимы контейнеров (хотя это не работает с Traefik или, по крайней мере, пару месяцев назад).

Другие вопросы по тегам