使用resolvable通过DNS查找容器

目录

作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处:https://andyyoung01.github.io/http://andyyoung01.16mb.com/

在某个主机上,我们可以使用link或Docker Compose来使不同的容器可以发现彼此,不过使用link或Compose需要在容器启动之前进行配置,无法更新一个运行中的容器的环境变量。为了解决这个问题,可以使用一个DNS服务器。而Resolvable正是一个这样的DNS服务器。

Resolvable是一个可以读取当前主机上正在运行容器信息的工具,它可以以标准的方式提供容器的名称到ip地址的映射,也就是一个DNS服务器。
下面启动一个Resolvable容器:

1
2
3
4
5
docker run -d \
--hostname resolvable \
-v /var/run/docker.sock:/tmp/docker.sock \
-v /etc/resolv.conf:/tmp/resolv.conf \
mgood/resolvable

上面的命令将主机上的docker.sock挂载到容器内部,以便于resolvable来监听主机上的Docker事件,并且可以自动注册容器。通过将主机上的resolv.conf挂载到容器内部,resolvable可以把自己加入到它所在主机的/etc/resolv.conf里,以便主机上的其它容器可以使用它作为默认的DNS服务器。当resolvable容器启动时,它将自己作为第一个nameserver插入到/etc/resolv.conf文件中;当容器关闭时自动移除该条目。
对于在主机上运行的每一个容器,resolvable可以自动将两个名字解析为ip地址:<container_name>.docker<container_hostname>。下面使用dig测试一下:

1
2
3
4
5
6
7
8
9
[yangdong@centos7 ~]$ docker run -d \
--hostname myhost \
--name myname \
busybox sleep 500
74bb7a2ec0e9ae0ab277084ab338401ff74814ca99f1f30d306d9298b756e48e
[yangdong@centos7 ~]$ dig +short myname.docker
172.17.0.5
[yangdong@centos7 ~]$ dig +short myhost
172.17.0.5

上面的命令在主机上启动了一个名为myname的容器,其主机名设置为myhost。通过在主机上运行dig命令,发现可以正确解析上面两个名字。不过这些信息也可以通过docker inspect命令得到。它最有用的地方在于,启动新的容器后,新容器自动使用了resolvable容器提供的dns服务,从而可以自动发现同一主机上的其它容器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[yangdong@centos7 ~]$ docker run -it --name busybox1 --hostname busyboxhost busybox sh
/ # ping myname.docker
PING myname.docker (172.17.0.5): 56 data bytes
64 bytes from 172.17.0.5: seq=0 ttl=64 time=0.133 ms
64 bytes from 172.17.0.5: seq=1 ttl=64 time=0.089 ms
64 bytes from 172.17.0.5: seq=2 ttl=64 time=0.189 ms
^C
--- myname.docker ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.089/0.137/0.189 ms
/ # ping myhost
PING myhost (172.17.0.5): 56 data bytes
64 bytes from 172.17.0.5: seq=0 ttl=64 time=0.046 ms
64 bytes from 172.17.0.5: seq=1 ttl=64 time=0.378 ms
64 bytes from 172.17.0.5: seq=2 ttl=64 time=0.119 ms
^C
--- myhost ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.046/0.181/0.378 ms

上面的命令在相同的主机上启动了另外一个容器,进入新容器的shell后,通过ping命令发现可以解析到刚才启动的容器。这对于相同主机上的不同容器之间通过名称彼此通信具有非常重要的意义。而且,这种方式并没有增加任何额外的命令行参数,也没有修改任何配置文件,resolvable的这种用法方便了单主机上的服务发现机制。对于多个不同主机上的容器的服务发现机制,可以使用其它的解决方案。