docker-compose link 导致服务不可用

2021-06-25  本文已影响0人  追风骚年

问题是这样的,一般我们在写 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 解析的实现中去查找结果。

等后续。。。

上一篇 下一篇

猜你喜欢

热点阅读