问题是这样的,一般我们在写 docker-compose.yaml
中的 service 时,service 之间可以通过 service 名称进行互相访问,如果使用名称进行服务间访问,docker 还会在底层提供负载的作用。
测试1
version: "3"
services:
busybox:
image: busybox
entrypoint: tail -f /dev/null
who:
image: containous/whoami
$ docker-compose up -d # 启动服务
$ docker-compose scale who=3 # 扩容 who 服务
$ docker-compose exec busybox sh # 进入busybox 服务
$ ping who
PING who (172.18.0.4): 56 data bytes
64 bytes from 172.18.0.4: seq=0 ttl=64 time=0.129 ms
64 bytes from 172.18.0.4: seq=1 ttl=64 time=0.118 ms
64 bytes from 172.18.0.4: seq=2 ttl=64 time=0.095 ms
^C
--- who ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.095/0.114/0.129 ms
$ ping who
PING who (172.18.0.5): 56 data bytes
64 bytes from 172.18.0.5: seq=0 ttl=64 time=0.371 ms
64 bytes from 172.18.0.5: seq=1 ttl=64 time=0.131 ms
64 bytes from 172.18.0.5: seq=2 ttl=64 time=0.166 ms
^C
--- who ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.131/0.222/0.371 ms
这里可以看到 docker 的内嵌 dns 为我们的 who 服务作了负载。
测试2
version: "3"
services:
busybox:
image: busybox
entrypoint: tail -f /dev/null
links:
- who
who:
image: containous/whoami
这里添加了一个 links
$ docker-compose up -d # 启动服务
$ docker-compose scale who=3 # 扩容 who 服务
$ docker-compose exec busybox sh # 进入busybox 服务
$ ping who
PING who (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.176 ms
64 bytes from 172.20.0.2: seq=1 ttl=64 time=0.132 ms
64 bytes from 172.20.0.2: seq=2 ttl=64 time=0.122 ms
^C
--- who ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.122/0.143/0.176 ms
$ ping who
PING who (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.090 ms
64 bytes from 172.20.0.2: seq=1 ttl=64 time=0.123 ms
64 bytes from 172.20.0.2: seq=2 ttl=64 time=0.115 ms
^C
--- who ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.090/0.109/0.123 ms
这里可以看到两次返回的 ip 是一样的,可以测试多次应该是得到都是同一个 ip。
可以再打开一个终端停止刚开始的容器
$ docker stop whoami_busybox_1
然后再去 ping 一下 who 的服务
$ ping who
ping: bad address 'who'
那这里就发生的事情就很奇怪了,居然 ping 不通了。
这里可以推断出 docker compose 启动的时候就已经将 who 服务和它的 ip 写到 busybox 中,所以对于 busybox 来说只会和第一个启动的 who 绑定,也没有走 docker 内嵌的 dns 服务。
很多文章指出是直接将容器名和 ip 写到 /etc/hosts
中
$ cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.20.0.3 32cee21646a5
我这里测试出来的结果是 32cee21646a5 是 busybox的 container id,172.20.0.3 是 busybox 的 ip,这里并没有找到 who 的对应关系,所以网上的一些文章应该是有误的。
我甚至用 tcpdump 去抓网卡对应的dns 解析的包
$ tcpdump -i eth0 udp port 53
$ ping baidu.com # 可以看到很多 udp 的包
$ ping sv1 # tcpdump 是没有输出的,所以对于内部服务是特殊处理的
但是这个问题终究还是没有找到根本原因,可能需要去 docker 的内嵌 dns 解析的实现中去查找结果。
等后续。。。
网友评论