2

我正在使用 docker-compose 和 traefik 运行一个 mongo 实例。

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.1Mac 进行连接。

问题是我无法使用 hostname 进行连接myapp-mongo.docker.localhost。它仅适用于 IP 127.0.0.1。

尝试 ping IP 127.0.0.1 响应正常,但尝试 ping 主机名不起作用。

我已经添加127.0.0.1 proxy.docker.localhost/etc/hosts让 traefik 工作。

所有其他 Web 应用程序的主机名都可以正常工作,例如myapp.docker.localhost. 这个问题只发生在这个 mongodb 容器上。

4

2 回答 2

3

可能是因为 Træfik 是 HTTP 代理,所以只支持 HTTP/HTTPS 连接。

于 2017-04-22T17:11:23.730 回答
1

我相信@bpatel 是对的(请参阅我在他的回答中留下的评论以及 github 对话的链接) Traefik 在撰写本文时仅支持 HTTP/HTTPS。

使用本机 docker 网络的解决方案

但是,您可以解决此问题!由于您使用的是 docker,因此您可以通过在代码中使用容器名称来解决问题(假设 mongo 和您的 mongo 访问代码都在共享 docker 网络上的容器中运行。如果容器使用 spun 启动,就会出现这种情况docker-compose) . 运行以下命令以查看您的容器是否正确链接:

  1. 运行docker ps以使您的容器名称运行(在NAMES列下)
  2. 运行docker network ls以查看您的网络名称
  3. 运行docker network inspect <target_network_name>以验证步骤 1 中的容器是否在同一网络上。

我从三个单独的 compose 文件运行 docker-compose,因此您应该能够涵盖以下大多数情况(对任何语法错误表示歉意,以下是精简的代码示例):

启动 traefik 的整个 docker-compose 文件(在目录名称“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 文件中的片段,它启动了 mongo

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

来自 docker-compose 的片段,它具有 mongo 访问代码

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

代码中的连接

不确定您使用的是什么语言,这就是我连接到 mongo 的以下 js 代码的样子(在那个 '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 操作,这样每个容器就可以通过容器名称在它们的 DNS 条目中查找它来知道其他容器的 IP

额外的情报

如果您的容器位于不同的计算机/虚拟机上,您可能想要使用服务发现工具(Consul 与 Traefik 配合得很好)或使用特定于集群中容器的docker网络覆盖做一些花哨的事情。

如果使用原始 docker 网络,您可以分配容器别名(但这不适用于 Traefik,或者至少几个月前还没有)。

于 2017-05-07T23:09:42.290 回答