Docker Swarm建立服务器集群
- 一、Docker Swarm简介
- 1. 集群模式
- 2. 管理节点--Manager
- 二、Docker Swarm的配置及使用
- 三、Docker Service向集群中添加服务
- 四、Docker Stack部署集群
一、Docker Swarm简介
1. 集群模式
这是Docker官网给出的一张swarm原理图,即swarm就是一个或多个Docker Engine的集群,负责集群的管理和编排。
Manager
负责维持集群状态并进行调度服务。(基于Raft算法)
Worker
是Docker Engine的实例,其唯一目的是执行容器。工作程序节点不参与Raft分布式状态,不制定调度决策。
Raft(共识算法)原本是一种针对简化版拜占庭将军问题的解决方法。但被广泛映射在分布式系统上,解决集群状态下会遇到的各种问题。
- Raft算法将所有节点分为Follower,Candidate,Leader三种状态。分别为追随节点,选举节点,管理节点。
- Raft算法主要分为两个过程,
选主
和复制日志
。其中选主故名思意,就是各节点通过投票选出Leader节点;复制日志这里举一个例子,比如服务器A(Leader)接收到用户1传来的更新数据库请求,要存入数据temp,此时A会将该更新请求同步至服务器B(Follower)和服务器C(Follower),B和C收到之后将数据暂时存在本地,将其状态置为UnCommitted,并返回OK,A收到半数Follower节点返回后,将数据写入并返回成功给用户1,此时B,C再将数据提交状态置为Committed。
上面大致介绍了Raft算法,具体的算法执行流程,可以在这里看到:Raft算法
2. 管理节点–Manager
下面是官网给出的Docker swarm集群的四点要求:
- 一个由三名经理组成的群体最多可以容忍一名经理的损失。
- 五个管理器群最多可以同时丢失两个管理器节点。
- 一个N管理器群集最多可以容忍管理器的丢失 (N-1)/2。
- Docker建议最多为七个管理器节点。
重要说明:添加更多管理器并不意味着增加可伸缩性或更高性能。通常,情况恰恰相反。
说明。
为什么要强调管理群集的可用节点数必须大于总结点数的一半?
首先,集群在节点之间通信不可达的情况下,集群会分裂成不同的小集群,小集群各自选出自己的Leader节点,导致原有的集群出现多个Leader节点的情况,当各集群重新可以通信时,多个Leader节点将使得群集发生紊乱,我们将这种情况称为脑裂。
这里给出一个文章中举出的例子帮助理解:
(1) 假如集群有 5 个节点,发生了脑裂,脑裂成了A、B两个小集群:
(a) A : 1个节点 ,B :4个节点 , 或 A、B互换(b) A : 2个节点, B :3个节点 , 或 A、B互换上面这两种情况下,A、B中总会有一个小集群满足 可用节点数量 > 总节点数量/2 。所以集群仍然能够选举出leader , 仍然能对外提供服务,只不过是有一部分节点失效了而已。
(2) 假如集群有4个节点,同样发生脑裂,脑裂成了A、B两个小集群:
(a) A:1个节点 , B:3个节点, 或 A、B互换 (b) A:2个节点 , B:2个节点可以看出,情况(a) 是满足选举条件的,与(1)中的例子相同。 但是情况(b) 就不同了,因为A和B都是2个节点,都不满足 可用节点数量 > 总节点数量/2 的选举条件, 所以此时集群就彻底不能提供服务了。
结论:节点数量是奇数个的情况下, 集群总能对外提供服务(即使损失了一部分节点);如果节点数量是偶数个,会存在集群不能用的可能性(脑裂成两个均等的子集群的时候)。
二、Docker Swarm的配置及使用
- 准备四台安装了docker的阿里云服务器。
- 将172.24.111.113作为Manager节点创建集群。
由于四台服务器在同一地区,私有IP可以相互ping通,所以这里可以使用私有IP作为docker swarm的广播IP
docker swarm init --advertise-addr 172.24.111.116
运行后出现如下成功提示:
3. 将其他服务器加入该集群。
docker swarm join-token worker
docker swarm join-token manager
运行成功后,我们会拿到加入该集群所需的相应令牌。
我们只需要在其他服务器中,输入对应令牌,即可以相应的身份加入到集群中。
docker swarm join --token 对应令牌
运行后出现如下成功提示:
如果想要退出集群,直接输入下面的命令:
docker swarm leave
- 查看建立完毕的集群。
docker node ls
Reachable,Leader节点均属于Manager节点,只有Manager节点才可以参与选举
你必须实时保证可用Manager节点数大于总Manager节点数的一半。如果我们现在停止三号节点的运行,由于运行的Manager只剩下一个,会出现如下图提示:
三、Docker Service向集群中添加服务
docker service命令类似于docker run,前者是运行一个服务,支持增扩容,只允许在集群中使用;后者单纯是一个容器,不支持增扩容。
replicated随机分配给任一节点,global模式为全局所有节点统一分配
docker service create --name 服务名A --mode replicated/global 镜像名B
# 我们根据对应镜像,在集群中运行一个服务。注意这个服务会随机运行在集群中的任何一个服务器中。
# mode 定义该服务是随机一个节点运行一个副本还是所有节点均运行一个副本
docker service update --replicas 10 A
# 扩容,在这个集群中运行10个A服务
docker service update --replicas 1 A
# 缩容,在这个集群中运行1个A服务
docker service scale A=服务数量
# 等同于上面的update命令,都是用来扩缩容
命令 | 功能 |
---|---|
docker service ls | 查看全部服务 |
docker service ps 服务名A | 查看A的所有进程 |
docker service inspect 服务名A | 查看A的全部信息 |
docker service ls | 查看全部服务 |
docker service rm 服务名A | 从集群中删除一个服务已运行进程全部删除 |
四、Docker Stack部署集群
docker compose只能进行单机部署,而在docker compose中,我们使用docker stack进行集群部署。docker compose 与 docker stack 都使用docker-compose.yml进行服务配置。
Service:一个service只能运行一个image,但是可以运行出同一个image的多个containers(即这个images内可能包含多个容器)。
Stack:一个Stack是一组相互关联的services,这组service共享依赖,可被安排在一起运行和扩展。
docker stack deploy 服务名A --compose-file=docker-compose.yml
# 使用yml在集群中建立一个stack
docker stack services A
# 查看stack A中的所有容器
docker stack ls
# 查看所有stack
docker stack rm A
# 删除一个stack
docker logs 容器ID
# 根据容器ID查看日志,解决docker stack创建容器无法实时看到日志的问题