什么是Docker Swarm
Docker Swarm是Docker公司推出的用来管理Docker集群的平台,Swarm是容器集群管理工具,可以统一管理分布在不同主机的多个容器,相比起Kubenetes,Docker Swarm无需额外安装。
下面这个图,就可以看到docker swarm管理docker的一个架构图。以前使用docker命令行是针对docker主机的,然后到这台机器上单独的控制这台机器上的主机,有了swarm之后,客户端命令是针对docker集群的。它的命令几乎等同于docker的原生命令,它把命令发送给swarm,swarm选择发送一个节点去真正的执行,swarm是通过docker自带的远程的API,来实现对docker的控制。
Docker Swarm 设计架构
因为是集成在Docker之中,由Docker Client向Swarm发送指令。每个Docker engine实例称为一个Node,既可以是物理机,也可以是虚拟机。分为manager和worker。worker只负责接收并执行任务,manager在此基础上还要接收用户指令,服务调度,服务发现...
docker Client 在manager节点的外边,假如执行了docker service create,先会经过Swarm接受这条命令,传给Scheduler模块,Scheduler模块主要实现调度的功能,负责选择出来最优的节点,里面包含了2个子模块,Fiter 和Strategy,Fiter很明显是过滤节点,用来找出满足条件的节点(资源足够多,节点正常的),Strategy是过滤出来后选择出最优的节点(对比选择资源剩余最多的节点,或者找到资源剩余最少的节点),当然Fiter 和Strategy都是用户可以单独定制的,中间的Cluster是抽象的worker节点集群,包含了Swarm节点里面每个节点的信息,右边的Discovery是信息维护的模块,比如Label Health。Cluster最终调用容器的api,完成容器启动的刘而成。
filter
- Constraints
约束过滤器,根据当前的操作系统的类型,内核版本,存储的类型进行指标上的约束,也可以自定义约束。当前系统启动的时候可以通过label指定当前机器所具有的特性然后通过Constraints把他们过滤出来。
- Affinity
亲和性过滤器,支持容器的亲和性和镜像的亲和性,比如一个应用,DB容器和web容器放在一起,就可以通过这个来实现,
- Dependency
依赖过滤器,link等等吧Dependency会将这些容器放在同一个节点上,有依赖管理的会将创建的容器和依赖的容器放在同一个节点上。
- Health filter
健康过滤器,根据节点的健康状态进行过滤,把有问题的节点去掉。
- Ports filter
端口过滤器,根据端口的使用情况进行过滤,比如一个8080端口在某个主机上被占用,某些主机未被占用,会选用未被占用的那些主机。
Strategy
- Binpack
在同等情况下,会使用资源最多的节点,通过这个策略可以让容器聚集起来。
- Spread
在同等情况下,会使用资源最少的节点,通过这个策略可以让容器均匀的分布在每个节点上。
- Random
随机选择一个节点。
Node架构
Manager nodes
Manger 节点,顾名思义,是进行 Swarm 集群的管理工作的,它的管理工作集中在如下部分,
- 维护一个集群的状态;
- 对 Services 进行调度;
- 为 Swarm 提供外部可调用的 API 接口;
Manager 节点需要时刻维护和保存当前 Swarm 集群中各个节点的一致性状态,这里主要是指各个 Tasks 的执行的状态和其它节点的状态;因为 Swarm 集群是一个典型的分布式集群,在保证一致性上,Manager 节点采用 Raft 协议来保证分布式场景下的数据一致性;
Worker nodes
Worker 节点和 Manager 节点一样,同样都是运行在宿主机上的 Docker Engine,只是 Worker 节点的目的更为简单,它就是用来执行 Task 的;而默认情况下 Manager 节点也同样是 Worker 节点,同样可以执行 Task;其它更多有关 Worker nodes 的相关操作,参看笔者的实战篇;
Service工作原理
为了部署一个应用的镜像到Swarm模式的Docker Engine中,我们需要创建一个service。通常service是拥有大型应用系统上下文信息的微服务镜像。例如,一个服务可能包含一个HTTP服务器、一个数据库、或者其他的软件,我们需要这些软件运行在一个分布式环境中。
当创建service时,我们需要指定用什么镜像运行container,以及container内部运行什么样的命令。我们还需要定义以下内容:
- service向Swarm以外暴露的可用端口
- 一个overlay network,用来支持service之间相互通信
- CPU和内存的限制和预设
- 滚动更新的策略
- 镜像在Swarm中运行的副本数
Services,Tasks 和 Containers 之间的关系
当我们部署一个service到swarm时,manager节点将接受我们对service定义,并作为service的理想状态。Manager节点在swarm节点之间调度service的副本。不同节点上运行的task是相互独立的。
例如,我们设想在3个HTTP监听实例之间实现负载均衡。下图展示了拥有3个副本的HTTP监听器。每一个监听器实例就是一个swarm中的task。
一个container是一个被隔离的进程。在swarm模式的模型中,每一个task运行一个container。task就像调度器放置container使用的一个“槽”。一旦container运行起来,调度器就能意识到task是在运行状态。如果container不可用或者被终止,则task也将被终止。
task和调度
task是swarm调度的原子单元。当创建和更新service时,我们声明了service的理想状态,协调器通过调度task来实现这个理想状态。例如,我们定义了一个service,要求协调器在任何时候都能保证有3个HTTP监听器在运行。协调器创建3个task作为回应。每一个task就像一个“槽”,调度器将产生3个container放在“槽”中。container是task的一个实例。当一个HTTP监听器不可用或者崩溃,协调器将创建一个新的task副本,并放入一个新的container。
task的状态变化采用一种单向机制。贯穿task生命周期的状态有:已分配状态、已准备状态、正在运行状态,等等。如果task运行失败了,协调器会移除这个task并停止它的container,然后创建新的task替代它,以保证service定义的理想状态。
Swarm模式背后的逻辑其实是一种通用的调度器和协调器逻辑。service和task被抽象设计成并不需要知道他们实现的container是什么样的。假设,我们可以实现其他类型的task,例如虚拟机task或者非容器化的进程task。调度器和协调器并不需要知道task的类型。然而,当前版本的Docker只支持容器task。
下图展示了Swarm模式如何接收service的创建请求,并调度task到worker节点。
复制和全局service
有两种service的部署模式,复制和全局。
设置task的数量来实现复制模式下的service。例如,想要部署3个副本的HTTP服务,每个副本都提供相同的服务。
全局service是在所有节点上都有一个task的service。不能指定task的数量。每次增加一个节点,协调器会创建一个task,并有调度器分配到新节点上。全局service的最佳应用是部署监控代理,病毒扫描,以及其他希望在swarm中每个节点上都部署的service。
下图展示了3个副本的service和一个全局service部署在swarm中的情况,黄色代表3个副本的service,灰色代表全局service: