Docker 1.10通过主机的主机名访问容器

我有Docker版本1.10与embedded式DNS服务。

我在我的docker-compose文件中创build了两个服务容器。 它们可以通过主机名和IP互相访问,但是当我想从主机访问其中的一个时,它不起作用,它只与IP一起工作,而不与主机名一起工作。

那么,是否有可能通过Docker 1.10中的主机名从主机访问一个docker容器?

更新:

泊坞窗,compose.yml

version: '2' services: service_a: image: nginx container_name: docker_a ports: - 8080:80 service_b: image: nginx container_name: docker_b ports: - 8081:80 

然后我通过命令启动它: docker-compose up --force-recreate

当我运行:

  • docker exec -i -t docker_a ping -c4 docker_b – 它的工作原理
  • docker exec -i -t docker_b ping -c4 docker_a – 它的工作原理
  • ping 172.19.0.2 – 有效( 172.19.0.2docker_b的ip)
  • ping docker_a失败

docker network inspect test_default

 [ { "Name": "test_default", "Id": "f6436ef4a2cd4c09ffdee82b0d0b47f96dd5aee3e1bde068376dd26f81e79712", "Scope": "local", "Driver": "bridge", "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.19.0.0/16", "Gateway": "172.19.0.1/16" } ] }, "Containers": { "a9f13f023761123115fcb2b454d3fd21666b8e1e0637f134026c44a7a84f1b0b": { "Name": "docker_a", "EndpointID": "a5c8e08feda96d0de8f7c6203f2707dd3f9f6c3a64666126055b16a3908fafed", "MacAddress": "02:42:ac:13:00:03", "IPv4Address": "172.19.0.3/16", "IPv6Address": "" }, "c6532af99f691659b452c1cbf1693731a75cdfab9ea50428d9c99dd09c3e9a40": { "Name": "docker_b", "EndpointID": "28a1877a0fdbaeb8d33a290e5a5768edc737d069d23ef9bbcc1d64cfe5fbe312", "MacAddress": "02:42:ac:13:00:02", "IPv4Address": "172.19.0.2/16", "IPv6Address": "" } }, "Options": {} } ] 

这是我所做的。

我写了一个名为dnsthing的Python脚本,它监听Docker事件API的容器开始或停止。 它使用容器的名称和地址维护一个hosts style文件。 容器被命名为<container_name>.<network>.docker ,所以例如,如果我运行这个:

 docker run --rm --name mysql -e MYSQL_ROOT_PASSWORD=secret mysql 

我得到这个:

 172.17.0.2 mysql.bridge.docker 

然后我运行一个指向这个hosts文件的dnsmasq进程。 具体来说,我使用以下configuration运行一个dnsmasq实例:

 listen-address=172.31.255.253 bind-interfaces addn-hosts=/run/dnsmasq/docker.hosts local=/docker/ no-hosts no-resolv 

我运行dnsthing脚本脚本:

 dnsthing -c "systemctl restart dnsmasq_docker" \ -H /run/dnsmasq/docker.hosts --verbose 

所以:

  • 在容器停止/启动时,更新/run/dnsmasq/docker.hosts
  • 在更新之后, dnsthing运行systemctl restart dnsmasq_docker
  • dnsmasq_docker使用上述configuration运行dnsmasq ,绑定到地址172.31.255.253的本地网桥接口。
  • 我的系统上的“main”dnsmasq进程由NetworkManager维护,使用/etc/NetworkManager/dnsmasq.d/dockerdns这个configuration:

     server=/docker/172.31.255.253 

    这告诉dnsmasq将.docker域中的所有主机请求传递给docker_dnsmasq服务。

这显然需要一些设置来把所有的东西放在一起,但是在这之后,它似乎只是工作:

 $ ping -c1 mysql.bridge.docker PING mysql.bridge.docker (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.087 ms --- mysql.bridge.docker ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.087/0.087/0.087/0.000 ms 

正如在这里回答的,有一个软件解决scheme,复制anwser:


有一个开源的应用程序解决了这个问题,它被称为DNS代理服务器

这是一个解决容器主机名的DNS服务器,如果找不到具有该主机名的主机名,然后从互联网上解决它

启动DNS服务器

 $ docker run --hostname dns.mageddo --name dns-proxy-server -p 5380:5380 \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /etc/resolv.conf:/etc/resolv.conf \ defreitas/dns-proxy-server 

它将自动设置为您的默认DNS(并在停止时恢复到原始状态)

开始你的容器testing

 docker-compose up 

泊坞窗,compose.yml

 version: '2' services: redis: container_name: redis image: redis:2.8 hostname: redis.dev.intranet network_mode: bridge # that way he can solve others containers names even inside, solve elasticsearch, for example elasticsearch: container_name: elasticsearch image: elasticsearch:2.2 hostname: elasticsearch.dev.intranet 

现在解决你的容器主机名

从主机

 $ nslookup redis.dev.intranet Server: 172.17.0.2 Address: 172.17.0.2#53 Non-authoritative answer: Name: redis.dev.intranet Address: 172.21.0.3 

从另一个容器

 $ docker exec -it redis ping elasticsearch.dev.intranet PING elasticsearch.dev.intranet (172.21.0.2): 56 data bytes 

以及它解决互联网主机名称

 $ nslookup google.com Server: 172.17.0.2 Address: 172.17.0.2#53 Non-authoritative answer: Name: google.com Address: 216.58.202.78 

最简单的方法是将条目添加到主机文件中

  • 对于linux:将127.0.0.1 docker_a docker_b添加到/ etc / hosts文件
  • 对于mac:类似于linux,但使用虚拟机docker-machine ip default

和@larsks类似,我也写了一个Python脚本,但是把它作为服务来实现。 这里是: https : //github.com/nicolai-budico/dockerhosts

它使用参数--hostsdir=/var/run/docker-hosts启动dnsmasq,并在每次运行容器列表发生更改时更新文件/var/run/docker-hosts/hosts 。 一旦文件/var/run/docker-hosts/hosts被更改,dnsmasq会自动更新其映射,容器将在一秒之内变成主机名。

 $ docker run -d --hostname=myapp.local.com --rm -it ubuntu:17.10 9af0b6a89feee747151007214b4e24b8ec7c9b2858badff6d584110bed45b740 $ nslookup myapp.local.com Server: 127.0.0.53 Address: 127.0.0.53#53 Non-authoritative answer: Name: myapp.local.com Address: 172.17.0.2 

有安装和卸载脚本。 只有你需要的是让你的系统与这个dnsmasq实例交互。 我在systemd-resolved中注册了:

 $ cat /etc/systemd/resolved.conf [Resolve] DNS=127.0.0.54 #FallbackDNS= #Domains= #LLMNR=yes #MulticastDNS=yes #DNSSEC=no #Cache=yes #DNSStubListener=udp