一、Swarm Overlay Network
Swarm有Service的概念。一個Service是指使用相同鏡像、同時運行的多個容器,多個容器同時一起對外提供服務,多個容器之間負載均衡。每個Service會有一個浮動IP(VIP),各個容器還有自己的物理IP。
創建基於Swarm的Overlay網絡,將Service掛載到此網絡上。然后Service中的各個容器便可以通過Service名稱(同時也是一個DNS名稱)和IP地址實現網絡互通。
同一個Service內,多個容器之間的負載均衡有兩種方案:
- 基於浮動IP(VIP)進行均衡
- 基於DNS解析出不同的IP地址進行均衡
swarm模式的覆蓋網絡包括以下功能: 1)可以附加多個服務到同一個網絡。 2)默認情況下,service discovery為每個swarm服務分配一個虛擬IP地址(vip)和DNS名稱,使得在同一個網絡中容器之間可以使用服務名稱為互相連接。 3)可以配置使用DNS輪循而不使用VIP 4)為了可以使用swarm的覆蓋網絡,在啟用swarm模式之間需要在swarm節點之間開放以下端口: 5)TCP/UDP端口7946 – 用於容器網絡發現 6)UDP端口4789 – 用於容器覆蓋網絡
二、創建swarm overlay 網絡
2.1 創建overlay網絡
[root@manager ~]# docker network create --driver overlay --opt encrypted --subnet 10.10.1.0/24 ol_net 參數解釋: –opt encrypted 默認情況下swarm中的節點通信是加密的。在不同節點的容器之間,可選的–opt encrypted參數能在它們的vxlan流量啟用附加的加密層。 --subnet 命令行參數指定overlay網絡使用的子網網段。當不指定一個子網時,swarm管理器自動選擇一個子網並分配給網絡。 [root@manager ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 40b5590f7216 bridge bridge local cb1610f00364 docker_gwbridge bridge local 9fa64715b4f2 host host local 2mhfiejb2g77 ingress overlay swarm 168285bc1c23 none null local mun52zjgstgx ol_net overlay swarm 由上可知,Swarm當中擁有2套覆蓋網絡。其中"ol_net"網絡正是我們在部署容器時所創建的。而"ingress"覆蓋網絡則為默認提供。 Swarm 管理節點會利用 ingress 負載均衡以將服務公布至集群之外。 在將服務連接到這個創建的網絡之前,網絡覆蓋到manager節點。上面輸出的SCOPE為 swarm 表示將服務部署到Swarm時可以使用此網絡。 在將服務連接到這個網絡后,Swarm只將該網絡擴展到特定的worker節點,這個worker節點被swarm調度器分配了運行服務的任務。 在那些沒有運行該服務任務的worker節點上,網絡並不擴展到該節點。
2.2 將服務連接到overlay網絡
[root@manager ~]# docker service create --replicas 5 --network ol_net --name my-nginx -p 80:80 nginx etq3t5muc0lnpqr14e3sodmno overall progress: 0 out of 5 tasks overall progress: 5 out of 5 tasks 1/5: running [==================================================>] 2/5: running [==================================================>] 3/5: running [==================================================>] 4/5: running [==================================================>] 5/5: running [==================================================>] verify: Service converg
在三個節點上服務都運行起來了,所以overlay網絡(ol_net)擴展到了3個節點上
2.3 查看my-nginx的ip信息
# 管理節點查看service vip [root@manager ~]# docker service inspect --format='{{json .Endpoint.VirtualIPs}}' my-nginx [{"NetworkID":"2mhfiejb2g77mfxss4dtu18h9","Addr":"10.255.0.89/16"},{"NetworkID":"mun52zjgstgxxinskkfqm4qt1","Addr":"10.10.1.89/24"}] # 10.10.1.89 就是swarm集群中my-nginx服務的vip
# 工作節點的ip,依次查看所有容器的ip [root@node-01 ~]# docker network inspect ol_net ......... "Containers": { "44e23ef7b17ec94d370866f51460a1d600c29018ff388e374581bc72d5466269": { "Name": "my-nginx.5.0aj9swgnsxgz4iwu63lsx5bgd", "EndpointID": "2956e153e67f42cf7785d41484d57640db19b4ae1bb712f1a53b89f672010115", "MacAddress": "02:42:0a:0a:01:5e", "IPv4Address": "10.10.1.94/24", "IPv6Address": "" } },
這里5個replicas的ip分別為10.10.1.90~94,整個網絡結構如下:
加入到同一個overlay網絡中的容器彼此間可以相互通過IP地址通信,也可以通過名稱通信。(nginx鏡像沒有網絡工具。。。,不能給出測試截圖)
三、使用swarm的服務發現
默認情況下,當創建了一個服務並連接到某個網絡后,swarm會為該服務分配一個VIP。此VIP根據服務名映射到DNS。在網絡上的容器共享該服務的DNS映射,
所以網絡上的任意容器可以通過服務名訪問服務。
在同一overlay網絡中,不用通過端口映射來使某個服務可以被其它服務訪問。Swarm內部的負載均衡器自動將請求發送到服務的VIP上,然后分發到所有的active的task上。
在同一個網絡中添加了一個centos服務,此服務可以通過名稱my-test訪問前面創建的nginx服務 [root@manager ~]# docker service create --name my-centos --network ol_net centosos 為這個服務添加一個task,不然不能正常運行 [root@manager ~]# docker service update --args "ping www.baidu.com" my-centos 查看在哪個節點上運行 [root@manager ~]# docker service ps my-centos ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS i2skqpwsd80g my-centos.1 centos:latest node-01 Running Running 18 seconds ago 打開交互 [root@node-01 ~]# docker exec -it 127e0e79f6eb /bin/bash
在centos內部,ping同my-nginx服務中的容器和服務本身,以及DNS查詢
# 和my-nginx服務通信 [root@127e0e79f6eb /]# ping 10.10.1.89 PING 10.10.1.89 (10.10.1.89) 56(84) bytes of data. 64 bytes from 10.10.1.89: icmp_seq=1 ttl=64 time=0.032 ms ^C --- 10.10.1.89 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.032/0.032/0.032/0.000 ms [root@127e0e79f6eb /]# ping 10.10.1.92 PING 10.10.1.92 (10.10.1.92) 56(84) bytes of data. 64 bytes from 10.10.1.92: icmp_seq=1 ttl=64 time=0.462 ms 64 bytes from 10.10.1.92: icmp_seq=2 ttl=64 time=0.252 ms #使用特殊查詢 查詢DNS,來找到my-nginx服務的所有容器的IP地址: [root@127e0e79f6eb /]# nslookup > my-nginx Server: 127.0.0.11 Address: 127.0.0.11#53 Non-authoritative answer: Name: my-nginx Address: 10.10.1.89 > tasks.my-nginx Server: 127.0.0.11 Address: 127.0.0.11#53 Non-authoritative answer: Name: tasks.my-nginx Address: 10.10.1.92 Name: tasks.my-nginx Address: 10.10.1.90 Name: tasks.my-nginx Address: 10.10.1.91 Name: tasks.my-nginx Address: 10.10.1.94 Name: tasks.my-nginx Address: 10.10.1.93 #從centos容器內部,通過wget來訪問my-nginx服務中運行的nginx網頁服務器 [root@127e0e79f6eb /]# wget -O- my-nginx --2018-04-10 09:21:27-- http://my-nginx/ Resolving my-nginx (my-nginx)... 10.10.1.89 Connecting to my-nginx (my-nginx)|10.10.1.89|:80... connected. HTTP request sent, awaiting response... 200 OK Swarm的負載均衡器自動將HTTP請求路由到VIP上,然后到一個active的task容器上。它根據round-robin選擇算法將后續的請求分發到另一個active的task上。
使用dnsrr模式,不能對外暴露端口,只能overlay網絡內部識別
#創建 [root@manager ~]# docker service create \ > --replicas 5 \ > --name web-test \ > --network ol_net \ > --endpoint-mode dnsrr \ > nginx # 查看 [root@manager ~]# docker service ps web-test ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS pjb8x0i0w5yy web-test.1 nginx:latest node-02 Running Running 3 minutes ago 5uora7bbgxyc web-test.2 nginx:latest node-01 Running Running 3 minutes ago uwxxqipk1nd3 web-test.3 nginx:latest node-02 Running Running 3 minutes ago iuneh99mli2d web-test.4 nginx:latest node-01 Running Running 3 minutes ago q2vz2y1upfu9 web-test.5 nginx:latest node-03 Running Running 3 minutes ago # 在my-centos容器中測試聯通 [root@0709f126d547 ~]# nslookup web-test Server: 127.0.0.11 Address: 127.0.0.11#53 Non-authoritative answer: Name: web-test Address: 10.10.1.36 Name: web-test Address: 10.10.1.38 Name: web-test Address: 10.10.1.34 Name: web-test Address: 10.10.1.35 Name: web-test Address: 10.10.1.37 # 任務會負載到各個容器 [root@0709f126d547 ~]# ping web-test PING web-test (10.10.1.34) 56(84) bytes of data. 64 bytes from web-test.1.pjb8x0i0w5yys4la6ibqavvcf.ol_net (10.10.1.34): icmp_seq=1 ttl=64 time=0.050 ms ^C --- web-test ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.050/0.050/0.050/0.000 ms [root@0709f126d547 ~]# ping web-test PING web-test (10.10.1.35) 56(84) bytes of data. 64 bytes from web-test.2.5uora7bbgxycg0ja2dj1l10us.ol_net (10.10.1.35): icmp_seq=1 ttl=64 time=0.334 ms [root@0709f126d547 ~]# ping web-test PING web-test (10.10.1.37) 56(84) bytes of data. 64 bytes from web-test.4.iuneh99mli2dpydycfvy0zefw.ol_net (10.10.1.37): icmp_seq=1 ttl=64 time=0.275 ms
四、Swarm的負載均衡
4.1 Swarm 內部負載
Swarm模式內置DNS組件,可以自動為集群中每一個服務分配DNS記錄。Swarm manager使用內部負載均衡,根據服務的DNS名稱在集群內的服務之間分發請求。
Swarm manager使用ingress load blancer暴露想從外部訪問集群提供的服務。Swarm manager 自動分配一個范圍為3000~32767端口的Published Port,也可以為該服務指定一個Published Port,如上例my-web的80端口。
ingress network是一個特殊的overlay網絡,便於服務的節點直接負載均衡。當任何swarm節點在發布的端口上接受到請求時,它將該請求轉發給調用的IPVS模塊,IPVS跟蹤參與該服務的所有容器的IP地址,並選擇其中一個,通過ingress network將請求路由給它。
查看請求:
從172.16.60.95~98都能訪問nginx服務器
4.2 應用外部負載均衡
可以在工作節點之外也能使用負載均衡,即在外部添加Nginx、LVS、HAProxy等