Swarm介绍
Swarm是Docker公司自己发布的一套用来管理Docker集群的平台,几乎全部用GO语言来完成的开发,可以在多台机器上对容器进行管理和编排。(Cluster : 集群)
Docker Swarm 和 Docker Compose 一样,都是Docker官方容器编排项目,但不同的是,Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,而 Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,对于微服务的部署,显然 Docker Swarm 会更加适合。
Swarm的几个关键概念
Swarm
集群的管理和编排是使用嵌入docker引擎的SwarmKit,可以在docker初始化时启动swarm模式或者加入已存在的swarm。
docker swarm:集群管理,子命令有init, join, leave, update
Node
node是加入到swarm集群中的一个docker引擎实体,可以在一台物理机上运行多个node。
manager节点还执行维护所需群集状态所需的编排和集群管理功能,manager节点选择单个领导者来执行编排任务,worker节点接收并执行从管理器节点分派的任务。
docker node:节点管理,子命令有accept, promote, demote, inspect, update, tasks, ls, rm
Service
一个服务是任务的定义,管理机或工作节点上执行。它是群体系统的中心结构,是用户与群体交互的主要根源。
创建服务时,你需要指定要使用的容器镜像。
docker service:服务创建,子命令有create, inspect, update, remove, tasks
Task
任务是在docker容器中执行的命令,manager节点根据指定数量的任务副本分配任务给worker节点。
Swarm的调度策略
Swarm在调度节点(leader节点)运行容器的时候,会根据指定的策略来计算最适合运行容器的节点。
目前支持的策略有:random,spread,binpack
Random
顾名思义,就是随机选择一个Node来运行容器,一般用作调试用,spread和binpack策略会根据各个节点的可用的CPU, RAM以及正在运行的容器的数量来计算应该运行容器的节点。
Spread
在同等条件下,Spread策略会选择运行容器最少的那台节点来运行新的容器,binpack策略会选择运行容器最集中的那台机器来运行新的节点。
使用Spread策略会使得容器会均衡的分布在集群中的各个节点上运行,一旦一个节点挂掉了只会损失少部分的容器。
Binpack
Binpack策略最大化的避免容器碎片化,就是说binpack策略尽可能的把还未使用的节点留给需要更大空间的容器运行,尽可能的把容器运行在一个节点上面。
Swarm Cluster模式的特点
批量创建服务
建立容器之前先创建一个overlay的网络,用来保证在不同主机上的容器网络互通的网络模式。
强大的集群的容错性
当容器副本中的其中某一个或某几个节点宕机后,cluster会根据自己的服务注册发现机制,以及之前设定的值 –replicas n,在集群中剩余的空闲节点上,重新拉起容器副本。
docker service其实不仅仅是批量启动服务这么简单,而是在集群中定义了一种状态。Cluster会持续检测服务的健康状态并维护集群的高可用性。
服务节点的可扩展性
Swarm Cluster不光只是提供了优秀的高可用性,同时也提供了节点弹性扩展或缩减的功能。当容器组想动态扩展时,只需通过scale参数即可复制出新的副本出来。
调度机制
所谓的调度其主要功能是cluster的server端去选择在哪个服务器节点上创建并启动一个容器实例的动作。
Swarm集群部署
机器环境
| IP | 主机名 | 担任角色 |
| 192.168.58.151 | manager | swarm manager |
| 192.168.58.152 | worker1 | swarm worker |
| 192.168.58.153 | worker2 | swarm worker |
准备工作
1、修改主机名
hostnamectl set-hostname managerhostnamectl set-hostname worker1hostnamectl set-hostname worker2
2、配置hosts文件
[root@manager ~]# vim /etc/hosts# 在文件末尾添加以下三行192.168.58.151 manager192.168.58.152 worker1192.168.58.153 worker2 # 使用scp复制到所有机器[root@manager ~]# scp /etc/hosts root@192.168.58.152:/etc/hosts[root@manager ~]# scp /etc/hosts root@192.168.58.153:/etc/hosts
3、关闭防火墙
# 关闭三台机器上的防火墙systemctl stop firewalldsystemctl disable firewalld
4、安装docker
1.卸载旧的版本yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine 2.需要的安装包yum install yum-utils -y 3.设置镜像的仓库yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo # 默认是国外的 yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 建议安装国内的 4.安装docker ——Install Docker Engine# docker-ce 社区版 docker-ee 企业版yum install docker-ce docker-ce-cli containerd.io -y 5.启动dockersystemctl start docker 6.设置docker开机自启systemctl enable docker 7.使用 docker version 或 docker -v 测试是否安装成功
创建Swarm并添加节点
1、创建swarm集群
# manager节点执行以下命令[root@manager ~]# docker swarm init --advertise-addr 192.168.58.151Swarm initialized: current node (pzvvc7ko4xflq024mnoo1tjmf) is now a manager.To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-0rta6xdpbwcya1l2jhq4xf32bygqv1dau9z6kctl0e93y5mwe2-6jprqypdft8rhp9jv9xjbzghl 192.168.58.151:2377To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
2、查看集群的相关信息
# 查看集群中目前已存在的机器[root@manager ~]# docker node lsID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSIONpzvvc7ko4xflq024mnoo1tjmf * manager Ready Active Leader 20.10.9
3、 添加节点主机到Swarm集群
# 上面我们在创建Swarm集群的时候就已经给出了添加节点的方法[root@worker1 ~]# docker swarm join --token SWMTKN-1-0rta6xdpbwcya1l2jhq4xf32bygqv1dau9z6kctl0e93y5mwe2-6jprqypdft8rhp9jv9xjbzghl 192.168.58.151:2377This node joined a swarm as a worker. [root@worker2 ~]# docker swarm join --token SWMTKN-1-0rta6xdpbwcya1l2jhq4xf32bygqv1dau9z6kctl0e93y5mwe2-6jprqypdft8rhp9jv9xjbzghl 192.168.58.151:2377This node joined a swarm as a worker.
# 再次在manager节点上查看集群相关信息[root@manager ~]# docker node lsID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSIONpzvvc7ko4xflq024mnoo1tjmf * manager Ready Active Leader 20.10.9npevvhuiq57g3zgmgyzqyuhg9 worker1 Ready Active 20.10.9b9zebfwf6dgzl348y4ox60l1s worker2 Ready Active 20.10.9
退出集群
# 在worker节点上执行,可以用来退出集群[root@worker2 ~]# docker swarm leaveNode left the swarm. # 然后在manager节点上删除已经退出集群的worker2节点[root@manager ~]# docker node lsID HOSTNAME STATUS AVAILABILITY MANAGER STATUSpzvvc7ko4xflq024mnoo1tjmf * manager Ready Active Leadernpevvhuiq57g3zgmgyzqyuhg9 worker1 Ready Activeb9zebfwf6dgzl348y4ox60l1s worker2 Down Active[root@manager ~]# docker node rm worker2worker2[root@manager ~]# docker node lsID HOSTNAME STATUS AVAILABILITY MANAGER STATUSpzvvc7ko4xflq024mnoo1tjmf * manager Ready Active Leader npevvhuiq57g3zgmgyzqyuhg9 worker1 Ready Active
更改节点的availablity状态
swarm集群中node的availability状态可以为 active或者drain,其中:
active状态下,node可以接受来自manager节点的任务分派
drain状态下,node节点会结束task,且不再接受来自manager节点的任务分派(也就是下线节点)
# 将worker1节点下线。如果要删除worker1节点,命令是"docker node rm --force worker1"[root@manager ~]# docker node update --availability drain worker1worker1[root@manager ~]# docker node lsID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSIONpzvvc7ko4xflq024mnoo1tjmf * manager Ready Active Leader 20.10.9npevvhuiq57g3zgmgyzqyuhg9 worker1 Ready Drain 20.10.9b9zebfwf6dgzl348y4ox60l1s worker2 Ready Active 20.10.9 # 如上,当worker1的状态改为drain后,那么该节点就不会接受task任务分发,就算之前已经接受的任务也会转移到别的节点上。 # 再次修改为active状态(即将下线的节点再次上线)[root@manager ~]# docker node update --availability active worker1worker1[root@manager ~]# docker node lsID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSIONpzvvc7ko4xflq024mnoo1tjmf * manager Ready Active Leader 20.10.9npevvhuiq57g3zgmgyzqyuhg9 worker1 Ready Active 20.10.9b9zebfwf6dgzl348y4ox60l1s worker2 Ready Active 20.10.9
在Swarm中部署服务
1、部署服务
[root@manager ~]# docker service create --name nginx01 -p 8080:80 --replicas 3 nginxaq2ni2p5fwm4sipn3lss25n38overall progress: 3 out of 3 tasks 1/3: running [==================================================>] 2/3: running [==================================================>] 3/3: running [==================================================>] verify: Service converged # 查看正在运行服务的列表[root@manager ~]# docker service lsID NAME MODE REPLICAS IMAGE PORTSaq2ni2p5fwm4 nginx01 replicated 3/3 nginx:latest *:8080->80/tcp
2、查询Swarm中服务的信息
# 不加 --pretty 可以输出更详细的信息[root@manager ~]# docker service inspect --pretty nginx01ID: aq2ni2p5fwm4sipn3lss25n38Name: nginx01Service Mode: Replicated Replicas: 3Placement:UpdateConfig: Parallelism: 1 On failure: pause Monitoring Period: 5s Max failure ratio: 0 Update order: stop-firstRollbackConfig: Parallelism: 1 On failure: pause Monitoring Period: 5s Max failure ratio: 0 Rollback order: stop-firstContainerSpec: Image: nginx:latest@sha256:644a70516a26004c97d0d85c7fe1d0c3a67ea8ab7ddf4aff193d9f301670cf36 Init: falseResources:Endpoint Mode: vipPorts: PublishedPort = 8080 Protocol = tcp TargetPort = 80 PublishMode = ingress
# 查询哪个节点正在运行该服务[root@manager ~]# docker service ps nginx01ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTStncgfw2q38vn nginx01.1 nginx:latest worker1 Running Running 12 minutes ago 3osieaaqvwqw nginx01.2 nginx:latest worker2 Running Running 11 minutes ago t2gxqleb9drp nginx01.3 nginx:latest manager Running Running 11 minutes ago # 如果上面命令执行后,上面的STATE字段中刚开始的服务状态为 Preparing ,需要等一会才能变为 Running 状态,其中最费时间的应该是下载镜像的过程
3、访问端口
登陆worker节点,可以查看到nginx容器在运行中
[root@worker1 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES140040f95064 nginx:latest "/docker-entrypoint.…" 4 minutes ago Up 4 minutes 80/tcp nginx01.1.tncgfw2q38vnibz3iini9roo3 [root@worker2 ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES40791e1baa8f nginx:latest "/docker-entrypoint.…" 4 minutes ago Up 4 minutes 80/tcp nginx01.2.3osieaaqvwqwt1skryyyf9xch
4、 在Swarm中动态扩展服务(scale)
# Service还提供了复制(类似kubernetes里的副本)功能,可以通过 docker service scale 命令来设置服务中容器的副本数,这里我们将上面的nginx01容器动态扩展到5个[root@manager ~]# docker service scale nginx01=5nginx01 scaled to 5overall progress: 5 out of 5 tasks 1/5: running [==================================================>] 2/5: running [==================================================>] 3/5: running [==================================================>] 4/5: running [==================================================>] 5/5: running [==================================================>] verify: Service converged [root@manager ~]# docker service lsID NAME MODE REPLICAS IMAGE PORTSaq2ni2p5fwm4 nginx01 replicated 5/5 nginx:latest *:8080->80/tcp # 再来看一下nginx服务中的容器[root@manager ~]# docker service ps nginx01ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTStncgfw2q38vn nginx01.1 nginx:latest worker1 Running Running 22 minutes ago 3osieaaqvwqw nginx01.2 nginx:latest worker2 Running Running 22 minutes ago t2gxqleb9drp nginx01.3 nginx:latest manager Running Running 22 minutes ago g4ubef25mqp5 nginx01.4 nginx:latest worker1 Running Running 3 minutes ago jtvn3b24avb7 nginx01.5 nginx:latest manager Running Running 2 minutes ago
5、Swarm 动态缩容服务(scale)
# swarm还可以缩容,同样是使用scale命令[root@manager ~]# docker service scale nginx01=2nginx01 scaled to 2overall progress: 2 out of 2 tasks 1/2: running [==================================================>] 2/2: running [==================================================>] verify: Service converged [root@manager ~]# docker service ps nginx01ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTStncgfw2q38vn nginx01.1 nginx:latest worker1 Running Running 26 minutes ago 3osieaaqvwqw nginx01.2 nginx:latest worker2 Running Running 26 minutes ago
6、使用 docker service update 对参数进行修改
除了上面使用scale进行容器的扩容或缩容之外,还可以使用docker service update 命令对服务的启动参数进行更新和修改。
# 这里将容器由2个动态扩展到3个[root@manager ~]# docker service update --replicas 3 nginx01nginx01overall progress: 3 out of 3 tasks 1/3: running [==================================================>] 2/3: running [==================================================>] 3/3: running [==================================================>] verify: Service converged [root@manager ~]# docker service ps nginx01ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTStncgfw2q38vn nginx01.1 nginx:latest worker1 Running Running 31 minutes ago 3osieaaqvwqw nginx01.2 nginx:latest worker2 Running Running 30 minutes ago wnezvvpsyjk8 nginx01.3 nginx:latest manager Running Running 23 seconds ago # 对已经使用的镜像滚动升级[root@manager ~]# docker service update --image nginx:latest nginx01nginx01overall progress: 3 out of 3 tasks 1/3: running [==================================================>] 2/3: running [==================================================>] 3/3: running [==================================================>] verify: Service converged
7、模拟宕机worker节点
在swarm cluster集群中启动的容器,在worker node节点上删除或停用后,该容器会自动转移到其他的worker node节点上。
# 如果一个节点宕机了(即该节点就会从swarm集群中被踢出),则Docker应该会将在该节点运行的容器,调度到其他节点,以满足指定数量的副本保持运行状态[root@worker2 ~]# systemctl stop docker [root@manager ~]# docker node lsID HOSTNAME STATUS AVAILABILITY MANAGER STATUSpzvvc7ko4xflq024mnoo1tjmf * manager Ready Active Leadernpevvhuiq57g3zgmgyzqyuhg9 worker1 Ready Activeb9zebfwf6dgzl348y4ox60l1s worker2 Down Active # 查询服务的状态列表,我们可以发现worker2节点故障后,它上面之前的1个task任务已经转移到manager节点上了[root@manager ~]# docker service ps nginx01ID NAME IMAGE NODE DESIRED STATE0iog3ge6y20u nginx01.1 nginx:latest manager Runningjz8gdbu70wy1 \_ nginx01.1 nginx:latest worker2 Shutdownqszwyli49co6 nginx01.2 nginx:latest manager Runningwjxlpsjjhuyi nginx01.3 nginx:latest worker1 Running
当访问192.168.58.151和192.168.58.152节点的8080端口,swarm的负载均衡会把请求路由到一个任意节点的可用的容器上,而访问192.168.58.153节点的8080端口,由于worker2节点宕机了,所以无法访问。
8、删除服务
[root@manager ~]# docker service rm nginx01nginx01 # 查看服务,发现已经被删除了[root@manager ~]# docker service lsID NAME MODE REPLICAS IMAGE PORTS
原文地址:http://www.cnblogs.com/yansink/p/16824233.html