swarm
swarm概述
Raft:
一致性算法,在保证大多数管理节点存活的情况下,集群才能使用,所以就要求如果集群的话,manager节点必须>3台,如果是两个台,其中一台宕机,剩余的一台也将不可用,以致整个集群不可用。
Manager:
管理节点,用于管理工作节点。
为了利用 swarm 模式的容错特性,Docker 建议您根据组织的高可用性要求实现奇数个节点。当您有多个管理器时,您可以从管理器节点的故障中恢复而无需停机。
一个三管理器群最多可以容忍一名管理器的损失。
一个五管理器群最多可以同时丢失两个管理器节点。
一个N管理器集群最多可以容忍丢失 (N-1)/2管理器。
Docker 建议一个 swarm 最多使用七个管理器节点。
Worker:
工作节点,负责项目的扩缩容。
工作节点也是 Docker 引擎的实例,其唯一目的是执行容器。Worker 节点不参与 Raft 分布式状态,不做调度决策,也不服务于 swarm 模式的 HTTP API。
您可以创建一个由一个管理器节点组成的集群,但如果没有至少一个管理器节点,您就不能拥有一个工作程序节点。默认情况下,所有经理也是工人。在单个管理节点集群中,您可以运行类似docker service create的命令,并且调度程序将所有任务放在本地引擎上。
要防止调度程序将任务放置在多节点集群中的管理器节点上,请将管理器节点的可用性设置为Drain。调度器优雅地停止Drain模式节点上的任务,并在一个 Active节点上调度任务。调度程序不会将新任务分配给Drain 可用的节点。
swarm部署
准备
资料参考:官方swarm文档
首先声明,如果想确保之后的操作顺利,要么直接关闭虚拟机或者各主机的防火墙,要么按照官网开放每个虚拟机或主机的三个端口。
注意,有的端口需要udp和tcp端口都要放开。
firewall-cmd --add-port=2377/tcp --permanent
firewall-cmd --add-port=7946/tcp --permanent
firewall-cmd --add-port=7946/udp --permanent
firewall-cmd --add-port=4789/udp --permanent
firewall-cmd --reload
机器节点 | IP地址 | 作用 |
---|---|---|
manager | 192.168.150.129 | 管理节点,也参与工作 |
node_1 | 192.168.150.131 | 工作节点1 |
node_2 | 192.168.150.132 | 工作节点2 |
创建集群
docker swarm init --advertise-addr 192.168.150.129
执行此命令之后,集群创建,同时也会创建好专用的ingress网络
当然,也可以在创建的时候指定IP 地址池,默认网段为10.0.0.0/24,切记自己指定的话,不要设置成本机或者已经在使用的网段,否则会冲突,导致外网无法访问swarm服务,无法理解就用上边的命令即可:
docker swarm init --advertise-addr 192.168.150.129 --default-addr-pool 192.168.149.0/24
作用:
添加节点到 swarm
如果想加入工作节点,就复制上方的命令在对应的机器上运行即可。
#加入管理节点:
docker swarm join --token SWMTKN-1-21khki6nbh8ia7y84q9j46i0rccaz699syze0kzqsh3fn4ry8j-ej6to7vhn97yauw6351g37j86 192.168.150.129:2377
#加入工作节点:
docker swarm join --token SWMTKN-1-21khki6nbh8ia7y84q9j46i0rccaz699syze0kzqsh3fn4ry8j-084pwto4nh055r3kpuqgzhpvz 192.168.150.129:2377
如果忘记了上边的命令、token,也可以运行如下命令来查看:
查看加入管理节点:
docker swarm join-token manager
查看加入工作节点:
docker swarm join-token worker
查看节点详情:
docker node ls
查看每个单点的详情:
docker node inspect node_1 --pretty
更改节点可用性
当我们不想所有节点都部署某个任务的时候,那么我们可以先排空这个节点。
docker node update --availability drain node_1
节点添加或删除标签
节点打标签的作用是,你可以在服务部署的时候灵活的选择将服务部署到指定的节点上,指定的根据就是标签。
标签常见方式有两种,一种是单独的名字,一种是key=value的形式,根据需求怎么方便怎么使用。
docker node update --label-add node1(自定义名称) 节点名称
docker node update --label-add node1_lable=node1((自定义key,value) 节点名称
也可以同时使用这两种方式给一个节点打标签。
docker node update --label-add node1 --label-add node1_lable=node1 节点名称
其实可以看出,标签创建无论采用哪种方式,结果都是以key,value方式存在的,只指定key,值默认为空而已。
所以这里直接给三个节点分别打上标签,用同一个key,不同的值:
删除节点:
docker node update --label-rm node1 节点名称
升级或降级节点
当管理器节点不可用或您想使管理器脱机进行维护时,这很有用。同样,您可以将管理节点降级为工作者角色;
注意,命令都是在管理节点运行,确保要升级的工作节点防火墙开放2377端口
,否则无法监测心跳。
开放端口:firewall-cmd --add-port=2377/tcp --permanent
重新加载: firewall-cmd --reload
-
升级工作节点为管理节点
docker node promote node_1
-
降级管理节点为工作节点
注意,如果只剩一台管理节点是不行的。docker node demote node_1
离开swarm集群
-
离群
docker swarm leave
-
删除节点
节点离开 swarm 后,可以在管理节点上运行该命令docker node rm
以从节点列表中删除该节点
例如:docker node rm node_1
强制离开或删除,请加上 --force
创建服务
这里我们已nginx为例
部署(普通/挂载)
-
普通部署
部署两份服务到集群中:
docker service create -p 80:80 --name=my_nginx nginx:1.22.0
如果想使用挂载的话,可以采用挂载卷或者挂载目录,这里采用挂载目录的方法:
docker service create \ -p 80:80 \ --replicas=2 \ --mount type=bind,src=/mydata/nginx/html,target=/usr/share/nginx/html \ --mount type=bind,src=/mydata/nginx/logs,target=/var/log/nginx \ --mount type=bind,src=/mydata/nginx/conf/nginx.conf,target=/etc/nginx/nginx.conf \ --name my_nginx \ -d nginx:1.22.0
挂载卷type=volume,更多请参考官方文档-卷的使用、Docker 持久存储介绍
-
指定节点部署
关键字:–constraint(==或!=),指定服务部署到哪个标签的节点上,或者指定不部署到哪个标签的节点上。
通过上文标签部分我们给三个节点分别分配了node=manager、node=worker1、node=worker2三个标签,下边测试一下只将服务部署到工作节点下:docker service create \ -p 80:80 \ --replicas=2 \ --constraint node.labels.node!=manager \ --mount type=bind,src=/mydata/nginx/html,target=/usr/share/nginx/html \ --mount type=bind,src=/mydata/nginx/logs,target=/var/log/nginx \ --mount type=bind,src=/mydata/nginx/conf/nginx.conf,target=/etc/nginx/nginx.conf \ --name my_nginx \ -d nginx:1.22.0
关键命令:--constraint node.labels.node!=manager
成功!!!
更新
-
更新服务端口
如果服务端口忘记指定,没必要删除服务重新部署,直接更新端口即可#添加 docker service update --publish-add 80:80 my_nginx
#删除 docker service update --publish-rm 80 my_nginx
-
更新服务个数
添加服务数量或者减少服务数量,主要看后边设置的服务数字,大于当前服务数就是增加,小于当前服务数,就是减少,这就是所谓的扩缩容:docker service scale my_nginx=3
-
更新服务版本
当我们服务升级的时候,需要更新包,比如java的项目jar包,不会总是一尘不变的,版本更新的时候就会用到,这里从1.22.0更新到 nginx:latest。docker service update --image nginx:latest my_nginx
默认一个服务更新完成再立刻更新下一个,也可以根据需求设置不同的参数:
--update-delay:
服务更新之间的时间间隔,一个服务更新完成之后多久再更新下一个,(可以将时间描述T为秒数Ts、分钟数Tm或小时数的组合Th。所以 10m30s表示延迟 10 分 30 秒)。
--update-parallelism:
同时并发更新的服务数量。例如:
docker service update \ --update-delay 10s \ --update-parallelism 2 \ --image nginx:latest \ my_nginx
创建的时候也可以指定(没有挂载的例子):
docker service create \ --replicas 3 \ --name my_nginx \ --update-delay 10s \ --update-parallelism 2 \ nginx:1.22.0
查看是否生效,在服务更新结束之后,执行:
docker service inspect --pretty my_nginx
服务部署失败会导致任务暂停,例如:
继续停止的任务:docker service update my_nginx
-
版本回退
如果服务的更新版本没有按预期运行或者发生错误,可以及时回退版本。docker service rollback my_nginx
如果失败了,等一会或者多试几次,就成功了,可能是我的镜像原因。
查看服务的滚动更新详情:
docker service ps my_nginx
删除
docker service remove my_nginx
各节点的docker中会删除掉容器,但是会保留镜像。
测试
浏览器访问任何一个节点都可以访问到nginx,即使这个节点没有安装服务。
看一下负载均衡效果,我这里用浏览器不管用,不会变化(可能是缓存的原因),所以采用本机DOS窗口去访问测试:
指定节点自由扩缩容
想了想,还是将这部分单拿出来说一说,首先,想一个场景:在真实生产环境中,我们要根据实际情况对项目进行扩缩容,也就是集群的增加和减少,通过上边的部署服务部分,我们知道,可以指定服务部署到哪些节点机器上,但这只是针对刚开始创建来说的,如果要是想扩缩容,那么怎么指定扩缩某个节点机器上的服务呢?要知道,swarm并没有将服务指定扩缩到哪某台机器上的命令。
所以,当我们在缩容的时候,想指定删除哪台节点机器的时候,那只能让这个节点离开swarm集群,而在扩容的时候,默认新增加的机器上是没有服务的,那么swarm在扩容的时候,优先部署没有服务的机器,这样也就实现了指定扩容了。