创建overlay网络
docker network create -d overlay swarm-overlay
创建whoami容器
jwilder/whoami镜像支持通过http请求来获取主机的hostname
docker service create --name whoami -p 8000:8000 --network swarm-overlay -d jwilder/whoami
创建busybox容器
docker service create --name busybox --network swarm-overlay -d busybox /bin/sh -c "while true;do sleep 3600;done"
查看服务
# 服务列表
[vagrant@swarm-manager ~]$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
zq7ulpxk83nq busybox replicated 1/1 busybox:latest
q1j2ddophtom whoami replicated 1/1 jwilder/whoami:latest *:8000->8000/tcp
# busybox节点分布
[vagrant@swarm-manager ~]$ docker service ps busybox
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
yzquayg07i2a busybox.1 busybox:latest swarm-work2 Running Running 23 seconds ago
# whoami节点分布
[vagrant@swarm-manager ~]$ docker service ps whoami
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
1diq1k8h38o5 whoami.1 jwilder/whoami:latest swarm-work1 Running Running 43 seconds ago
发现busybox部署在了swarm-work2(192.168.205.12)节点上,whoami部署在了swarm-work1(192.168.205.11)节点上
网络测试
在swarm-work2
节点上测试,发现是可以ping通swarm-work1节点的上whoami容器的
[vagrant@swarm-work2 ~]$ docker exec c2f9bbbea76c ping whoami
PING whoami (10.0.1.10): 56 data bytes
64 bytes from 10.0.1.10: seq=0 ttl=64 time=0.058 ms
64 bytes from 10.0.1.10: seq=1 ttl=64 time=0.198 ms
64 bytes from 10.0.1.10: seq=2 ttl=64 time=0.332 ms
但是有一个问题,10.0.1.10
并不是whoami容器的对外IP,因为我们将whoami容器扩展到3台之后,返回的ip也都是10.0.1.10
docker service scale whoami=3
然后对其中一台whoami容器上执行如下命令,发现10.0.1.10
只是lo网卡上的一个ip,确实不是对外ip。
[vagrant@swarm-manager ~]$ docker exec ac13768a6699 ip a
1: lo: mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 10.255.0.6/32 brd 10.255.0.6 scope global lo
valid_lft forever preferred_lft forever
inet 10.0.1.10/32 brd 10.0.1.10 scope global lo
valid_lft forever preferred_lft forever
23: eth0@if24: mtu 1450 qdisc noqueue state UP
link/ether 02:42:0a:ff:00:08 brd ff:ff:ff:ff:ff:ff
inet 10.255.0.8/16 brd 10.255.255.255 scope global eth0
valid_lft forever preferred_lft forever
25: eth1@if26: mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.3/16 brd 172.18.255.255 scope global eth1
valid_lft forever preferred_lft forever
28: eth2@if29: mtu 1450 qdisc noqueue state UP
link/ether 02:42:0a:00:01:0e brd ff:ff:ff:ff:ff:ff
inet 10.0.1.14/24 brd 10.0.1.255 scope global eth2
valid_lft forever preferred_lft forever
如果我们使用nslookup命令,也能证实10.0.1.10
并不是真实IP
[vagrant@swarm-work2 ~]$ docker exec -it c2f9bbbea76c /bin/sh
/ # nslookup tasks.whoami
Server: 127.0.0.11
Address 1: 127.0.0.11
Name: tasks.whoami
Address 1: 10.0.1.14 ac13768a6699.swarm-overlay
Address 2: 10.0.1.15 whoami.3.n249t5179xlde8tpymb0r5zwm.swarm-overlay
Address 3: 10.0.1.11 whoami.1.1diq1k8h38o5ase5pmuaodr0u.swarm-overlay
事实上,10.0.1.10
是service考虑到容器的扩展,为多个相同的容器分配的一个统一的对外IP、虚拟IP,即service ip、VIP
负载均衡
通过VIP,一个域名解析到多个容器,我们也能够看到负载均衡的效果了
# 第一次访问
wget whoami:8000
Connecting to whoami:8000 (10.0.1.10:8000)
index.html 100% |*****************************************************************************************************************| 17 0:00:00 ETA
cat index.html
I'm ac13768a6699
# 第二次访问
rm -rf index.html
wget whoami:8000
Connecting to whoami:8000 (10.0.1.10:8000)
index.html 100% |*****************************************************************************************************************| 17 0:00:00 ETA
cat index.html
I'm 409eef9c93da