一、什么是docker swarm
Docker Swarm 和 Docker Compose 一样,都是 Docker 官方容器编排项目,但不同的是, Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,而 Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,对于微服务的部署,显然 Docker Swarm 会更加适合。
docker deamon:
Swarm deamon只是一个调度器(Scheduler)加路由器(router),Swarm自己不运行容器,它只是接受Docker客户端发来的请求,调度适合的节点来运行容器,这就意味着,即使Swarm由于某些原因挂掉了,集群中的节点也会照常运行,放Swarm重新恢复运行之后,他会收集重建集群信息。
二、Docker Swarm 基本结构
Swarm是典型的master-slave结构,通过发现服务来选举manager。manager是中心管理节点,各个node上运行agent接受manager的统一管理,集群会自动通过Raft协议分布式选举出manager节点,无需额外的发现服务支持,避免了单点的瓶颈问题,同时也内置了DNS的负载均衡和对外部负载均衡机制的集成支持
三、Swarm的几个关键概念
1.Swarm
集群的管理和编排是使用嵌入docker引擎的SwarmKit,可以在docker初始化时启动swarm模式或者加入已存在的swarm
2.Node
一个节点是docker引擎集群的一个实例,可以将其视为Docker节点。
您可以在单个物理计算机或云服务器上运行一个或多个节点,但生产群集部署通常包括分布在多个物理和云计算机上的Docker节点。
要将应用程序部署到swarm,请将服务定义提交给管理器节点。
管理器节点将称为任务的工作单元分派给工作节点。
Manager节点还执行维护所需群集状态所需的编排和集群管理功能。Manager节点选择单个领导者来执行编排任务。
工作节点接收并执行从管理器节点分派的任务。
默认情况下,管理器节点还将服务作为工作节点运行,但您可以将它们配置为仅运行管理器任务并且是仅管理器节点。代理程序在每个工作程序节点上运行,并报告分配给它的任务。工作节点向管理器节点通知其分配的任务的当前状态,以便管理器可以维持每个工作者的期望状态。
3.Service
一个服务是任务的定义,在管理机或工作节点上执行。它是群体系统的中心结构,是用户与群体交互的主要根源。创建服务时,你需要指定要使用的容器镜像。
4.Task
任务是在docekr容器中执行的命令,Manager节点根据指定数量的任务副本分配任务给worker节点
四、swarm的调度策略
Swarm在调度(scheduler)节点(leader节点)运行容器的时候,会根据指定的策略来计算最适合运行容器的节点,目前支持的策略有:spread, binpack, random.
1、Random
顾名思义,就是随机选择一个Node来运行容器,一般用作调试用,spread和binpack策略会根据各个节点的可用的CPU, RAM以及正在运
行的容器的数量来计算应该运行容器的节点。
2、Spread
在同等条件下,Spread策略会选择运行容器最少的那台节点来运行新的容器,binpack策略会选择运行容器最集中的那台机器来运行新的节点。
使用Spread策略会使得容器会均衡的分布在集群中的各个节点上运行,一旦一个节点挂掉了只会损失少部分的容器。
3、Binpack
Binpack策略最大化的避免容器碎片化,就是说binpack策略尽可能的把还未使用的节点留给需要更大空间的容器运行,尽可能的把容器运行在一个节点上面。
五、Swarm Cluster模式特性
1)批量创建服务
建立容器之前先创建一个overlay的网络,用来保证在不同主机上的容器网络互通的网络模式
2)强大的集群的容错性
当容器副本中的其中某一个或某几个节点宕机后,cluster会根据自己的服务注册发现机制,以及之前设定的值--replicas n,在集群中剩余的空闲节点上,重新拉起容器副本。整个副本迁移的过程无需人工干预,迁移后原本的集群的load balance依旧好使!不难看出,docker service其实不仅仅是批量启动服务这么简单,而是在集群中定义了一种状态。Cluster会持续检测服务的健康状态并维护集群的高可用性。
3)服务节点的可扩展性
Swarm Cluster不光只是提供了优秀的高可用性,同时也提供了节点弹性扩展或缩减的功能。当容器组想动态扩展时,只需通过scale参数即可复制出新的副本出来。
仔细观察的话,可以发现所有扩展出来的容器副本都run在原先的节点下面,如果有需求想在每台节点上都run一个相同的副本,方法其实很简单,只需要在命令中将"--replicas n"更换成"--mode=global"即可!
复制服务(--replicas n)随机发放副本
将一系列复制任务分发至各节点当中,具体取决于您所需要的设置状态,例如“--replicas 3”。
全局服务(--mode=global)表示在全部的容器内创建这个副本
适用于集群内全部可用节点上的服务任务,例如“--mode global”。如果大家在 Swarm 集群中设有 7 台 Docker 节点,则全部节点之上都将存在对应容器。
第六、搭建docker swarm群集
1、定义群集
init 初始化
--advertise-addr 指定ip地址创建
2、创建好后会自动生成加入节点的命令,如图所示 复制下来粘贴到需要加入的docker节点内
3、 我们在manager节点下查看是否加入成功
这里搭建docker swarm就搭建完成了
第七、docker swarm 命令和实现
docker swarm群集管理命令关键字:
docker node节点关键命令:
docker node节点关键命令:
命令实现:
显示 Docker 系统信息,包括镜像和容器数
info内容详情:
查看swarm群集节点:
如果想对某一台节点进行一个暂停维护: #下线节点
上线节点:
docker swarm删除节点:
docker swarm删除后从新添加新节点: #获取加入信息
在从新添加节点出现一下错误
如果出现这种情况: #表示这台docker容器已经加入过群集了 无法添加,这里需要手动删除
Error response from daemon: This node is already part of a swarm. Use "docker swarm leave" to leave this swarm and join another one.
解决办法: #这里的leave就是在集群中删除节点,-f参数强制删除
从新加入:
我们这里再看一下节点是否加入:
举例
通过例子我们更好的来熟悉docker swarm的群集命令
利用docker swarm搭建nginx 群集
1、首先创建一个跨主机的网络 用docker自带的overlay网络即可
# -d 驱动程序来管理网络 #网络名字nginx_net
创建完成后查看:
2、发布一个服务 为了提升效率 提前将镜像导入到群集机器内,导入后创建三个副本
server create 创建服务 --replicas 副本数 --network 使用网络的名字 --name 创建完成后服务的名称
查看:
查看详情:
inspect 查看详情
--pretty 使命令输出格式化为可读的格式 #不加这条会看到更加详细的内容
这里显示的是一些服务的详细信息,如果想看服务在那台机器上运行用:
3、做完我们尝试访问一下
-i 显示请求头部信
这里访问都是 轮巡访问状态 3个副本轮流访问
docker swarm 扩容副本收缩副本数量
最后的数值是副本数量,可大可小
##这里注意如果有任何一台node节点宕机,副本数不会遍,跑在宕机节点的容器会自动跑在其他节点上。这里我们做个演示,我已经副本收缩到3个了
模拟宕机 docker03
看节点:
查看服务:可以看打 docker03 上的nginx.3 跑到docker01上面了
从新启动一下docker03 自动就加入到
注意这里想要服务跑到原来的机器上 需要在对应的docker主机上停止并删除容器
这里我就强制删除容器了:
到docker01上面看一下容器id号
删除容器:
查看是否恢复到以前的docker03上面:
下面的/_开头的是历史记录不用管
升级镜像: #如果镜像版本太低可以升级镜像 ,因为我用的最新的nginx镜像,我就降级了
命令: 我将版本从latest降级到1.18 版本了 升级的话 nginx:new 或者 nginx:+版本号或者latest ,没有镜像会自动下载
这样做会将原来的容器停止掉,产生新的容器并且运行
docker swarm使用volume数据卷
1、为了更直观 我这里将服务全部删除从新运行一下
2、创建数据卷,我们创建具名数据卷
查看全部数据卷:
查看具体数据卷位置
数据间位置就在画出的地方
3、创建并挂载数据卷
我们将nginx默认主页目录挂在出来 方便我们更改目录
type文件类型
src需要挂在的目录或者数据卷名字
dst挂载容器内容的目录位置
我们进到目录下 看看是否有主页默认的index文件了
当然 在别的环境 尽量挂载到数据文件 ,因为我这里挂载的是主页目录文件所以我修改index.html文件的话只有一台能主页能变 其余两台不变
假如我在docker01上面改主页文件,那么只有docker01的主页才会更改
说白了就是 每个docker主机的数据卷目录都是独立的,修改一个不能通用
第二种挂载方式:
type文件类型 参数target表示容器里面的路径,source表示本地硬盘路径