Docker Engine 从v1.12.0版本开始,原生集成了 Docker Swarm,对集群的操作可以直接通过docker service命令来控制,非常方便,操作过程也大大简化。Docker Swarm 对于一般的开发者而言,最大的好处在于原生支持的负载均衡机制,能够有效的将service给scale up,借助 Raft Consensus 算法,将系统的 robustness 做得非常好,最大限度能够容忍 (n-1)/2 个故障节点。

具体关于 Docker Swarm 的介绍可以参考官方文档,写得非常有条理,这里我们按照官方给出的三节点的案例,在 Azure 的 VM 上搭建我们的 Swarm 集群。三个集群的角色分别为:

  • manager1
  • worker1
  • worker2

这个示例虽然跟下图并不完全一致,但各部分之间的关系还是可以通过这幅图大致了解的。

img

准备工作

  • 配置虚拟机,安装 Docker Engine
  • 打开 237779464789三个端口

img

这里给Azure打个小广告,相比阿里云的ECS,Azure的虚拟机管理更加完善,虽然一开始用会稍微有些麻烦,但熟悉之后就会发现网络、安全这些方面做得很详细。

搭建Swarm集群

创建管理节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Terminal in manager1

$ docker swarm init --advertise-addr 192.168.99.100
Swarm initialized: current node (dxn1zf6l61qsb1josjja83ngz) is now a manager.

To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
192.168.99.100:2377

To add a manager to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-61ztec5kyafptydic6jfc1i33t37flcl4nuipzcusor96k7kby-5vy9t8u35tuqm7vh67lrz9xp6 \
192.168.99.100:2377

这里的--advertise-addr参数用来标记当前管理节点发布出去后的网络地址,集群中的其他节点应该可以通过这个IP访问到管理节点。

当管理节点创建完成,我们可以通过docker infodocker node ls命令查看节点创建情况。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ docker info

Containers: 2
Running: 0
Paused: 0
Stopped: 2
...snip...
Swarm: active
NodeID: dxn1zf6l61qsb1josjja83ngz
Is Manager: true
Managers: 1
Nodes: 1
...snip...

$ docker node ls

ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
dxn1zf6l61qsb1josjja83ngz * manager1 Ready Active Leader

创建worker节点

根据前面命令行输出结果提示,现在将两台worker添加到集群中。记得执行时将相对应的token和IP地址换成实际情况中的值。

1
2
3
4
5
6
# Terminal in worker1
$ docker swarm join \
--token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
192.168.99.100:2377

This node joined a swarm as a worker.
1
2
3
4
5
6
# Terminal in worker2
$ docker swarm join \
--token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
192.168.99.100:2377

This node joined a swarm as a worker.

现在我们可以在manager1节点上查看集群中的所有节点

1
2
3
4
5
6
7
# Terminal in manager1
$ docker node ls

ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
03g1y59jwfg7cf99w4lt0f662 worker2 Ready Active
9j68exjopxe7wfl6yuxml7a7j worker1 Ready Active
dxn1zf6l61qsb1josjja83ngz * manager1 Ready Active Leader

到目前为止,集群环境搭建完毕。

部署测试服务

我们以部署nginx为例,测试我们搭建的Swarm集群。

1
$ docker service create --replicas 3 --publish 8080:80 --name helloworld nginx

这里的--replicas参数用来表示nginx需要部署多少个实例,因为这里是三台物理机器,如果replicas设为3,swarm会在三台机器上各部署一个实例。如果想要重新scale实例的个数,可以通过下面的命令。

1
docker service scale helloworld=5

我们可以通过一系列的命令去查看nginx的部署情况,例如

1
2
$ docker service inspect --pretty helloworld
$ docker service ps helloworld

删除一个服务也很简单,直接执行rm就可以了。

1
$ docker service rm helloworld