【swarm】Docker swarm 的服务发现
Docker Swarm mode下会为每个节点的docker engine内置一个DNS server,各个节点间的DNS server通过control plane的gossip协议互相交互信息,此处DNS server用于容器间的服务发现。
swarm mode会为每个 –net=自定义网络的service分配一个DNS entry。目前必须是自定义网络,比如overaly。而bridge和routing mesh的service,是不会分配DNS的。
那么,下面就来详细介绍服务发现的原理。
每个Docker容器都有一个DNS解析器,它将DNS查询转发到docker engine,该引擎充当DNS服务器。docker 引擎收到请求后就会在发出请求的容器所在的所有网络中,检查域名对应的是不是一个容器或者是服务,如果是,docker引擎就会从存储的key-value建值对中查找这个容器名、任务名、或者服务名对应的IP地址,并把这个IP地址或者是服务的虚拟IP地址返回给发起请求的域名解析器。
由上可知,docker的服务发现的作用范围是网络级别,也就意味着只有在同一个网络上的容器或任务才能利用内嵌的DNS服务来相互发现,不在同一个网络里面的服务是不能解析名称的,另外,为了安全和性能只有当一个节点上有容器或任务在某个网络里面时,这个节点才会存储那个网络里面的DNS记录。
如果目的容器或服务和源容器不在同一个网络里面,Docker引擎会把这个DNS查询转发到配置的默认DNS服务 。



在上面的例子中,总共有两个服务myservice和client,其中myservice有两个容器,这两个服务在同一个网里面。
在client里针对docker.com和myservice各执行了一个curl操作,下面时执行的流程:
为了client解析docker.com和myservice,DNS查询进行初始化
容器内建的解析器在127.0.0.11:53拦截到这个DNS查询请求,并把请求转发到docker引擎的DNS服务
myservice被解析成服务对应的虚拟IP(10.0.0.3),在接下来的内部负载均衡阶段再被解析成一个具体任务的IP地址,如果是容器名称这一步直接解析成容器对应的IP地址(10.0.0.4或者10.0.0.5)。
docker.com在mynet网络上不能被解析成服务,所以这个请求被转发到配置好的默认DNS服务器(8.8.8.8)上。