Docker Swarm系列——2.Swarm服务发现

文章目录

        • 1. 负载均衡
        • 2. 服务发现

在这篇文章中,大家将会了解Docker是如何进行服务发现并在不同容器间实现网络负载均衡。通过上一篇文章我们知道,随着Swarm模式和服务的引入,容器现在可以通过自定义合适的名称和端口进行逻辑分组。请求会在集群中所有可用的容器之间进行负载均衡,这无形中增加了服务的可用性,并降低了单个容器的负载。

1. 负载均衡

负载均衡是Swarm路由网格(service mesh)中提供的一个功能,在Docker内部,利用Linux IPVS(一种内核第4层多协议负载均衡器)实现。
Docker Swarm系列——2.Swarm服务发现_第1张图片
在【1.Swarm服务初识】文章中,通过docker swarm init,我们初始化了一个具有2个节点(172.17.0.15, 172.17.0.16)的Swarm集群:

$ docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
vq9zrem4w61cbp6g2cb8un6cz *   host01              Ready               Active              Leader              18.03.1-ce
rq0mc2w41bbgcv3rqfhfavcbs     host02              Ready               Active                                  18.03.1-ce

并创建了一个名为http的服务,其中有两个容器正在运行,该服务通过80端口对外公开。默认情况下,对服务的请求基于公共端口进行负载平衡。

docker network create -d overlay --attachable httpnet
docker service create --name http --network httpnet --replicas 2 -p 80:80 nandy/show-host-info:v1

当在端口80上向集群中的节点发出请求时,它将在两个容器之间分配负载。curl 172.17.0.15:80通过返回值我们可以看出是哪个容器处理的请求。

$ curl 172.17.0.15:80
{"version":"v1","hostname":"6bf3107d0fcc","address":"10.0.0.6"}
$ curl 172.17.0.15:80
{"version":"v1","hostname":"195f225a8e47","address":"10.0.0.5"}

2. 服务发现

Docker Swarm内置路由网格来实现分布式网络,使于不同节点上的容器通信就好像在一台主机上,Swarm通过创建专为云服务而设计的虚拟可扩展网络(VXLAN)来实现此。

路由以两种不同的方式工作。任何对于服务的暴露端口的请求都会被转发给服务的虚拟IP(VIP),VIP只会在Docker网络内部进行路由,最终路由到真正的容器IP。

服务在部署时,VIP、服务名已经注册于Docker内置的DNS服务器中,当根据服务名请求时,DNS服务器反向解析并返回VIP。Docker官方推荐用dig, nslookup进行DNS域名解析查询。
运行docker run --name=dig --network httpnet --rm benhall/dig dig http

...
;; QUESTION SECTION:
;http.                                IN      A

;; ANSWER SECTION:
http.                 600     IN      A       10.0.0.4
...

运行docker run --name=ping --network httpnet --rm alpine ping -c4 http:

PING http (10.0.0.4): 56 data bytes
64 bytes from 10.0.0.4: seq=0 ttl=64 time=0.082 ms
64 bytes from 10.0.0.4: seq=1 ttl=64 time=0.090 ms
64 bytes from 10.0.0.4: seq=2 ttl=64 time=0.081 ms
64 bytes from 10.0.0.4: seq=3 ttl=64 time=0.082 ms

--- http ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.081/0.083/0.090 ms

运行docker inspect http查看服务的VIP:

...
            "VirtualIPs": [
                ...
                {
                    "NetworkID": "w6qvnm5nkdvcnsykpttkceqdb",
                    "Addr": "10.0.0.4/24"
                }
            ]
...

最终我们会发现,服务中容器的IP地址,都是在VIP的基础上依次增加。例如:VIP是10.0.0.4,则容器为10.0.0.5[6,7,8…],多开几个服务进行验证。

当服务进行扩展或者某些容器意外停止时,只要服务不死,对请求方来说,服务就是透明的,永远返回的是VIP,而真正的容器地址被隐藏,由VIP进行维护和转发,这样就实现了动态服务发现。并且,Docker Swarm的所有节点都参与到ingress路由网格,它允许集群中的所有节点接受已发布端口的连接,即使节点上没有任何任务运行,详见文章开始图片所示。

你可能感兴趣的:(docker)