单独一个容器,存在的意义不大,无法横向扩展。因此需要一个编排系统来控制容器的生命周期,包括创建,部署,扩展,自动扩展,升级等等,目前这个默认是由kubenetes来完成的,但docker也提供了自己的编排系统叫做swarm。
Docker overlay network的提出,是为了实现swarm集群的对外提供服务,通常就是load balance负载均衡服务。服务的概念在docker的swarm集群和kubenetes中基本是一样的。
服务概念的提出是因为容器的生命周期是不确定,经常会存在重新生成,迁移等情况。一旦发生这些情况,容器的IP地址也发生了变化,而服务的地址是不变的。因而不管容器怎么变化,用户访问的IP地址永远不变。Overlay网络创建一个跨越多个docker主机的分布式网络,用户对于overlay网络IP的访问由docker透明转发给每个主机的每个容器。
Docker swarm启动后(docker swarm init)默认会产生一个overlay类型的网络ingress
frank@ubuntu:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
yqj5siq7377c ingress overlay swarm
在Swarm集群里面创建的service默认情况下自动连接到这个ingress网络。
如果有其他host需要加入这个swarm集群,则可以在启动docker后用命令
docker swarm join --token SWMTKN-1-2olksxxervw9fj4bokqcucb0ii9hh4ybkofnst3pvpcj07z7vh-9210hcxemu75pyygtcnq7xd4x 192.168.199.142:2377
这里的关键是token。
加入后可以通过命令docker node ls来查看swarm集群中的节点数量。
frank@ubuntu:~$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
bcukwug9ikt0u5on8f9lhqnrk * ubuntu Ready Active Leader
后面会看到这些命令跟kubenetes非常类似。逻辑本来就是一样的,swarm和kubenetes都是容器的编排系统,只不过swarm是docker原生的,kubenetes是来自google的,现在kubenetes明显胜出。
overlay network的架构如下图所示

也可以自己用下列命令创建一个overlay网络
$ docker network create -d overlay --attachable cisco
frank@ubuntu:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
8e3dd79a135a bridge bridge local
ugkc3cyhn8pk cisco overlay swarm
然后创建一个service挂到这个overlay 网络(这个只是把容器挂到了这个overlay网络,对外提供服务的地址还是挂载在ingress overlay网络)
$ docker service create --name my-nginx --publish target=80,published=80 \ --replicas=2 --network cisco nginx
frank@ubuntu:~$ docker service ls
ID NAME MODE REPLICAS IMAGE
po195ps9ld69 my-nginx replicated 2/2 nginx:latest
检查overlay network(docker inspect cisco),可以看到挂接了两个container
"Containers": {
"53e38da31894b8423ddc9135b5de1419fd5a185aa4cbdd1d6d56e573cb1c0a04": {
"Name": "mydocker.1.md0zesv11i2revbwzuniczp6h",
"EndpointID": "3f395e169aeb9b4fb184bf38a242676fb69952a2a5d00c071a5b49a8edcf9bd4",
"MacAddress": "02:42:0a:00:00:04",
"IPv4Address": "10.0.0.4/24",
"IPv6Address": ""
},
"64ed89a47dbfb16221a06e7229d1615e913036c09db07032e10c55b2f4206d67": {
"Name": "mydocker.2.ilj4qfdn248odo4eqe79qc7ft",
"EndpointID": "b0bedd2dce5437ebd03621cdfa8cf7b47b534ffac71fb6b3aeeb960af4e01de7",
"MacAddress": "02:42:0a:00:00:03",
"IPv4Address": "10.0.0.3/24",
"IPv6Address": ""
}
},
检查默认的ingress网络,可以发现这个网络上除了attach了两个容器外,还挂了一个虚地址。
"Containers": {
"53e38da31894b8423ddc9135b5de1419fd5a185aa4cbdd1d6d56e573cb1c0a04": {
"Name": "mydocker.1.md0zesv11i2revbwzuniczp6h",
"EndpointID": "43cdf011149e57b8e1aebcdc8af9eedfa28c7e5cce2b8e78afbb42cb88ec18e7",
"MacAddress": "02:42:0a:ff:00:06",
"IPv4Address": "10.255.0.6/16",
"IPv6Address": ""
},
"64ed89a47dbfb16221a06e7229d1615e913036c09db07032e10c55b2f4206d67": {
"Name": "mydocker.2.ilj4qfdn248odo4eqe79qc7ft",
"EndpointID": "927e8527519da0d3c0615b86f696eeea3c68b4e06bbabca7e0a6c6693925d4de",
"MacAddress": "02:42:0a:ff:00:05",
"IPv4Address": "10.255.0.5/16",
"IPv6Address": ""
},
"ingress-sbox": {
"Name": "ingress-endpoint",
"EndpointID": "42524c9f035815a5b767e963bd420316bfd0d291f35d31f2864b1fed149eb37a",
"MacAddress": "02:42:0a:ff:00:03",
"IPv4Address": "10.255.0.3/16",
"IPv6Address": ""
}
},
检查swarm service my-nginx(docker inspect my-nginx)
"Endpoint": {
"Spec": {
"Mode": "vip",
"Ports": [
{
"Protocol": "tcp",
"TargetPort": 80,
"PublishedPort": 80,
"PublishMode": "ingress"
}
]
},
"Ports": [
{
"Protocol": "tcp",
"TargetPort": 80,
"PublishedPort": 80,
"PublishMode": "ingress"
}
],
"VirtualIPs": [
{
"NetworkID": "t0q7o3qnje8wnc9fpamka88xz",
"Addr": "10.255.0.4/16"
},
{
"NetworkID": "plbxreq6bks9zkg8hb4o2rrb8",
"Addr": "10.0.0.2/24"
}
]
},
service 已经发布在主机的或者说是这个swarm集群的地址上,可以从外部访问。主机地址和service IP之间的转换是通过iptables
C:\Windows\system32>curl 192.168.199.142
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
理论上多访问几次就会在容器之间进行负载均衡。
kill任何一个容器,swarm service会自动再创建一个容器,但新容器的地址和旧的不一定一样。但对外提供服务的地址不变,但新的容器可能采用新的地址




