前言
此篇博文是笔者所总结的 Docker 系列之一;
本文为作者的原创作品,转载需注明出处;本文采用是 Docker Engine 1.12;
概述
Docker Swarm 的集群管理能力和编排能力是由嵌入在 Docker Engine 的 swarmkit 实现的;
Docker Swarm 是由一系列运行在 swarm mode 模式下的 Docker hosts 组成的,Docker host 也称作 Docker node,这些 node 有两种不同的角色,
manager node
- 用来集中管理运行在 swarm 集群节点上的 services,比如修改 service 的配置,网络以及 volumes 等;
- 用来调度 Service 到 worker node 上执行;
需要注意的是,一个 manager node 同时也可以是 worker node,可以执行由 manager node 分派的任务 task;
worker node
执行由 manager 分发的 task (也可称作 service 或 Swarm serivce);
也就是说,Docker host 可以不加入 Swarm 集群而独立运行,该模式称作 standalone mode 模式,运行的是 Docker containers;而如果是 swarm mode 模式下,运行的是 Docker Swarm services (虽然本质上仍然是 Docker containers,但是为了区分,叫法不同,当然特性也不同);Docker containers 和 Docker Swarm services 之间的区别是,Swarm services 只能通过 manager node 控制和管理,而 Docker containers 由 Docker Daemon 进行控制和管理;
Docker Swarm 的主要特性有,
- 去中心化设计
每个 Docker host 都会保存集群的状态信息,通过 Gossip 协议将最新信息散布到集群的其它节点上,并实现最新信息的同步;后续可以看到 Docker Network Control Plane 正是基于此实现的去中心化管理; - 扩容
在笔者的实战篇中可以看到,通过 Docker Swarm 进行扩容非常的容易; - 自动容错 (Desired state reconciliation)
如果某个 service _A_ 配置了 10 个执行副本 replicas,那么如果某些运行了 service _A_ 的节点出现了故障,那么 Docker Swarm 会自动的将故障节点上的 _A_ 迁移到到其它的 node 上; - 容器间网络连接 (Multi-host networking)
容器之间可以通过 Swarm Overlay network 实现直接通讯,这部分内容,笔者将会在 Overlay network 文章中专门进行描述; - 服务发现 (Service Discovery)
Swarm manager 为每个运行在 Swarm 上的 service 都分配了一个唯一的 DNS 名字,通过该 DNS 名字便可以直接找到 service 的服务地址;不过 Swarm 的强大之处在于,DNS 的寻找过程是去中心化的,也就是说任何一个 service 请求可以通过 Swarm 集群中的任何一个 node 进行请求转发,转发至该 service 的服务地址上,即便是当前的 node 上并没有运行该 service,这得益于 Docker Network Control Plane 的设计,使得每个 Swarm node 都能够保存当前 Swarm 网络的最新状态和数据;同时,通过这样的设计 Docker Swarm 实现了自己的基于 DNS 的 Load Balance; - Load balancing
可以将一个 service 的端口暴露给一个外部负载均衡器( external load balancer ),实际上就是将 service 的端口映射到该外部负载均衡器上;这样,便可以通过这个外部负载均衡器的端口直接访问到该服务; - 默认的安全行为
默认情况下,所有的 swarm node 之间的通讯都是通过 TLS 进行加密的; - 滚动更新 (Rolling Updates)
在保证旧的服务可用的前提下,对服务进行平滑升级;这样可以保证服务不中断;
Nodes
一个节点 node 指的就是一个加入 Swarm 的 Docker engine,一个 Swarm 集群就是由数个这样的 node 所构成;要将一个应用部署到 Swarm 集群中运行,就是指将一个 service definition 提交给 manager node,然后再由 manager node 根据该 service definition 生成相应的 task 并分发给指定的 worker node 执行;
Services and tasks
Service 指的是 Task 的定义和说明,而 Task 则是最终在 Nodes 上所执行的任务,也就是最终运行的 Container;不过很多时候,我们在说 Service 的时候,也就指的是 Task;不过也要注意它们之间的区别,通常 Service 是指的 Task 的描述和定义,这份描述和定义是唯一的,而 Task 在 Swarm 集群下往往有多个执行的副本,因此 Service 和 Task 是 1:n 的关系;
当你在 manager node 上创建一个 Service 的时候( 通过 docker service create 命令 ),需要指定 docker image、参数以及在 Container 中所要运行的命令( Command ),然后 manager node 会根据该 definition (定义)生成 Task 并发送给指定的 Worker Node 执行;
创建 Service 的时候可以指定所需执行的副本的数量和方式,指定的方式有两种,
- replicated service 模式,
可以显示的指定需要多少个在 Swarm 集群中同时执行的 task 副本; - global services 模式,
表示每一个 Swarm 集群的 node 都会启动并执行该 task;
A task carries a Docker container and the commands to run inside the container.
这里给出了 task 的定义,可以看到,task 本身就是一个 Docker container;
负载均衡 Load Balancing
Swarm manager 通过 ingress load balancing 将 Services 暴露出去;过程中,Swarm manager 可以随机的自动的分配一个 PublishPort 给该 Service,或者用户可以为该 Service 自定义 PublishPort,需要注意的是,如果是 Swarm manager 随机分配的端口,范围在 30000-32767 之间;
外部的访问,比如云负载均衡器比如阿里的 SLB,要访问某个 Service,可以通过 Swarm 集群中的任何一个节点上的 PublishPort 访问到该 Service,无论该节点是否运行了该 Service 所对应的 Task 与否,因为任何一个节点都可以将该请求正确的转发至运行了该 Task 的 Node 上;之所以可以这样,得益于 Swarm 实现了一个去中心化的网络维护中心既 Docker Network Control Plane,使得集群中的任何一个 Node 都实时的完整的保存了当前 Swarm 集群的网络状态和参数,这样,任何一个 Node 都知道其它 Node 的网络地址和运行状态;从具体实现上来看,Swarm 在其内部实现了一套内部的 DNS 服务,每一个在 Swarm 中运行的 Service 都有一个唯一对应的 DNS,这样,外部访问可以通过该服务的 DNS 直接在 Swarm 中找到其对应的服务地址并建立连接请求;
整理接下来的整理思路
- swarm mode overview 和 swarm mode 和核心概念
- 实战篇
- 架构篇,Docker swarm mode 是如何工作的
- 深入创建 Swarm 和管理 Swarm 节点
- 深入部署和管理 Swarm Service
- Docker Swarm service networks (一)实战
- Docker Swarm service networks (二)深入原理
- Docker Swarm 运维篇
- Docker Swarm 外围工具篇
References
https://docs.docker.com/get-started/part4/#introduction
https://docs.docker.com/engine/swarm/
https://success.docker.com/article/Docker_Reference_Architecture-_Designing_Scalable,_Portable_Docker_Container_Networks