2015-10-20 50 views
6

我正在运行码头 - 与node:4.2.1-wheezydnsdock容器组成。Docker DNS getaddrinfo ENOTFOUND

我在/ etc/default/docker里有DOCKER_OPTS="--dns 172.17.42.1"

当我在我的node.js容器中运行node -e "require('dns').resolve('host_name_here')"时,主机通过172.17.42.1 dns服务器正确解析。

但是,当我运行node -e "require('dns').lookup('host_name_here')"它失败,并出现ENOTFOUND错误。

问题是http.request使用dns.lookup而不是dns.resolve

The docs say that dns.lookup calls getaddrinfo。据我所知,getaddrinfo缓存/etc/resolv.conf可能会缓存空的/etc/resolv.conf(但cat /etc/resolv.conf打印nameserver 172.17.42.1)。

我真的不知道如何解决这个问题。什么会导致这种行为?

更新1

docker -v 
Docker version 1.7.1, build 786b29d 

docker-compose -v 
docker-compose version: 1.4.2 

更新2

我所有的东西更新到最新版本(1.9.0码头工人,码头工人,组成1.5.0和节点高达5.0 .0)但问题仍然存在。

所以这是搬运工,compose.yml再现问题:

dnsdock: 
    image: tonistiigi/dnsdock 
    volumes: 
    - /var/run/docker.sock:/run/docker.sock 
    ports: 
    - "172.17.42.1:53:53/udp" 
    environment: 
    - DNSDOCK_ALIAS=dns.org 
node: 
    image: node:5.0.0-wheezy 
    command: node -e "setTimeout(function() { var dns = require('dns'); dns.resolve('dns.org', console.log.bind(console, 'resolve')); dns.lookup('dns.org', console.log.bind(console, 'lookup')); }, 5000)" 
    dns: 172.17.42.1 

您应该与docker0接口的IP取代172.17.42.1。需要setTimeout(..., 5000),因为node集装箱可能在dnsdock之前启动。

这是我docker-compose up输出:

Creating test_node_1 
Creating test_dnsdock_1 
Attaching to test_node_1, test_dnsdock_1 
dnsdock_1 | 2015/11/07 09:29:44 Added service: 3653951cff40c06c04b9ab3f5d2fc94ccc19305eaac7ba1a545ce1dbab3e3e17 {test_dnsdock_1 dnsdock 172.17.42.3 -1 [dns.org]} 
dnsdock_1 | 2015/11/07 09:29:44 Added service: 36577feea136bc713f77b64b2a6a9712cd509c47ca55427f6749308cc5a4b140 {test_node_1 node 172.17.42.2 -1 []} 
node_1 | resolve null [ '172.17.42.3' ] 
node_1 | lookup { [Error: getaddrinfo ENOTFOUND dns.org] 
node_1 | code: 'ENOTFOUND', 
node_1 | errno: 'ENOTFOUND', 
node_1 | syscall: 'getaddrinfo', 
node_1 | hostname: 'dns.org' } 
dnsdock_1 | 2015/11/07 09:29:49 Stopped service: 36577feea136bc713f77b64b2a6a9712cd509c47ca55427f6749308cc5a4b140 
test_node_1 exited with code 0 
+0

你可以分享一个码头 - 撰写。yml重现你的设置? –

+0

也请考虑包含一个可以重现这一点的示例脚本。 –

回答

2

为了更好的DNS查找,你可以考虑使用一个网络覆盖,如 “Docker Overlay Networks: That was Easy

它采用了KV呈现(键/值)在Consul上存储基础,以及一个群集群,您可以在其中注册节点。

您可以构建一个覆盖网络

eval "$(docker-machine env --swarm c0-master)" 
docker network create -d overlay myStack1 

并用它来运行的图像:

docker run -d --name web --net myStack1 nginx 
docker run -itd --name shell1 --net myStack1 alpine /bin/sh 

这两个容器将被连接到同一个网络,并发现按容器名称(不管起始顺序)。
此外,当容器重新启动时,它将保持可发现的级联重启状态。

+0

感谢您的回复! 我的用例是同构的应用程序。所以它在客户端和前端服务器上使用相同的js。 这是我来到的体系结构: ** nginx **:在前端服务器和后端服务器之间分配请求。 ** dnsdock **:将'app.com'和'api.app.com'解析为nginx。 **前端**:使用dnsdock通过'api.app.com'访问后端。 我应该如何使用码头网络来实现它?我应该摆脱nginx和dnsdock并将后端容器名称设置为'api.app.com'吗?如果我决定使用'app.com/api'而不是'api.app.com'呢? –

+0

@AliakseiTuzik nginx似乎是一个好主意。在我的回答中,dnsdock将被领事取代。 – VonC