天天看點

Docker Swarm服務發現和負載均衡原理

Docker Swarm服務發現和負載均衡原理

Docker使用的是Linux核心iptables和IPVS的功能來實作服務發現和負載均衡。Iptables是Linux核心中可用的包過濾技術,可根據資料包的内容進行分類、修改和轉發決策。IPVS是Linux核心中可用的傳輸級負載均衡。

本地建立一個叢集環境,我本地有三節點叢集環境:

Docker Swarm服務發現和負載均衡原理

用戶端鏡像:registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu

服務端鏡像:registry.cn-hangzhou.aliyuncs.com/anoy/vote

  1. 基于DNS的負載均衡:

DNS server内嵌于Docker引擎。在建立叢集的時候可以直接指定

--endpoint-mode dnsrr 來指明,這個服務裡面的task或者是所有啟動的容器通路都通過DNS的方式來進行負載均衡,這個是啥意思。操作下就清楚了:

建立一個網絡

docker network create --driver overlay overlay1

建立client節點(啟動一個),和vote節點(啟動多個),實作client節點通路vote的時候,是給均衡到不同的vote上了。

docker service create --endpoint-mode dnsrr --replicas 1 --name client --network overlay1 registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu ping anoyi.com

docker service create --endpoint-mode dnsrr --name vote --network overlay1 --replicas 2 registry.cn-hangzhou.aliyuncs.com/anoy/vote

然後進行如下操作

docker service ls 檢視服務

docker service ps xxxxclient的id  檢視client的資訊,找到他在哪個節點上,然後登陸到那個節點節點的機器上

docker ps  檢視容器,找到client對應的容器

docker exec -it xxxxclientid bash  登陸到這個容器  

上面操作如下圖

Docker Swarm服務發現和負載均衡原理

此時在client容器上,可以直接dig vote 看下對vote的dns解析

Docker Swarm服務發現和負載均衡原理

如上,有兩條。可以測試下是不是會被随機解析到上面,這裡用ping

Docker Swarm服務發現和負載均衡原理

是可以看到均衡效果的,這個就是基本的DNS解析來實作負載均衡。但是這樣會産生問題,某些應用程式将DNS主機名緩存到IP位址映射,這回導緻應用程式在通路更改時逾時,具有非零DNS ttl 值會導緻DNS條目反應最新的詳細資訊時發生延遲。

  1. 基于VIP的負載均衡。

  基于VIP的負載均衡可以解決1中DNS總是随便挑給用戶端帶來的不友善的影響。每個服務都有一個IP位址,并且該IP位址映射到與該服務關聯的多個容器的IP位址。在這種情況下,與服務關聯的服務IP不會改變,即使與該服務關聯的容器死亡并重新啟動。

  運作過程中,DNS service會将服務名”vote”解析到VIP,使用iptables和ipvs,VIP實作2個服務端”vote”容器的負載均衡。

把上面建立的兩個服務删除,然後重新部署。

docker service create --replicas 1 --name client --network overlay1 registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu ping anoyi.com

docker service create --name vote --network overlay1 --replicas 2 registry.cn-hangzhou.aliyuncs.com/anoy/vote

并沒有指定--endpoint-mode,也就是說Docker Swarm預設就是用的VIP

檢視這兩個服務的VIP

docker service inspect --format {{.Endpoint.VirtualIPs}} vote

docker service inspect --format {{.Endpoint.VirtualIPs}} client

Docker Swarm服務發現和負載均衡原理

然後跟上面姿勢一樣,找下client在哪個節點上,登上去,看下他是怎麼dns vote的。

Docker Swarm服務發現和負載均衡原理

這次DNS就隻有一個解析了,解析到的位址是vote服務的VIP,ping的話也不會存在跳轉别的ip的情況。

現在别動,繼續在client裡面執行

curl vote | grep -i "container id"

通過傳回來的容器id來區分到底是誰在為我們幹活

Docker Swarm服務發現和負載均衡原理

路由網格(Routing mesh)

使用路由網格,服務暴露的端口會暴露在Swarm叢集中的所有工作節點。Docker是通過建立 ingress overlay網絡來實作這一點的。所有節點預設使用内在的sandbox網絡命名空間成為ingress overlay網絡的一部分:

直接在上面的實操例子上更新一個端口映射

docker service update --publish-add 80:80 9fk2k04fw98p

Docker Swarm服務發現和負載均衡原理

Sandbox和vote容器是ingress網絡的一部分,它有助于路由網格。client容器和vote容器是overlay1網絡的一部分,有助于内部負載均衡。所有容器都是預設docker_gwbridge網絡的一部分。遵循iptables中的NAT規則顯示,端口80上的主機流量發送到node1裡的Sandbox.

這樣,然後浏覽器通路(不同重新整理):

Docker Swarm服務發現和負載均衡原理

跟預期的一樣,每個節點上不停的重新整理都會看到下面的容器id會交替變化,說明負載均衡是好使的。