Docker Swarm

发布于 2021-09-25  3.3k 次阅读


一,Docker Swarm概述

一,Docker Swarm的简介

Dcoker Swarm是由Docker官方推出的容器集群管理工具(Docker Compose为服务编排工具),基于Go语言实现,使用它可以将多个Docker主机封装为单大型虚拟Docker主机,实现Docker的分布式集群部署,快速打造一套容器云平台

Docker Swarm是生产环境中运行Docker分布式应用程序最简单的方法,作为容器集群管理器,Swarm最大的优势就是100%支持标准的Docker API,其他基于标准API的工具如Compose。docker-py,各种管理软件,甚至Docker本身都可以很容易的与Swarm进行集成,大大方便了用户将原先基于单节点的系统移植到Swarm。同时Swarm内置了对Docker网络插件的支持,用户可以很容易的部署跨主机的容器集群服务

Docker Swarm和Docker Compose本质上是一样的,都是Docker官方的容器编排工具,但不同的是Docker Compose是再单个服务器或主机上创建多个容器的工具,而Docker Swarm则可以再多个不同服务器或主机上创建容器集群服务,对于微服务的部署,Docker Swarm是非常适合的

注:假如容器集群非常多,对容器要求非常高,高并发高性能,容器的实时管理监控,Docker Swarm是无法满足的,它只适合普通的分布式集群,如果对上述要求非常苛刻就需要上K8S

二,Docker Swarm的核心概念

Docker1.12引入了Swarm模式,一个Swarm由多个Docker主机组成,它们以Swarm集群模式运行,Swarm集群由Manager节点和Worker节点组成,有些主机可以同时扮演两种角色

Swarm创建服务时,需要指定要使用的镜像,在运行的容器中执行命令,定义其副本的数量,可以的网络和数据卷,将服务映射到外部端口

与独立容器相比,集群容器的注意优势是,你可以修改服务的配置,包括它所连接的网络和数据卷等,而不需要手动重启服务,

一,Manager节点和Worker节点

Swarm集群由Manager节点和Worker节点组成,一个节点就是Swarm集群中的一个实例,也就是一个主机,可以运行一个或多个节点在单台物理服务器上,但是生产环境中,典型的部署方式是:Docker节点交叉分布式部署在多台服务器,节点名称默认为机器的hostname

  • Manager:负责整个集群的管理工作包括集群配置,服务管理,容器编排等所有跟集群有关的工作,它会选举出一个leader来指挥编排任务
  • Worker:工作节点接收和执行从Manager分配的任务Tasks运行在相应的服务service上

二,集群的容错机制

一,Manager容错

如果在单个Manager集群中Manager出现故障,则服务也将继续运行,但需要创建一个新的集群才能恢复

为了利用集群模式的容错性功能,Docker根据集群的高可用性需求实现奇数个节点,当有多个manager节点时,可以从一个manager节点的故障中恢复,而不要停机

  • 三个manager的集群可以保证其中一个manager节点的最大数据损失
  • 五个manager的集群可以保证其中两个manager节点的最大损失
  • manager集群容忍最大manager损失比例为(N-1/2)
  • Docker swarm集群最大提供7个manager节点

注:超过一半的manager故障,集群就完全瘫痪

二,Worker容错

worker节点本质是docker容器的实例,它唯一的目的就是执行容器,它不参与调度决策也不服务于swarm集群HTTP API

worker节点的任务都由manager分配,当单个worker节点宕机时,manager会将任务分配给其他worker节点,并不影响服务,当它故障恢复了,就能重新接收分配

三,Docker Swarm的服务,任务,容器

一,服务的工作原理

service服务在Docker中是一个较为抽象的概念,要在Docker引擎处于集群模式时部署应用程序镜像,必须创建service服务,通常服务是在较大型应用的上下文中为微服务提供镜像,服务实例可以包括HTTP服务,数据库,或者希望在分布式环境中运行的任何其他类型的可执行程序

创建service服务时,需要指定使用的容器镜像以及运行在容器内执行那些命令(和传统的docker指令一样)

Swarm创建服务可以定义其他服务选项:

  • 服务名称
  • 使用那个镜像创建容器
  • 要运行多少个副本
  • 服务容器连接到那个网络
  • 容器端口要映射那些外部端口
  • ……

二,服务,任务,容器

当将服务部署到集群中时,manager接收服务指令,然后再将服务划分为一项任务或复制成多个任务,再分配给Worker节点独立执行

任务的概念:包括一个Docker容器和再容器中运行的命令,任务是一个集群的最小单元,任务与容器是一对一的关系,manager节点根据服务规模中设置的副本数量将任务分配到worker节点

注:一旦任务被分配到一个节点,便无法移动到另一个节点,它只能分配的worker节点上运行或者失败

三,副本服务和全局服务

Docker Swarm不止提供了优秀的高可用,同时也提供了节点的弹性扩容和缩容的功能,可以通过以下两种类型的Service部署实现:

  • 副本服务(Replicated Service):当服务需要动态扩容缩容时,只需通过scale参数或者--replicas n参数指定运行相同任务的数量,即可复制出新的副本,将一系列复制任务分发至各个节点
  • 全局服务(Global Services):通过--mode global参数将服务分发至全部节点上,每一个节点运行一个相同的任务,不需要预先指定任务的数量,每增加一个节点到Swarm中,协调器就会建一个任务,然后调度器把任务分配到新节点

下图显示了黄色三服务副本和灰色全球服务:

 

四,Overlay网络(覆盖网络)

一,Overlay网络的概述

在Docker中有四种主要网络:Host网络,Container网络,Bridge网络(默认),None网络

在Docker Swarm集群模式下默认使用的是Overlay网络(覆盖网络)

Overlay网络其实并不是一门新技术,它是构建在另一个网络上的计算机网络,它本质是一种网络虚拟技术的形式,近年来随着云计算虚拟化技术的演进促进了网络虚拟化技术的应用,Overlay网络就是在物理主机网络虚拟出的网络,它依赖于物理主机网络,并不能独立出现

注:Overlay底层依赖的网络是Underlay网络

Overlay网络出现的目的:解决容器跨节点数据传输和路由问题

Underlay网络是专门用来承载用户IP流量的基础架构层,它与Overlay网络之间的关系有点类似于物理机和虚拟机,Underlay网络和物理机一样都是存在的实体,它们分别对应着真实存在的网络设备和计算设备,而Overlay网络和虚拟机都是依托在下层实体基础

在Docker1.12版本以后Swarm模式原生已支持Overlay网络,只要在这个Overlay网络内的容器,不管在不在同一个宿主机都能相互通信,即跨主机通信,但不同Overlay网络内的容器之间是相互隔离的,无法通信

二,Overlay网络的操作

网络的操作和docker原生操作是一样的

1,创建Overlay网络:

docker network create -d overlay 网络名称

2,删除Overlay网络:

docker network rm 网络名称

3, 创建一个覆盖网络,可用于集群服务或独立容器与其他在 Docker daemons 上运行的其他独立容器进行通信,则添加标志:--attachable

docker network create -d overlay --attachable my-attachable-overlay

……

二,Docker Swarm集群的操作

一,创建一个Swarm集群并加入节点

一,创建集群

命令:docker swarm init

参数:

1,--advertise-addr:为Swarm集群的Overlay网络指定一个IP地址,所以节点主机都使用这个IP进行通信

#为swarm的Overlay网络分配一个192.168.9.1的IP
docker swarm init --advertise-addr 192.168.9.1

2,--default-addr-pool:自定义默认的IP地址池

默认情况下,Docker Swarm 将默认地址池用于全球范围(覆盖)网,每个没有指定子网的网络都将按顺序从该池中分配子网。在某些情况下,最好为网络使用不同的默认 IP 地址池:10.0.0.0/8

如果默认范围与网络中已分配的地址空间相冲突,则最好确保网络使用不同的范围

docker swarm init --default-addr-pool 10.10.0.0/16

在任意节点下通过docker swarm init命令创建一个新的swarm集群时,运行该命令的主机会自动加入改集群,并为Manager节点

通常,第一个加入集群的manager节点将为Leader,后面加入的manager节点都为Reachable,当前的Leader如果挂掉,所有的Reachable将重新选举出一个Leader

注:在多台Manager节点中,内部还会有一次选举,选出一个Leader和多个Reachable

二,集群连接令牌

Docker中内置的集群模式自带了公钥基础系统(PKI),这使容器的安全部署变得较为简单,集群中的节点使用传输层安全协议(TLS)对集群中其他节点的通信进行身份认证,授权,加密

默认在docker Swarm init创建集群时,Manager节点会自动生成token令牌(跟证书(CA)和密钥对),这个token在全球范围内都是唯一的,它作为集群的唯一标识,节点想要加入集群都必须填写tonken,用于保护与加入集群的其他节点之间的安全通信

Manager节点一次会生成两个令牌,供其他节点加入集群时使用:一个Worker令牌, 一个Manager令牌,每个令牌都包括根CA证,书的摘要和随机生成的密钥。当节点加入群集时,加入的节点便用摘要来验证来自远程管理节点的根CA证书。远程管理节点使用密钥来确保加入的节点是批准的节点

三,集群节点加入

首次创建群时,单个 Docker 引擎置于集群模式,要充分利用集群模式,可以向集群添加节点:

  • 添加Worker节点会增加容量,当您将服务部署到集群中时,Swarm会在可用节点上安排任务,无论它们是Worker节点还是Manager节点,当您将Worker添加到您的集群中时,您将增加集群的规模,以处理任务,而不会影响Manager
  • Manager节点可增加故障耐受性,Manager节点为集群执行编排和集群管理功能,在Manager节点中,单个Leader节点执行编排任务,如果一个Leader节点下降,剩余的Reachable节点将选出一位新领导者,并恢复对集群状态的编排和维护,默认情况下,Manager节点也会运行任务

命令:docker swarm join 集群IP:2377

选项:

  • --token:指定集群的令牌(必填)
#例:2733是一个docker Swarm集群节点使用固定端口,加入时都用此端口
docker swarm join --token SWMTKN-1-2lefzq18zohy9yr1vskutf1sfb2a590xz9d0mjj2m15zu9eprw-2938j5f50t35ycut0vbj2sx0s 192.168.31.43:2377

注:Manager节点和Worker节点的添加,使用命令是一样的,要想加入为Manager节点和Worker节点,就指定两角色不同的令牌

节点加入内部的执行流程:

  • 将当前节点上的 Docker Swarm切换到集群模式
  • 向Manager索取 TLS 证书
  • 用机器主机名称命名节点
  • 根据集群令牌将当前节点连接到Manager收听地址的集群
  • 将当前节点设置为可用性,这意味着它可以从调度器接收任务
  • 将覆盖网络扩展到当前节点

二,集群节点的管理

一,查看节点列表

命令:docker node ls

[root@manager ~]# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
3jcmnzjh0e99ipgshk1ykqwsd *   manager             Ready               Active              Leader              18.06.0-ce
dasque2xprzdw6wdx7afoqw04     worker1             Ready               Drain                                   18.06.1-ce
cfdqw5ns4adcvumzgiv66xpyj     worker2             Ready               Active                                  18.06.1-ce

信息说明:

1,ID:节点的唯一标识

2,HOSTNAME:节点的主机名

3,STATUS:节点状态,Ready为准备状态

4,AVAILADILITY:集群节点的AVAILADILITY状态,它可以指定三种状态

  • Active:node可以接收manager分配的任务,并正常执行已有任务
  • Pause:node不再接收manager分配的任务,但继续执行已有任务
  • Drain:node不接收manage分配的任务且结束已有任务

5,MANAGER STATUS:因为在manager中还会进行二次选举,会重新产生两个角色

  • Leader: 意味着改manager节点节点是主要的管理器节点,它为集群做出所有管理和编排决策
  • Reachable: 表示节点是参与 Raft 人数的节点,如果Leader节点不可用,该节点节点将有资格当选为新的Leader

6,ENGINE VERSION:Docker引擎的版本号

注:节点标识可以为主机名也可以是节点的ID

二,查看单节点的详细信息

可以在manager节点上查看单个节点的信息,默认输出为json格式

命令:docker node inspect 节点标识  

  • --pretty:加入此选项,信息将平铺格式输出

三,设置节点的可用性状态

Swarm可用性状态(availability):

  • active:正常状态
  • drain:暂停状态,不接收分配任务也不执行本地已有任务
  • pause:不接受分配任务,但执行本地已有任务

命令:docker node update --availability 可用性状态 节点标识

四,节点的升级和降级

节点升级:从worker节点升级为manager节点

命令:docker node promote  节点标识

节点降级:从manager节点降级为worker节点

命令:docker node demote  节点标识

五,节点退出集群和节点删除

退出集群:在当前推出主机上运行 docker swarm leave就可退出集群(-f强制)

当前节点离开群时,swarm停止在群模式下运行,集群编排器不再将任务安排到改节点

删除节点:需先推出集群才进行删除要么就-f强制删除

命令:docker node rm 节点标识

三,集群服务的管理

一,创建服务

命令:docker service create 服务镜像

参数选项:

  • --name:指定服务容器的名称
  • -p(--publish):暴露端口
  • -v:创建数据卷共享
  • --network:为服务添加网络
  • --replicas:服务副本数
  • --update-delay:容器与容器之间更新的时间间隔
  • --update-parallelism:更新时并行的更新数量
  • --update-failure-action:任务容器更新失败时的模式(默认为pause,"pause 停止 | continue继续")
  • --rollback-monitor:容器和容器之间回滚的时间间隔

二,查看服务

1,查看所有服务:docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
cwql_nginx           replicated          1/1                 nginx:latest        *:80->80/tcp

说明:

  • ID:服务(容器)ID唯一标识
  • NAME:服务(容器)的名称
  • MODE:服务的模式,服务有两种模式:replicated为副本模式,global为全局模式
  • REPLICAS:副本数量
  • IMAGE:创建容器服务的镜像名
  • PORTS:端口的映射

2,查看服务详细信息:docker service inspect --pretty 服务标识

ID:             dfsxfmda4dqwasdqwda       #服务ID
Name:           wql_nginx #服务名称
Service Mode:   Replicated #服务的模式
Replicas:      1 #副本数
Placement:
UpdateConfig:
Parallelism:   1
On failure:    pause
Monitoring Period: 5s
Max failure ratio: 0
Update order:      stop-first
RollbackConfig:
Parallelism:   1
On failure:    pause
Monitoring Period: 5s
Max failure ratio: 0
Rollback order:    stop-first
ContainerSpec:
Image:         nginx:latest@sha256:b73f527d86e3461fd652f62cf47e7b375196063bbbd503e853af5be16597cb2e
Init:          false
Resources:
Networks: nginx_net #使用的网络
Endpoint Mode:  vip
Ports:
PublishedPort = 80 #端口映射
  Protocol = tcp
  TargetPort = 80
  PublishMode = ingress

3,查询服务的状态信息

  1. 查看使用服务的状态信息:docker service ps -a
  2. 查询当个服务的状态信息:docker service ps 服务标识
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE               ERROR               PORTS
yzonph0zu7km        my_nginx.1          nginx:latest        manager43           Running             Running about an hour ago                      
mlprstt9ds5x        my_nginx.2          nginx:latest        node139             Running             Running 52 seconds ago                         
y09lk90tdzdp        my_nginx.3          nginx:latest        node139             Running             Running 52 seconds ago                         
clolfl3zlvj0        my_nginx.4          nginx:latest        node188             Running             Running 2 minutes ago

说明:

  • ID:服务(容器)ID
  • NAME:服务(容器)名称
  • IMAGE:镜像
  • NODE:运行该服务的机器
  • DESIRED STATUS:状态(Running为运行 | Preparing为准备)
  • CURRENT STATE:现行状态,隔一段时间进行更新

三,服务的更新和删除

一,动态缩容扩容服务

命令:docker service scala 服务标识=副本数

这条命令在运行的集群中也可以动态的增加或者减少服务

二,更新服务

命令:docker service update 服务名

参数选项:

  • --image:通过镜像更新服务版本
  • --rollback:回滚服务版本
  • --args:容器加入指令
  • --network-add:容器添加新的网络
  • --network-rm:删除容器网络
  • --publish-add:添加端口映射
  • --publish-rm:删除端口映射
  •  --config-add 配置文件名称,target=/../容器内配置文件名 :添加新的配置文件到容器
  •  --config-rm 配置文件名称 :删除容器服务内的配置文件

三,删除服务

命令:docker service rm 服务名称

  • -f:强制删除

三,docker Swarm小案例

一,环境准备

Swarm和Compose不一样它不需要手动安装,在安装docker时就自带了Swarm

1,准备好三台虚拟机(我是Centos 7.6)

2,分别安装docker(我是docker 20.10.8)

注:版本要在docker1.12以上

3,关闭防火墙

注:因为只是测试所以直接关闭防火墙,生产环境中根据端口放行即可

角色 IP 主机名 docker版本
Manager 192.168.68.151 manager 20.10.8
Worker 192.168.68.153 worker1 20.10.8
Worker 192.168.68.133 worker2 20.10.8

修改主机名的方式:

  • hostname 主机名(立即生效,重启失效)
  • hostnamectl set-hostname 主机名(立即生效,重启也生效)
  • vi /etc/hosts,添加127.0.0.1 主机名(持久生效)

二,集群操作

1,在192.168.68.151机器上创建集群:

[root@manager ~]# docker swarm init
Swarm initialized: current node (sm56viuz67sj4ag8qaihug60l) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-49lqduquny7gpg94clntjywn2i6312z2dan0gtukt6138nh9l2-83vwjl1qidnra9m1tmjnpszro 192.168.68.151:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

2,将其他两台机器加入集群

#192.168.68.153机器运行
docker swarm join --token SWMTKN-1-49lqduquny7gpg94clntjywn2i6312z2dan0gtukt6138nh9l2-83vwjl1qidnra9m1tmjnpszro 192.168.68.151:2377
#192.168.68.133机器运行
docker swarm join --token SWMTKN-1-49lqduquny7gpg94clntjywn2i6312z2dan0gtukt6138nh9l2-83vwjl1qidnra9m1tmjnpszro 192.168.68.151:2377

3,查看集群节点

[root@manager ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
sm56viuz67sj4ag8qaihug60l *   manager    Ready     Active         Leader           20.10.8
n5e8fvd0bk92tdv64tqirionu     worker1    Ready     Active                          20.10.8
onhr5vnvdq9qd5dqtrpvk1yt4     worker2    Ready     Active                          20.10.8

4,创建一个类型为overlay的网络

[root@manager ~]# docker network create -d overlay wql
ptlvuvajayaxnjipvb8x1z5k5

5,运行tomcat服务

#服务副本为3,网络为wql,名称为tomcat
[root@manager ~]# docker service create --name tom_fq --network wql --replicas 3 tomcat
toqrin5ffdsy2ofa9s48ibhs6
overall progress: 3 out of 3 tasks
1/3: running   [==================================================>]
2/3: running   [==================================================>]
3/3: running   [==================================================>]
verify: Service converged

6,查看服务的状态

[root@manager ~]# docker service ps tom_fq
ID             NAME       IMAGE           NODE      DESIRED STATE   CURRENT STATE                ERROR     PORTS
pffir25azf4o   tom_fq.1   tomcat:latest   manager   Running         Running 2 minutes ago                  
mr4p4qfgg2t3   tom_fq.2   tomcat:latest   worker1   Running         Running 2 minutes ago                  
ygebt4mqn9gt   tom_fq.3   tomcat:latest   worker2   Running         Running about a minute ago

7,更新服务添加8080端口映射

[root@manager ~]# docker service update --publish-add 8080:8080 tom_fq
tom_fq
overall progress: 3 out of 3 tasks
1/3: running   [==================================================>]
2/3: running   [==================================================>]
3/3: running   [==================================================>]
verify: Service converged

路漫漫其修远兮,吾将上下而求索