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
). Выполните следующее, чтобы увидеть, правильно ли связаны ваши контейнеры:
- бежать
docker ps
чтобы ваши имена контейнеров работали (подNAMES
колонка) - бежать
docker network ls
чтобы увидеть ваши сетевые имена - бежать
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 или, по крайней мере, пару месяцев назад).