Docker Swarm(一)基础核心概念篇

前言

此篇博文是笔者所总结的 Docker 系列之一;

本文为作者的原创作品,转载需注明出处;本文采用是 Docker Engine 1.12;

概述

Docker Swarm 的集群管理能力和编排能力是由嵌入在 Docker Engine 的 swarmkit 实现的;

Docker Swarm 是由一系列运行在 swarm mode 模式下的 Docker hosts 组成的,Docker host 也称作 Docker node,这些 node 有两种不同的角色,

  • manager node

    1. 用来集中管理运行在 swarm 集群节点上的 services,比如修改 service 的配置,网络以及 volumes 等;
    2. 用来调度 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 中找到其对应的服务地址并建立连接请求;

整理接下来的整理思路

  1. swarm mode overview 和 swarm mode 和核心概念
  2. 实战篇
  3. 架构篇,Docker swarm mode 是如何工作的
  4. 深入创建 Swarm 和管理 Swarm 节点
  5. 深入部署和管理 Swarm Service
  6. Docker Swarm service networks (一)实战
  7. Docker Swarm service networks (二)深入原理
  8. Docker Swarm 运维篇
  9. 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