日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

从零开始学习docker(十九)Swarm mode 集群服务间通信--RoutingMesh

發(fā)布時間:2024/9/16 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 从零开始学习docker(十九)Swarm mode 集群服务间通信--RoutingMesh 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

擼了今年阿里、頭條和美團的面試,我有一個重要發(fā)現(xiàn).......>>>

在上一節(jié)中,我們介紹了通過service create部署了wordpress和mysql,我們發(fā)現(xiàn)了幾個問題:

不同節(jié)點之間如何通信?

通過service創(chuàng)建,將mysql和wordpress部署到cluster中,然后這兩個service位于不同的節(jié)點上,這兩個節(jié)點之間是可以相互通信的,并且可以通過service name進行通信,這里面就涉及到一個DNS服務(wù)發(fā)現(xiàn)的問題。

我們在之前將docker-compose時講過,我們通過docker-compose部署一個application,這個application中的service 如果是連在了同一個網(wǎng)絡(luò)上,那么他們之間是可以通過service name相互訪問的。這個底層是通過DNS服務(wù)去實現(xiàn)的。這是docker-compose在單機的情況下。

今天我們在swarm cluster中我們的service是位于不同的節(jié)點上面,他們之間也可以通過service name進行通信的,所以說這也是DNS的功勞在里面。對于swarm來講,我們有內(nèi)置的DNS服務(wù)發(fā)現(xiàn)功能,通過swarm創(chuàng)建一個service時,如果是連到了一個overlay上,就可以為所有連到這個overlay上的service增加一條DNS記錄,然后通過DNS記錄就可以得到IP地址,然后就可以訪問服務(wù)了。如下圖所示:

其中DNS的name用service name來表示,而對應(yīng)的記錄IP并不是service所在容器的IP,而是一個虛擬IP(Virtual IP)。

為什么會這樣?我們想一想,如果我們的service有一個橫向的擴展(scale),那么service就不一定會在哪個節(jié)點上面,有一種情況是:某個節(jié)點的service down掉了,我們在其他節(jié)點上重新啟動一個service,這時他的IP地址發(fā)生了變化;還有一種情況:有多個service,因此會對應(yīng)多個IP地址。如果我們在DNS中通過實際的容器地址去表示IP地址,那么這會產(chǎn)生不穩(wěn)定的現(xiàn)象,因為IP地址有可能發(fā)生變化。這時我們?nèi)绻ㄟ^虛擬IP來解決這個問題。我們通過service來分配一個虛擬IP,而這個虛擬IP是不會變化的,也就是說一旦我們的service創(chuàng)建之后,IP就不會發(fā)生變化。但是這個虛擬IP地址背后,它所指的是實際IP(也就是容器IP),這時通過LVS實現(xiàn)的。

下面我們通過實驗來具體演示一下。

準(zhǔn)備環(huán)境

創(chuàng)建一個overlay類型的網(wǎng)絡(luò),名稱叫my-demo

iie4bu@hostdocker:~$ docker network create -d overlay my-demo cojus8blvkdozz8ykefozf7ml

創(chuàng)建一個service:這個service使用一個whoami的image,這個image會提供一個web服務(wù)的,如果我們訪問他的8000端口的話,它會返回容器的hostname。

iie4bu@hostdocker:~$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS 9i6wz6cg4koc whoami replicated 1/1 jwilder/whoami:latest *:8000->8000/tcp

查看whoami 運行在哪個節(jié)點:

iie4bu@swarm-manager:~$ docker service ps whoami ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS 6hhuf528spdw whoami.1 jwilder/whoami:latest swarm-manager Running Running 23 minutes ago

可以看到運行在swarm-manager節(jié)點上,可以通過docker container ls 看到這個容器:

iie4bu@swarm-manager:~$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cc9f97cc5056 jwilder/whoami:latest "/app/http" 23 minutes ago Up 23 minutes 8000/tcp whoami.1.6hhuf528spdw9j9pla7l3tv3t

監(jiān)聽了本地的8000端口,

iie4bu@swarm-manager:~$ curl 127.0.0.1:8000 I'm cc9f97cc5056

返回了hostname。

然后我們再創(chuàng)建一個service,也連到這個my-demo上面,這個service是busyboxservice。

iie4bu@swarm-manager:~$ docker service create --name client -d --network my-demo busybox sh -c "while true; do sleep 3600; done" jsj6euq2qlwljg421bet1d8cr

然后查看service:

iie4bu@swarm-manager:~$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS jsj6euq2qlwl client replicated 1/1 busybox:latest 9i6wz6cg4koc whoami replicated 1/1 jwilder/whoami:latest *:8000->8000/tcp

當(dāng)client的REPLICAS變?yōu)?/1之后,說明已經(jīng)啟動成功。

查看client位于哪個節(jié)點:

iie4bu@swarm-manager:~$ docker service ps client ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS czotxqi6bi5k client.1 busybox:latest swarm-worker2 Running Running about a minute ago

可以看到是位于swarm-worker2節(jié)點上。

進入到swarm-worker2節(jié)點中,查看client的容器:

iie4bu@swarm-worker2:~$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f84e7570ee1c busybox:latest "sh -c 'while true; …" 4 minutes ago Up 4 minutes client.1.czotxqi6bi5k8uwkgzxcrwp1r

實驗

進入swarm-worker2的client容器中,然后去ping whoami

iie4bu@swarm-worker2:~$ docker exec -it f84e sh / # ping whoami PING whoami (10.0.2.5): 56 data bytes 64 bytes from 10.0.2.5: seq=0 ttl=64 time=0.085 ms 64 bytes from 10.0.2.5: seq=1 ttl=64 time=0.078 ms 64 bytes from 10.0.2.5: seq=2 ttl=64 time=0.077 ms ^C --- whoami ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 0.077/0.080/0.085 ms

發(fā)現(xiàn)是可以ping通whoami的,并且是ping的10.0.2.5這個IP地址。而我們是在swarm-worker2節(jié)點中,去ping swarm-manager節(jié)點。說明是可以通過name訪問到service,但是這個ip 10.0.2.5地址并不是whoami容器的ip地址。

思考:我們將whoami服務(wù)scale變成多個,那么在ping whoami的時候地址會不會變呢?

擴展whoami:

iie4bu@swarm-manager:~$ docker service scale whoami=2 whoami scaled to 2 overall progress: 2 out of 2 tasks 1/2: running [==================================================>] 2/2: running [==================================================>] verify: Service converged

然后我們查看whoami這個服務(wù):

iie4bu@swarm-manager:~$ docker service ps whoami ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS 6hhuf528spdw whoami.1 jwilder/whoami:latest swarm-manager Running Running about an hour ago bw90ld3onwya whoami.2 jwilder/whoami:latest swarm-worker1 Running Running 42 seconds ago

可以看到,service被分別部署到了swarm-manager和swarm-worker1上。?

在swarm-worker1上查看:

iie4bu@swarm-worker1:~$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5559895ccaea jwilder/whoami:latest "/app/http" 2 minutes ago Up 2 minutes 8000/tcp whoami.2.bw90ld3onwyabn3vv9rfoj9qf

發(fā)現(xiàn)確實,在swarm-worker1中有了一個whoami容器。

然后我們在client中再去ping一下whoami

/ # ping whoami PING whoami (10.0.2.5): 56 data bytes 64 bytes from 10.0.2.5: seq=0 ttl=64 time=0.083 ms 64 bytes from 10.0.2.5: seq=1 ttl=64 time=0.073 ms 64 bytes from 10.0.2.5: seq=2 ttl=64 time=0.072 ms 64 bytes from 10.0.2.5: seq=3 ttl=64 time=0.072 ms 64 bytes from 10.0.2.5: seq=4 ttl=64 time=0.072 ms 64 bytes from 10.0.2.5: seq=5 ttl=64 time=0.072 ms

可以看到:我們在ping whoami 的時候可以ping通,而且地址還是10.0.2.5 是不是很奇怪?我們現(xiàn)在有兩個whoami,它ping的一個地址到底是誰的呢?

其實ip地址10.0.2.5并不是我們?nèi)魏我粋€whoami service容器的地址,而是一個VIP(虛擬IP)。如何證明?

使用nslookup命令可以證明。這個命令就是用來查詢DNS的。可以去DNS服務(wù)器上查詢一個DNS name。

?例如通過nslookup查詢百度的IP地址:

iie4bu@swarm-manager:~$ nslookup www.baidu.com Server: 8.8.8.8 Address: 8.8.8.8#53Non-authoritative answer: www.baidu.com canonical name = www.a.shifen.com. www.a.shifen.com canonical name = www.wshifen.com. Name: www.wshifen.com Address: 103.235.46.39

然后我們在client容器中運行nslookup。

/ # nslookup whoami Server: 127.0.0.11 Address: 127.0.0.11:53Non-authoritative answer:*** Can't find whoami: No answer/ #

127.0.0.11為DNS服務(wù)器的地址,這個DNS服務(wù)器是有cluster維護的,而我們現(xiàn)在并沒有返回正確結(jié)果,原因是新版busybox鏡像的問題,使用舊版本即可,如1.28.3版。
刪除busybox服務(wù)后,重新運行:

iie4bu@swarm-manager:~$ docker service rm client client iie4bu@swarm-manager:~$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS 9i6wz6cg4koc whoami replicated 2/2 jwilder/whoami:latest *:8000->8000/tcp iie4bu@swarm-manager:~$ docker service create --name client -d --network my-demo busybox:1.28.3 sh -c "while true; do sleep 3600; done" h4wlczp85sw5ez5op51plfazn overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged

再次進入到容器中:

iie4bu@swarm-worker2:~$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 633ddfc082b9 busybox:1.28.3 "sh -c 'while true; …" 53 seconds ago Up 52 seconds client.1.3iv3gworpyr5vdo0h9eortlw0 iie4bu@swarm-worker2:~$ docker exec -it 633 sh / #

然后執(zhí)行nslookup:

iie4bu@swarm-worker2:~$ docker exec -it 633 sh / # nslookup whoami Server: 127.0.0.11 Address 1: 127.0.0.11Name: whoami Address 1: 10.0.2.5

返回了whoami的IP地址是10.0.2.5,但是這個地址既不是swarm-manager上的ip又不是swarm-worker1上面的ip。

看一下swarm-manager上面的whoami 的 ip:

iie4bu@swarm-manager:~$ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cc9f97cc5056 jwilder/whoami:latest "/app/http" About an hour ago Up About an hour 8000/tcp whoami.1.6hhuf528spdw9j9pla7l3tv3t iie4bu@swarm-manager:~$ docker exec -it cc9f97cc5056 sh /app # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet 10.255.0.168/32 brd 10.255.0.168 scope global lovalid_lft forever preferred_lft foreverinet 10.0.2.5/32 brd 10.0.2.5 scope global lovalid_lft forever preferred_lft forever 18: eth0@if19: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP link/ether 02:42:0a:ff:00:05 brd ff:ff:ff:ff:ff:ffinet 10.255.0.5/16 brd 10.255.255.255 scope global eth0valid_lft forever preferred_lft forever 20: eth1@if21: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ffinet 172.18.0.3/16 brd 172.18.255.255 scope global eth1valid_lft forever preferred_lft forever 23: eth2@if24: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP link/ether 02:42:0a:00:02:07 brd ff:ff:ff:ff:ff:ffinet 10.0.2.7/24 brd 10.0.2.255 scope global eth2valid_lft forever preferred_lft forever /app #

在swarm-worker2上面查看一下whoami的ip:

iie4bu@swarm-worker1:~$ docker exec -it 5559895ccaea sh /app # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever 20: eth0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP link/ether 02:42:0a:ff:00:06 brd ff:ff:ff:ff:ff:ffinet 10.255.0.6/16 brd 10.255.255.255 scope global eth0valid_lft forever preferred_lft forever 22: eth2@if23: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:13:00:03 brd ff:ff:ff:ff:ff:ffinet 172.19.0.3/16 brd 172.19.255.255 scope global eth2valid_lft forever preferred_lft forever 24: eth1@if25: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP link/ether 02:42:0a:00:02:0a brd ff:ff:ff:ff:ff:ffinet 10.0.2.10/24 brd 10.0.2.255 scope global eth1valid_lft forever preferred_lft forever /app #

發(fā)現(xiàn)都沒有10.0.2.5IP地址。

然后在client中使用命令nslookup tasks.whoami

/ # nslookup tasks.whoami Server: 127.0.0.11 Address 1: 127.0.0.11Name: tasks.whoami Address 1: 10.0.2.10 whoami.2.bw90ld3onwyabn3vv9rfoj9qf.my-demo Address 2: 10.0.2.7 whoami.1.6hhuf528spdw9j9pla7l3tv3t.my-demo / #

我們看到tasks.whoami一共有兩個地址,一個是10.0.2.7,一個是10.0.2.10,跟我們上面的container中查看的一致。這才是真正的ip地址。所以通過tasks.whoami可以查看到真正的容器地址。

如果我們把whoami橫向擴展成3個,會怎么樣?

在swarm-manager中設(shè)置scale whoami=3

iie4bu@swarm-manager:~$ docker service scale whoami=3 whoami scaled to 3 overall progress: 3 out of 3 tasks 1/3: running [==================================================>] 2/3: running [==================================================>] 3/3: running [==================================================>] verify: Service converged iie4bu@swarm-manager:~$ docker service ps whoami ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS 6hhuf528spdw whoami.1 jwilder/whoami:latest swarm-manager Running Running 2 hours ago bw90ld3onwya whoami.2 jwilder/whoami:latest swarm-worker1 Running Running about an hour ago 9idgk9jbrlcm whoami.3 jwilder/whoami:latest swarm-worker2 Running Running 49 seconds ago

現(xiàn)在whoami位于三個容器,分別位于swarm-manager、swarm-worker1、swam-worker2。

這時返回到client,在執(zhí)行nslookup tasks.whoami

/ # nslookup tasks.whoami Server: 127.0.0.11 Address 1: 127.0.0.11Name: tasks.whoami Address 1: 10.0.2.10 whoami.2.bw90ld3onwyabn3vv9rfoj9qf.my-demo Address 2: 10.0.2.13 whoami.3.9idgk9jbrlcm3ufvkmbmvv2t8.my-demo Address 3: 10.0.2.7 whoami.1.6hhuf528spdw9j9pla7l3tv3t.my-demo

可以看到又多了一條記錄。

新增的10.0.2.13就是新增的service的地址,可以驗證一下,在swarm-worker:

iie4bu@swarm-worker2:~$ docker exec -it f47e05019fd9 sh /app # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet 10.255.0.168/32 brd 10.255.0.168 scope global lovalid_lft forever preferred_lft foreverinet 10.0.2.5/32 brd 10.0.2.5 scope global lovalid_lft forever preferred_lft forever 24: eth2@if25: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP link/ether 02:42:0a:00:02:0d brd ff:ff:ff:ff:ff:ffinet 10.0.2.13/24 brd 10.0.2.255 scope global eth2valid_lft forever preferred_lft forever 26: eth1@if27: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:12:00:04 brd ff:ff:ff:ff:ff:ffinet 172.18.0.4/16 brd 172.18.255.255 scope global eth1valid_lft forever preferred_lft forever 28: eth0@if29: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1450 qdisc noqueue state UP link/ether 02:42:0a:ff:00:07 brd ff:ff:ff:ff:ff:ffinet 10.255.0.7/16 brd 10.255.255.255 scope global eth0valid_lft forever preferred_lft forever

可以看到10.0.2.13。

實際上任何一個連到my-demo網(wǎng)絡(luò)上的容器執(zhí)行nslookup都會的到這個結(jié)果。

總結(jié):

? ? 在client中ping whoami,返回的ip是10.0.2.5

? ? 而使用命令nslookup tasks.whoami 返回的ip并沒有10.0.2.5。

?ip:10.0.2.5就是虛擬ip。

這個虛擬IP是不會變的。因為service的數(shù)量會有變化的。而虛擬的ip與實際的container ip有一個map關(guān)系。通過這個map關(guān)系去找到了這個虛擬ip

訪問whoami這個service具體情況?

因為我們的busybox沒有裝curl,所以我們用wget模擬請求。

在client container中訪問whoami:8000

/ # wget whoami:8000 Connecting to whoami:8000 (10.0.2.5:8000) index.html 100% |*******************************| 17 0:00:00 ETA / # more index.html I'm f47e05019fd9 / #

可以正常訪問到。其中f47e05019fd9是container的id。

將index.html刪掉,然后在訪問一遍whoami:

/ # wget whoami:8000 Connecting to whoami:8000 (10.0.2.5:8000) index.html 100% |*******************************| 17 0:00:00 ETA / # more index.html I'm cc9f97cc5056 / #

發(fā)現(xiàn)container的id變?yōu)閏c9f97cc5056。

可以說每次訪問whoami:8000返回內(nèi)容都是不一樣的,也就是說我們做了一個負載均衡。也就是說10.0.2.5背后其實是?10.0.2.10、10.0.2.13和10.0.2.7這三個web服務(wù)器。每次訪問10.0.2.5,都會做一個負載均衡。第一次是?10.0.2.10給的響應(yīng),第二次是10.0.2.13依次循環(huán)。

這些負載均衡、VIP都是通過LVS幫我們實現(xiàn)的。

簡單總結(jié)一下:

我們這節(jié)講的其實就是Routing Mesh。這一節(jié)講的是Internal 網(wǎng)絡(luò)。

Internal網(wǎng)絡(luò):我們在swarm中連接到同一個overlay網(wǎng)絡(luò)中的容器是通過service name通信的,然后這個service name對應(yīng)的ip地址并不是容器的具體ip地址,而是一個虛擬ip,而且如果容器做了scale,那么通過VIP去訪問服務(wù)的時候Internal會幫我們做負載均衡。

Ingress網(wǎng)絡(luò):如果service有綁定端口,比如說我們本節(jié)的whoami綁定的8000端口,上一節(jié)的wordpress綁定的80端口,雖然這個service在cluster中的部分節(jié)點中運行,但是可以在swarm的任何節(jié)點通過對應(yīng)的端口訪問到服務(wù),這就是Ingress Routing Mesh。

下一節(jié)詳細介紹Ingress網(wǎng)絡(luò)。

?

總結(jié)

以上是生活随笔為你收集整理的从零开始学习docker(十九)Swarm mode 集群服务间通信--RoutingMesh的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。