traefik 主机名适用于网络应用程序但不适用于 mongodb

traefik hostname works for web apps but not for mongodb

我是 运行 一个 mongo 具有 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 运行 很好,我可以使用 Mac.

中的 127.0.0.1 进行连接

问题是我无法使用主机名 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 正常工作。

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

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

我相信@bpatel 是正确的(参见我在他的回答中留下的评论 link 到 github 对话)Traefik 在撰写本文时仅支持 HTTP/HTTPS。

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

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

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

I 运行 docker-compose 由三个独立的 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 作为代理(同样,这是有效的,因为我们正在充分利用 docker 网络):

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 条目中查找 IP

额外情报

如果您的容器位于单独的 computers/vm 上,您可能想要尝试使用服务发现工具(Consul 与 Traefik 配合得很好)或者使用 docker network overlay 做一些有趣的事情特定于集群中的容器。

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