Docker DNS getaddrinfo ENOTFOUND
我正在运行docker-compose和node:4.2.1-wheezy
和dnsdock
容器。
我在/ etc / default / DOCKER_OPTS="--dns 172.17.42.1"
里面有DOCKER_OPTS="--dns 172.17.42.1"
。
当我在我的node.js容器中运行node -e "require('dns').resolve('host_name_here')"
,主机通过172.17.42.1 dns服务器正确parsing。
但是当我运行node -e "require('dns').lookup('host_name_here')"
时, ENOTFOUND
错误会失败。
问题是, http.request
使用dns.lookup
而不是dns.resolve
。
文档说 dns.lookup
调用getaddrinfo
。 据我了解getaddrinfo
caching/etc/resolv.conf,也许它caching空/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。
我更新了所有的东西到最新版本(docker1.9.0,docker组成1.5.0和节点5.0.0),但问题仍然存在。
所以这是docker-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接口的IPreplace172.17.42.1
。 setTimeout(..., 5000)
是必需的,因为node
容器可能在dnsdock
之前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
为了更好地查找dns,可以考虑使用networking覆盖,如“ Docker覆盖networking:很简单 ”
它使用基于Consul的KV(Key / Value)存储,以及一个可以注册节点的群集。
你可以build立一个覆盖networking
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
这两个容器都将连接到同一个networking,并且可以通过容器名称(不pipe启动顺序)来发现。
此外,当一个容器重新启动时,它将保持可发现的级联重启。