赞
踩
Docker Swarm是Docker的集群管理工具,它提供了标准的Docker API,所有任何已经与Docker守护程序通信的工具都可以使用Swarm轻松地扩展到多个主机。支持的工具包括Dokku、Docker Compose、Docker Machine和Jenkins等。
compose、machine 和 swarm 是docker 原生提供的三大编排工具,简称docker三剑客。其官网地址
- https://docs.docker.com/engine/swarm/
- 复制代码
Docker Swarm 和 Docker Compose
Docker Swarm 和 Docker Compose都是 Docker 官方容器编排项目
Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,可以将组成某个应该的多个docker容器编排在一起,同时管理。
Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口(docker stack)统一管理这些Docker主机上的各种Docker资源。
docker stack
Docker Swarm就是用来管理Docker集群的,但是现在基本上使用的很少,一般都是用的K8S,学习K8S之前可以先学习一个Docker Swarm,将其作为一个容器编排的一个学习基础,了解一下即可
Swarm集群由多个运行在swarm mode的docker主机组成,docker主机分为管理节点(manager)和工作节点(work node)两种类型
管理节点(manager):负责整个集群的管理工作包括集群配置、服务管理,服务的创建和调度等
工作节点(work node):负责运行相应的服务来执行任务(运行容器服务)
manager节点也可以运行的容器服务,但是一般不这么做,只是让它管理work node
Swarm集群的优点:
Standalone模式简单点说就是 manager 和 work 的一种管理关系模式
在Docker Swarm中有几个基本概念:nodes、Service、tasks、load balancing。需要简单了解一下
Node是加入到Swarm集群中的Docker实例,即是一个docker节点,包含上面说的【管理节点(manager)和工作节点(work node)】
管理节点(manager node)
Manager节点主要通过raft算法实现整个集群和运行的service的内部状态维护,Docker官方建议一个集群最好使用基数manager节点数(最大使用7个manager节点)保证可用性 ,Manager节点主要工作是完成以下tasks:
工作节点(work node)
Work节点是容器实际运行的实例节点,在默认情况下manager节点也是work节点,而且在在Swarm集群中必须存在manager节点
manager节点状态、信息的同步根据Raft consensus group(Raft一致性算法)的网络进行通信同步的,而worker之间的通信依靠的是Gossip network通信协议实现的。
管理节点与工作节点的切换
在多节点的Swarm集群中,节点有两种模式:【Active模式,Drain模式】。
Swarm调度不会将任务分配到Drain模式,只会在Active模式的节点上分配任务。因此可以将manager节点设置为Drain模式(避免调度任务运行在manager节点,manager指做管理)
- docker node promote
- 复制代码
通过以上命令可以修改节点模式,将worker节点变为manager节点,也可以将manager节点转换为worker节点。
Service是manage和work节点上执行的task的定义,创建service的时候可以指定使用哪个container image以及执行的命令。
当Service部署到Swarm集群的时候,swarm管理节点会将service为标准(container image以及执行的命令),然后将service调度到集群的节点上,以一个或多个tasks执行,这些nodes上运行的tasks之间是相互独立的。
如上service中有三个replicas tasks,每个实例是Swarm集群中的一个task。
Task是Swarm集群中调度的最小单元,当创建或更新service时候给定了desired state,集群会调度tasks来实现这种理想状态。
负载均衡:Swarm集群使用ingress loading balancing提供集群服务,Swarm集群会自动为service分配PublishedPort,默认使用30000-32767范围。
官方地址
- https://docs.docker.com/engine/swarm/
- 复制代码
添加私服仓库地址
由于官方镜像下载比较慢,由于网络原因可能拉取不下来,而集群的每个节点都需要安装镜像,所以使用私有仓库会快很多,当然也可以不使用私有仓库,直接自己下载上传。
- #编辑配置文件
- vi /etc/docker/daemon.json
- #增加仓库配置信息
- # 在daemon.json中添加以下 key,保存退出。此步用于让 docker 信任私有仓库地址
- {"insecure-registries":["192.168.242.130:5000"]}
-
-
- #重新加载docker配置
- systemctl daemon-reload
- #重启docker
- systemctl restart docker
- 复制代码
这里模拟安装集群,以三个节点搭建集群在加上一个Harbor节点,节点信息如下
节点 | Ip | 说明 |
---|---|---|
manager-01 | 192.168.242.131 | swarm-manager 节点 |
work-01 | 192.168.242.132 | swarm-work节点 |
work-02 | 192.168.242.133 | swarm-work节点 |
harbor | 192.168.242.130 | harbor 私服 |
安装上述配置,克隆出相应的虚拟机,其中harbor之前已经存在,这里用之前的,所以一共克隆出三个服务器
查看网络情况
- docker network ls
- 复制代码
初始化manager管理节点
语法
- docker swarm init
- 复制代码
参数说明
这个命令需要指定两个参数--advertise-addr 与--listen-addr
初始化manager管理节点完整命令如下
- #这里使用192.168.242.131这台主机作为manager 所以以下命令在192.168.242.131上执行 端口默认是2377
- docker swarm init --advertise-addr 192.168.242.131:2377 --listen-addr 192.168.242.131:2377
- 复制代码
执行上面命令后,就会初始化swarm集群,并且会告诉我们如何增加wrok 节点和manager节点
再次查看网络情况
- #集群初始化后会新增集群网络
- docker network ls
- 复制代码
查看节点
- docker node ls
- 复制代码
新加一个work节点
通过上面初始化manager返回的命令,给集群加入新的节点,只需要在对应的主机上执行该命令即可
- docker swarm join --token SWMTKN-1-55wujoaco7zp7kdvot57wu15drul4m3svoifnitz69r6jv2xyj-5o009d6f4oxlnahfwfzke5ukj 192.168.242.131:2377
- 复制代码
我在192.168.242.132这台主机上执行上述命令,将其加入到集群中
这个命令本质上就是manager初始化的时候返回了一个token,其他主机通过这个token加入集群,并且token只有24小时。如果失效,则需要重新获取
重新获取token
- #获取一个worker加入集群的token
- docker swarm join-token worker
- 复制代码
查看节点
- docker node ls
- 复制代码
新加一个manager节点
一个集群要有多个manager节点,上面加入了work节点,接下来在集群中加入一个manager节点,加入方式一样的,先获取manager的token
获取manager节点的token
- #获取一个manager加入集群的token ,这个命令要在之前的那个manager 192.168.242.131 上执行
- docker swarm join-token manager
- 复制代码
加入集群
这里就用 192.168.242.133 这个主机作为一个manager加入集群
manager与work的权限
swarm集群中,只有manager节点可以执行swarm命令(比如docker node ls),work节点会报错,因为只有manager节点才可以管理集群,执行集群相关的命令
work 节点只是不能执行swarm的集群命令,但是docker本身的命令是可以执行的,比如docker ps等
查看节点信息
可以分别在manager和node中查看节点的swarm信息,对比差异
- docker info
- 复制代码
节点可用性与状态说明
在使用docker node ls 命令查看集群的节点信息的时候,有两列需要注意一下:AVAILABILITY,MANAGER STATUS
AVAILABILITY
决定当前节点可用性,是否用于运容器,它有三个值:
改变节点的可用性(availability)
- docker node update --availability drain 节点Id/名称
- 复制代码
MANAGER STATUS
表示manger节点的状态,work节点为空,它也有三个状态值
节点权限提升/降低
节点manager和work两种,他们的权限不一样,我们可以手动的对节点权限提升/降低,也是将manager降级为work,将work升级为manager节点。升级降级的命令都要在manager节点执行。
将work升级为manager节点
- #将worker节点提升为manager节点,在manager节点执行如下命令:
- docker node promote 节点名称|节点ID
- 复制代码
比如我将132 节点升级为manager节点
将manager降级为work
- 将manager节点降低为worker节点,在manager节点执行如下命令:
- docker node demote 节点名称|节点ID
- docker node ls
- 复制代码
将刚刚升级的132 节点重新降级为worker节点
work脱离集群
前面演示了怎么给集群中加入节点,现在来看看将节点脱离集群
- #在要脱离集群的节点上使用一下命令, 主动离开集群,让节点处于down状态,才能删除
- docker swarm leave
- #指向完后,等一会在manager节点使用命令:docker node ls 就会发现该节点已经脱离集群管理
- 复制代码
这里我将132节点脱离集群
删除脱离集群的节点
上述节点脱离集群后,才能删除节点,删除节点使用如下命令
- docker node rm 节点名称|节点ID
- 复制代码
manager脱离集群
manager节点不能脱离集群,使用docker swarm leave会报错。
manager节点不能脱离集群,只能强制退出,manager退出后意味着整个swarm 不复存在。
- #manager节点强制退出
- docker swarm leave --force
- 复制代码
swarm命令汇总
命令 | 描述 |
---|---|
docker swarm init | 初始化一个 swarm 群集 |
docker swarm join | 加入群集作为节点或管理器 |
docker swarm join-token | 管理用于加入群集的令牌 |
docker swarm leave | 离开 swarm 群集 |
docker swarm unlock | 解锁 swarm 群集 |
docker swarm unlock-key | 管理解锁钥匙 |
docker swarm update | 更新 swarm 群集 |
node命令汇总
命令 | 描述 |
---|---|
docker node demote | 从 swarm 群集管理器中降级一个或多个节点 |
docker node promote | 将一个或多个节点推入到群集管理器中(也就是升级节点) |
docker node inspect | 显示一个或多个节点的详细信息 |
docker node ls | 列出 swarm 群集中的节点 |
docker node ps | 列出在一个或多个节点上运行的任务,默认为当前节点 |
docker node rm | 从 swarm 群集删除一个或多个节点 |
docker node update | 更新一个节点 |
上述安装过程是通过命令行的方式安装docker-swarm,docker-swarm也提供了一个图形界面来操作,接下来就来安装一下docker-swarm的图形界面。
docker-swarm的图形界面需要安装在manager节点上,不然无法操作节点
- #docker官网地址
- https://hub.docker.com/r/dockersamples/visualizer
- 复制代码
拉取镜像
- docker pull dockersamples/visualizer:latest
- 复制代码
备份镜像
备份镜像有两种方式:私服和tar包。
tar包
镜像拉取下来之后,可以把它打成一个tar,保存起来,后面使用的时候直接还原即可,就不用下载了
- #打成一个tar 包
- docker save dockersamples/visualizer:latest -o dockersamples.visualizer.tar
- #需要用的时候还原成镜像
- docker load -i dockersamples.visualizer.tar
- 复制代码
私服
除了打成tar 存在本地之外,还可以将镜像上传私服,以后在私服拉取
- # 1、标记镜像打一个tag
- docker tag dockersamples/visualizer:latest 192.168.242.130:5000/edwinedu/dockersamples/visualizer:latest
-
- # 2、上传标记的镜像 上传之前要先登录 docker login -u admin -p Harbor12345 192.168.242.130:5000
- docker push 192.168.242.130:5000/edwinedu/dockersamples/visualizer:latest
- 复制代码
运行镜像
- # /var/run/docker.sock 是必须要的挂载目录 HOST是指定Ip,需要是manager节点的Ip
- docker run -itd --name visualizer -p 8099:8080 -e HOST=192.168.198.131 -e PORT=8080 -v /var/run/docker.sock:/var/run/docker.sock 192.168.242.130:5000/edwinedu/dockersamples/visualizer:latest
- 复制代码
访问图形界面
- http://192.168.242.131:8099/
- 复制代码
docker-service 是指一组任务的集合,服务定义了任务的属性,比如任务的个数、服务策略、镜像的版本号等,服务有两种模式:
接下来以Nginx为例,分别在几个节点上部署Nginx任务
拉取Nginx镜像
- docker pull nginx:1.18.0-alpine
- 复制代码
备份镜像
由于要在每个节点都安装Nginx,所以需要在每个节点都下载镜像,当然可以使用私服下载,但是这里我不使用私服,练习一个scp命令
- #打成一个tar 包
- mkdir -p /data/nginx
- docker save nginx:1.18.0-alpine -o /data/nginx/nginx:1.18.0.tar
- 复制代码
传输镜像
将nginx镜像使用scp 命令传输到192.168.242.132,192.168.242.132两个节点中
- #执行下面命令之前,要确保132 133 两个节点有指定的目录 /data/nginx
- #注意nginx\:1.18.0.tar 中间有一个反斜杠
- scp /data/nginx/nginx\:1.18.0.tar root@192.168.242.132:/data/nginx
- scp /data/nginx/nginx\:1.18.0.tar root@192.168.242.133:/data/nginx
- 复制代码
解压nginx
分别在所有节点中解压nginx (192.168.242.132,192.168.242.132两个节点)
- cd /data/nginx
- docker load -i nginx:1.18.0.tar
- 复制代码
创建nginx网络
在manager节点中创建overlay网络
- docker network create -d overlay nginx-net
- 复制代码
部署Nginx
在集群中创建7个Nginx服务,在manager节点中执行,使用【docker service create】命令
- # --network nginx-net 使用刚刚创建的网络
- # replicas 7 代表 7个副本服务
- docker service create --name nginx --network nginx-net -p 80:80 --replicas 7 nginx:1.18.0-alpine
- 复制代码
界面查看
manager节点也可以查看
- docker service ls
- 复制代码
访问Nginx
- #三台主机都可以访问
- http://192.168.242.131/80
- http://192.168.242.132/80
- http://192.168.242.133/80
- 复制代码
剔除manager中非服务
前面说manager节点只用于管理集群,一般不部署服务,而在上面图形界面中显示,manager中有三个服务,如果要剔除,可以执行以下命令
- docker node update --availability drain 节点Id|名称
- 复制代码
服务的缩容与扩容
目前是在两个work中部署了7个nginx,如果要扩容与缩容,只需要修改service的数量就可以无感扩容与缩容,执行一下命令
- #将nginx服务从七个减到5
- docker service scale nginx=5
- 复制代码
在我们日常开发中,版本迭代是非常常见的,可能一周、一个月就迭代一个版本,那么版本迭代升级应该怎么做呢,接下来我们将nginx从1.18升级到1.19。
查看nginx版本
查看nginx版本可以通过容器查看,也可以通过界面查看
- #通过容器查看版本,先进入容器中
- docker exec -it 503fe639bb89 sh
- nginx -v
- #退出容器
- exit
- 复制代码
准备nginx:1.19的镜像
跟上面1.18的镜像一样,先在manager节点上拉取镜像,然后scp到132 133两台主机上,生产环境我们可以使用私服拉取镜像,不需要打包,这里只是练习scp命令
- #拉取nginx:1.19.3-alpine镜像
- docker pull nginx:1.19.3-alpine
-
- #打成一个tar 包
- mkdir -p /data/nginx
- docker save nginx:1.19.3-alpine -o /data/nginx/nginx:1.19.3.tar
-
- #执行下面命令之前,要确保132 133 两个节点有指定的目录 /data/nginx
- #注意nginx\:1.18.0.tar 中间有一个反斜杠
- scp /data/nginx/nginx\:1.19.3.tar root@192.168.242.132:/data/nginx
- scp /data/nginx/nginx\:1.19.3.tar root@192.168.242.133:/data/nginx
-
- #分别在132 133 主机上执行解压1.19.3.tar
- cd /data/nginx
- docker load -i nginx:1.19.3.tar
- 复制代码

升级Nginx
在manager节点执行以下命令,将nginx从1.18.0-alpine升级到1.19.3-alpine
- docker service update --image nginx:1.19.3-alpine nginx
- 复制代码
添加一个对外端口
- #将8090 也映射到容器的80端口
- docker service update --publish-add 8090:80 nginx
- 复制代码
删除service
- docker service rm nginx
- 复制代码
删除之前创建的nginx-net
- docker network rm nginx-net
- 复制代码
命令 | 描述 |
---|---|
docker service create | 创建服务 |
docker service inspect | 显示一个或多个服务的详细信息 |
docker service logs | 获取服务的日志 |
docker service ls | 列出服务 |
docker service rm | 删除一个或多个服务 |
docker service scale | 设置服务的实例数量 |
docker service update | 更新服务 |
docker service rollback | 恢复服务至update之前的配置 |
Stack是一组Service,和docker-compose类似,它也可以通过yml的将一组service放在一起操作,docker stack命令可以方便地操作一个Stack,而不用一个个地操作Service。
默认情况下,一个Stack共用一个Network,相互可访问,与其它Stack网络隔绝
下面还是以上面的nginx集群为例,通过docker stack 来构建集群
编写docker-stack.yml文件
docker stack 文件的语法基本与docker-compose类似,
- #版本写高一点,不支持 1 2
- version: '3'
- services:
- edwin-nginx:
- image: nginx:1.19.3-alpine
- container_name: edwin-nginx
- # 指定一个网络
- networks:
- - edwin-net
- restart: always
- ports:
- - 80:80
- deploy:
- replicas: 7
- # 创建nginx网络 networks中也可以不指定driver:overlay,因为docker swarm默认网络类型是overlay。
- networks:
- edwin-net:
- driver: overlay
- 复制代码

上传docker-stack.yml
- 将docker-stack.yml上传到manager节点的/data/nginx目录下
- 复制代码
启动镜像
在manager节点中创建docker-stack.yml文件。执行如下命令:
- #nginx-stack 是stack的名字
- docker stack deploy nginx-stack --compose-file=docker-stack.yml
- #或者是
- docker stack deploy nginx-stack -c docker-stack.yml
- 复制代码
查看stack服务
- docker stack services nginx-stack
- 复制代码
查看运行的节点
查看7个nginx-stack容器分别运行在哪个节点中,可以通过以下命令
- # 查看service的服务名为:nginx-stack_edwin-nginx
- docker service ls
- #查看7个nginx-stack容器分别运行在哪个节点中
- docker service ps nginx-stack_edwin-nginx
- 复制代码
查看的前提是我们要修改各个主机的名字,不然都会显示localhost.localdomain
修改主机名字
- # 第一步 在各个主机执行 docker-swarm-work-02 为当前主机要设置的主机名
- hostnamectl set-hostname docker-swarm-manager-01
- #第二步
- vi /etc/hosts
- # 将其中的 localhost.localdomain 替换成 docker-swarm-work-02
- 127.0.0.1 localhost docker-swarm-work-02 localhost4 localhost4.localdomain4
- ::1 localhost docker-swarm-work-02 localhost6 localhost6.localdomain6
- #第三步 重启服务器
- reboot
- #第四步 查看hostname
- hostname
- 复制代码
分别按照上述步骤修改主机名字后,再次查看查看7个nginx-stack容器分别运行在哪个节点中,结果如下
删除stack服务
- docker stack rm nginx-stack
- 复制代码
命令 | 描述 |
---|---|
docker stack deploy | 部署新的stack或更新现有stack |
docker stack ls | 列出现有stack |
docker stack ps | 列出stack中的任务 |
docker stack rm | 删除一个或多个stack |
docker stack services | 列出stack中的服务 |
Task是 Swarm 集群中的最小的调度单位,任务包含一个Docker容器和在容器内运行的命令,如果某一个任务奔溃,那么协调器将创建一个新的副本任务,该任务将生成一个新的容器。
Task调度主要分为Manager节点的任务分配和Worker节点的任务执行两部分
Task 的执行是一种单向机制,它会按顺序的依次经历 assigned, prepared 和 running 等执行状态,如果Task执行失败了,Manager的编排器会直接将该 Task 以及它的 Container 给删除掉,然后在其它节点上另外创建并执行该 Task
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。