您好,登錄后才能下訂單哦!
今天小編給大家分享一下Docker Swarm服務發現和負載均衡的原理是什么的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
使用的技術
docker 使用了 linux 內核 iptables 和 ipvs 的功能來實現服務發現和負載均衡。
iptables 是 linux 內核中可用的包過濾技術,它可用于根據數據包的內容進行分類、修改和轉發決策。
ipvs 是 linux 內核中可用的傳輸級負載均衡器。
準備工作
swarm 集群: 【manager】node1、【worker】node2
客戶端鏡像: registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu
服務端鏡像: registry.cn-hangzhou.aliyuncs.com/anoy/vote
如圖所示,我們將在 swarm 集群中部署 “client” 服務 和 “vote” 服務,其中 “vote” 服務部署多個副本。客戶端請求 “vote” 服務時,輸出結果中包含服務端的容器 id,這樣就更方便演示網絡請求。
集群狀態
[root@node1 ~]# docker node ls id hostname status availability manager status engine version rnr2i1y2of3n5vy2vzh2vkzq0 * node1 ready active leader 18.03.1-ce qvik057dvphx5s06evmswahaf node2 ready active 18.03.1-ce
使用如下命令,創建 overlay 網絡:
docker network create --driver overlay overlay1
基于 dns 的負載均衡
下圖描述了基于 dns 的負載均衡是如何工作的:
dns server 內嵌于 docker 引擎。docker dns 解析服務名 “vote” 并返回容器 id 地址列表(隨機排序)。客戶端通常會挑第一個 ip 訪問,因此負載均衡可能發生在服務器的不同實例之間。
使用如下命令創建 2 個基于 dns 負載均衡的服務 “client” 、 “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
查看服務信息:
[root@node1 ~]# docker service ls id name mode replicas image ports 2mrj3pqyioc3 client replicated 1/1 registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu:latest 826s79tsixuh vote replicated 2/2 registry.cn-hangzhou.aliyuncs.com/anoy/vote:latest [root@node1 ~]# docker service ps client id name image node desired state current state error ports f74i688vbh12 client.1 registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu:latest node2 running running 2 minutes ago [root@node1 ~]# docker service ps vote id name image node desired state current state error ports 7iiuzl2a63hy vote.1 registry.cn-hangzhou.aliyuncs.com/anoy/vote:latest node1 running running 47 seconds ago uyhxxqfdima7 vote.2 registry.cn-hangzhou.aliyuncs.com/anoy/vote:latest node2 running running about a minute ago
可以看出 "client" 運行于 node2,在 node2 上進入 client 容器,使用 dig 來解析服務名 "vote",如下所示,"vote" 解析到 10.0.0.6 和 10.0.0.5
[root@node2 ~]# docker ps container id image command created status ports names 1eed67d37cbb registry.cn-hangzhou.aliyuncs.com/anoy/vote:latest "gunicorn app:app -b…" about a minute ago up about a minute 80/tcp vote.2.uyhxxqfdima7smos5pki84wul 436702b21a1c registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu:latest "ping anoyi.com" 3 minutes ago up 3 minutes client.1.f74i688vbh12on8oniufht633 [root@node2 ~]# docker exec -it 436702b21a1c /bin/bash root@436702b21a1c:/# dig vote ;; answer section: vote. 600 in a 10.0.0.5 vote. 600 in a 10.0.0.6
使用 ping 解析 "vote" 服務,如下所示,交替解析到 10.0.0.6 和 10.0.0.5
root@436702b21a1c:/# ping -c1 vote ping vote (10.0.0.6) 56(84) bytes of data. 64 bytes from vote.2.uyhxxqfdima7smos5pki84wul.overlay1 (10.0.0.6): icmp_seq=1 ttl=64 time=0.087 ms root@436702b21a1c:/# ping -c1 vote ping vote (10.0.0.5) 56(84) bytes of data. 64 bytes from vote.1.7iiuzl2a63hyj084qgufc175v.overlay1 (10.0.0.5): icmp_seq=1 ttl=64 time=0.767 ms
如果使用 curl,如下所示,請求也能解析到不同的容器
root@436702b21a1c:/# curl vote | grep -i "container id" % total % received % xferd average speed time time time current dload upload total spent left speed 100 3162 100 3162 0 0 7542 0 --:--:-- --:--:-- --:--:-- 7546 processed by container id 9b42319d4f13 root@436702b21a1c:/# curl vote | grep -i "container id" % total % received % xferd average speed time time time current dload upload total spent left speed 100 3162 100 3162 0 0 452k 0 --:--:-- --:--:-- --:--:-- 514k processed by container id 1eed67d37cbb
基于 dns 負載均衡存在如下問題:
某些應用程序將 dns 主機名緩存到 ip 地址映射,這會導致應用程序在映射更改時超時
具有非零 dns ttl 值會導致 dns 條目反映最新的詳細信息時發生延遲
基于 vip 的負載均衡
基于 vip 的負載均衡克服了基于 dns 負載均衡的一些問題。在這種方法中,每個服務都有一個 ip 地址,并且該 ip 地址映射到與該服務關聯的多個容器的 ip 地址。在這種情況下,與服務關聯的服務 ip 不會改變,即使與該服務關聯的容器死亡并重新啟動。
下圖描述了基于 vip 的負載均衡是如何工作的:
dns server 會將服務名 "vote" 解析到 vip,使用 iptables 和 ipvs,vip 實現 2 個服務端 "vote" 容器的負載均衡。
使用如下命令創建 2 個 vip 模式的服務 “client” 、 “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
查看這 2 個服務和它們的服務 ip:
[root@node1 ~]# docker service inspect --format {{.endpoint.virtualips}} vote [{tetug0isdx1gri62g7cfm889i 10.0.0.9/24}] [root@node1 ~]# docker service inspect --format {{.endpoint.virtualips}} client [{tetug0isdx1gri62g7cfm889i 10.0.0.7/24}]
在 "client" 的容器中使用如下命令,可以看到服務名 "vote" 映射到 vip "10.0.0.9"
[root@node2 ~]# docker exec -it f3d1c4ef53f8 /bin/bash root@f3d1c4ef53f8:/# dig vote ;; answer section: vote. 600 in a 10.0.0.9
service ip "10.0.0.9" 使用 linux 內核的 iptables 和 ipvs 負載均衡到 2 個容器。iptables 實現防火墻規則,ipvs 實現負載均衡。為了證明這一點,我們需要使用 nsenter 進入容器的網絡空間 ( namespace )。為此,我們需要找到網絡的命名空間。
如下是 node2 上的網絡命名空間:
[root@node2 ~]# cd /run/docker/netns/ [root@node2 netns]# ls 1-tetug0isdx 1-vyy22w04t6 be7330b99a27 d67fa9efb59e ingress_sbox
前 2 個命名空間是用于 overlay 網絡,后面的用于容器。下面的命令用于找到 "client" 容器的網絡命名空間:
[root@node2 netns]# docker ps container id image command created status ports names 43a789312e70 registry.cn-hangzhou.aliyuncs.com/anoy/vote:latest "gunicorn app:app -b…" 3 minutes ago up 3 minutes 80/tcp vote.1.u46ms31e8zjdxtwrxvaec8zub f3d1c4ef53f8 registry.cn-hangzhou.aliyuncs.com/anoy/ubuntu:latest "ping anoyi.com" 4 minutes ago up 4 minutes client.1.ycox088aek5ajejezubwsjqf2 [root@node2 netns]# docker inspect f3d1c4ef53f8 | grep -i sandbox "sandboxid": "be7330b99a274a03a7f58e9e991346dc6f048836a1682c7244a6068acbfb664c", "sandboxkey": "/var/run/docker/netns/be7330b99a27",
sandboxid 即為 "client" 容器的網絡命名空間。
使用如下命令,我們就能夠進入到 "client" 容器的網絡命令空間:
nsenter --net=f3d1c4ef53f8 sh
下面,我們可以看到 iptables 的轉發規則和 ipvs 輸出:
sh-4.2# iptables -nvl -t mangle chain output (policy accept 606 packets, 50867 bytes) pkts bytes target prot opt in out source destination 0 0 mark all -- * * 0.0.0.0/0 10.0.0.7 mark set 0x102 0 0 mark all -- * * 0.0.0.0/0 10.0.0.9 mark set 0x103 sh-4.2# ipvsadm ip virtual server version 1.2.1 (size=4096) prot localaddress:port scheduler flags -> remoteaddress:port forward weight activeconn inactconn fwm 258 rr -> node2:0 masq 1 0 0 fwm 259 rr -> 10.0.0.10:0 masq 1 0 0 -> 10.0.0.11:0 masq 1 0 0
service ip "10.0.0.9" 使用 iptables output 鏈獲得標記 0x103 (十六進制 -> 十進制:259),然后 ipvs 使用此標記并將它負載均衡到 "10.0.0.10" 和 "10.0.0.11" 。
查看 vote 服務的 2 個容器的 ip 如下所示,即 vip "10.0.0.9" 負載均衡到不同的容器實例:
[root@node2 netns]# docker inspect vote.1.u46ms31e8zjdxtwrxvaec8zub | grep ipv4 "ipv4address": "10.0.0.10" [root@node1 ~]# docker inspect vote.2.tutj19i4iwu1xn7arsaq815cu | grep ipv4 "ipv4address": "10.0.0.11"
進入 client 服務的容器,使用 curl 請求 vote 服務,輸出結果如下,即請求分發到不同的容器:
root@f3d1c4ef53f8:/# curl vote | grep -i "container id" % total % received % xferd average speed time time time current dload upload total spent left speed 100 3162 100 3162 0 0 14409 0 --:--:-- --:--:-- --:--:-- 14438 processed by container id c2af209c4e90 root@f3d1c4ef53f8:/# curl vote | grep -i "container id" % total % received % xferd average speed time time time current dload upload total spent left speed 100 3162 100 3162 0 0 165k 0 --:--:-- --:--:-- --:--:-- 171k processed by container id 43a789312e70
路由網格 (routing mesh)
使用路由網格,服務暴露的端口會暴露在 swarm 集群中的所有工作節點。docker 是通過創建 "ingress" overlay 網絡來實現這一點的,所有節點默認使用內在的 sandbox 網絡命名空間成為 "ingress" overlay 網絡的一部分。
下圖描述了 routing mesh 如何實現負載均衡的:
首先,會將 hostname 或 ip 映射到 sandbox ip,sandbox 中的 iptables 和 ipvs 負責將請求負載均衡到 2 個 vote 容器。ingress sandbox 網絡命名空間駐留在 swarm 集群中的所有工作節點,它通過將主機映射的端口負載均衡到后端容器來協助路由網格功能。
使用如下命令創建 vote 服務,使用路由網格暴露端口到所有節點:
復制代碼 代碼如下:
docker service create --name vote --network overlay1 --replicas 2 -p 8080:80 registry.cn-hangzhou.aliyuncs.com/anoy/vote
下圖顯示了 sandbox、容器和每個節點的網絡之間的映射關系:
如圖所示,sandbox 和 vote 容器是 "ingress" 網絡的一部分,它有助于路由網格。client 容器和 vote 容器是 "overlay1" 網絡的一部分,它有助于內部負載均衡。所有容器都是默認 "docker_gwbridge" 網絡的一部分。
遵循 iptables 中的 nat 規則顯示,端口 8080 上的主機流量發送到 node1 里的 sandbox:
[root@node1 ~]# iptables -nvl -t nat chain docker-ingress (2 references) pkts bytes target prot opt in out source destination 0 0 dnat tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.18.0.2:8080 315 18876 return all -- * * 0.0.0.0/0 0.0.0.0/0
進入 node1 上的 sandbox 網絡命名空間 (ingress_sbox),查看 iptables 的轉發規則和 ipvs 輸出:
[root@node1 netns]# nsenter --net=ingress_sbox sh sh-4.2# iptables -nvl -t mangle chain prerouting (policy accept 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 mark tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 mark set 0x105 sh-4.2# ipvsadm ip virtual server version 1.2.1 (size=4096) prot localaddress:port scheduler flags -> remoteaddress:port forward weight activeconn inactconn fwm 261 rr -> 10.255.0.5:0 masq 1 0 0 -> 10.255.0.6:0 masq 1 0 0
端口 8080 標記為 0x105 (十六進制 -> 十進制:261),ipvs 使用此標記將它負載均衡到 "10.255.0.5" 和 "10.255.0.6" 。
查看 vote 服務的 2 個容器的 ip 如下所示,即主機端口 8080 的流量會負載均衡到不同的容器實例:
[root@node1 netns]# docker inspect 6173afd5fab8 | grep ipv4 "ipv4address": "10.255.0.6" "ipv4address": "10.0.0.14" [root@node2 ~]# docker inspect b07e95c5c681 | grep ipv4 "ipv4address": "10.255.0.5" "ipv4address": "10.0.0.13"
驗證負載均衡,在 node1 上通過 node2 的 ip 和 8080 端口請求 vote 服務:
[root@node1 netns]# curl node2:8080 | grep -i "container id" % total % received % xferd average speed time time time current dload upload total spent left speed 100 3162 100 3162 0 0 199k 0 --:--:-- --:--:-- --:--:-- 192k processed by container id 6173afd5fab8 [root@node1 netns]# curl node2:8080 | grep -i "container id" % total % received % xferd average speed time time time current dload upload total spent left speed 100 3162 100 3162 0 0 7551 0 --:--:-- --:--:-- --:--:-- 7546 processed by container id b07e95c5c681
在 node2 上通過 node1 的 ip 和 8080 端口請求 vote 服務:
[root@node2 ~]# curl node1:8080 | grep -i "container id" % total % received % xferd average speed time time time current dload upload total spent left speed 100 3162 100 3162 0 0 7531 0 --:--:-- --:--:-- --:--:-- 7546 processed by container id 6173afd5fab8 [root@node2 ~]# curl node1:8080 | grep -i "container id" % total % received % xferd average speed time time time current dload upload total spent left speed 100 3162 100 3162 0 0 169k 0 --:--:-- --:--:-- --:--:-- 171k processed by container id b07e95c5c681
以上就是“Docker Swarm服務發現和負載均衡的原理是什么”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。