docker-swarm的运⽤
写了如何使⽤docker-compose来部署服务。虽然docker-compose解决了docker间通信问题,但是缺点也是很明显的。就是只能在⼀台宿主机上通信。我们使⽤docker-compose在宿主机上部署了20+的应⽤,宿主机配置 16C 32GB RAM。服务全部启动后,常态内存占⽤就⾼达85%。显然是⽆法应对突发情况的,因此如果服务⽐较多,仅仅使⽤docker-compose是不够的。因此我们使⽤docker-swarm来部署服务。
docker-swarm是docker官⽅推出的docker集解决⽅案,相⽐与k8s更轻量,因此如果服务不多可以采⽤docker-swarm来部署服务!
1.初始化集
[root@zhongjianjian03 ~]# docker swarm init
执⾏该命令的节点,⼀般会成为master(leader)节点,之后的⼀些集操作命令,也都是在master节点执⾏。这⾥⼀定要注意
注意红线框住的地⽅,这⾥给了⼀个命令,就是其他节点如果要加⼊集可以使⽤这个命令加⼊。
我这⾥⼜了⼀台机器,执⾏了该命令
可以看到当前节点加⼊到了swarm集,且作为worker节点。此时
我们可以在master节点查看节点状态了
使⽤命令。
[root@zhongjianjian03 ~]# docker node ls
可以看到⽬前集有两个节点了(在这⾥我是使⽤了两个linux主机,如果只有⼀台主机,可以试试使⽤docker-machine来创建虚拟主机,这个⼯具还有功能就是可以创建管理本地及远程虚拟主机,试想假如有100台主机,如何在上⾯配置Docker呢?批量执⾏脚本是个选择,同样的使⽤docker-machine也是⼀个选择)。且⼀台master ⼀台work 即MANAGER STATUS 其实这个字段还有其他值
Reachable:该节点是管理节点中的从节点,如果 Leader 节点不可⽤,该节点有资格被选为新的 Leader
Unavailable:该管理节点已不能与其他管理节点通信。如果管理节点不可⽤,应该将新的管理节点加⼊集,或者将⼯作节点升级为管理节点。
这⾥有⼀个知识点就是如果节点⽐较多的情况下怎么知道节点对应的宿主机呢?
其实在每个节点使⽤ hostname这个命令即可对应到节点的列表中了。(docker node ls 命令会展⽰节点对应的Hostname)
实际上我们还可以对每个节点进⾏个性化设置。即添加标签。
# 只能在manager节点执⾏该命令
docker node update --label-add <label-name>=<label-value> --label-add <label-name>=<label-value> <hostname>
命令如上。此时我们即可对每个node添加标签了,⽐如我们可以添加⼀个名称为ip的标签
使⽤命令
docker node update --label-add ip=192.168.1.
即可添加到对应的label。
此时我们在manager节点,使⽤ docker node ls 得到节点列表。
同时使⽤。
docker node inspect <;节点id>
即可到该节点对应的ip。当然直接使⽤该命令(不⽤前⾯的⿇烦步骤)也可以得到当前节点对应的Ip
既然集已经创建好了,那么我们如何部署⾃⼰的应⽤呢?
其实很简单,前⾯学习的docker-compose的知识可以⽤到了。
这⾥先说明⼀下部署的应⽤。要部署4个应⽤。使⽤docker-swarm在两个节点的情况下,他会给每个节点分配两个应⽤。最后达成的效果应该是这个四个服务可以互相访问的到。
⾸先先编写"l",这⾥为什么加上了引号,因为严格意义上说我们并不是要使⽤docker-compose了,因为这⾥有的参数并不适⽤于docker-compose。
version: '3'
services:
node_a1:
image: xxx/node:v1
networks:
- my-net
ports:
- "8000:8080"
deploy:
replicas: 1
command: java -jar node-a1-1.jar
node_a2:
image: xxx/node:v1
networks:
- my-net
ports:
- "8001:8080"
deploy:
replicas: 1
command: java -jar node-a2-1.jar
node_b1:
image: xxxx/node:v1
networks:
- my-net
ports:
- "8002:8080"
deploy:
replicas: 1
command: java -jar node-b1-1.jar
node_b2:
image: xxx/node:v1
networks:
- my-net
ports:
- "8003:8080"
deploy:
replicas: 1
command: java -jar node-b2-1.jar
networks:
my-net:
driver: overlay
可以看到,我们写了四个应⽤,这四个应⽤⾥⾯是什么内容呢? 其实就是每个应⽤访问其他三个应⽤。需要注意的是。这⾥使⽤的⽹络是overlay
接下来就是要发布服务了。使⽤命令
# 在master节点执⾏ , l 就是刚才编辑的"l"⽂件 test 是服务名前缀
[root@zhongjianjian03 ~]# docker stack deploy -l test
可以看到创建了⼀个⽹络,和四个应⽤。docker重启容器命令
此时我们可以查看我们的服务有哪些
#mster节点执⾏
[root@zhongjianjian03 ~]# docker service ls
可以看到我们的服务有哪些。
但其实我关⼼的是,我的服务在哪个节点上,毕竟我是swarm集,有两台机器。
其实查服务在哪个节点,有两种⽅法,⼀种是直接在某个节点上执⾏
docker ps
这样就可以看到执⾏命令的节点上跑了哪些容器(也即服务)。
节点A
节点B
这样我们就到了服务对应的机器节点。
你可能会想这样很慢,如果节点很多,那要⼀个服务所在的节点不是很慢?
其实还可以使⽤其他⽅式,⾸先查询所有的服务列表
⽐如我想知道 test_node_b2所在的节点。此时我们现在有了 service id 。我们可以通过命令查到服务所在节点信息
# 在master节点执⾏
[root@zhongjianjian03 ~]# docker service ps i5xlp60hd4x5
如图,可以看到已经查到了节点信息,可以跟上图做⼀个⽐较,发现信息是⼀致的。
但是当我们的服务⽐较多的时候,怎么快速到服务对应的容器是哪个呢?
# 该命令在master/work节点都可以⼯作,命令返回容器信息(只显⽰当前节点的)
docker ps --filter name=<service_name> -q(可选)
此时,服务都启动了。我们怎么知道服务之前是否互通呢?
很简单,之前我们在编辑“l”⽂件时定义了四个服务。
即:node_a1 node_a2 node_b1 node_b2
现在这四个服务分布在了两个机器上。我们任意选择⼀个机器,选择其中的⼀个容器进去。
⽐如我们进⼊node_a1容器
# 需在容器所在的节点上执⾏该命令
[root@zhongjianjian03 ~]# docker exec -it d97765b92136 bash
这样我们就进⼊了容器内部。
接着我们只需要使⽤ping 命令就可以知道是否可以互相访问了
从图⽚可以知道。⽹络是通的。接着就可以测试⾃⼰应⽤的通过性了,具体就以实际应⽤为准了
⾄此docker-swarm集搭建完毕。可以看到跟docker-compose相⽐,只是在命令上有些不同,docker-compose需要单独安装,⽽docker-swarm则需要提前创建集。
现在我们的应⽤分布在集⾥,就可以⽅便的进⾏服务冗余了,当然docker-swarm的命令不⽌这些,但是缺点也⽐较明显就是没有可视化的界⾯可供操作,虽然可以通过安装portainer 来管理swarm集,但功能上会有局限,并没有k8s强⼤!
同样的,如果增加了某个服务,⽐如增加了⼀个node5服务,⾸先现在 l中新增服务。然后使⽤命令
docker stack deploy --compose-file=/opt/docker/l node5
即可完成新增服务的部署!
如果不想使⽤集了。也可以删除集。
当前节点状态:
可以看到 AVAILABILITY字段的两个值均是在线状态
删除节点:
# 让 node3 离开,排空该node 的容器(在 master 上操作)
[root@zhongjianjian03 ~]# docker node update --availability drain i0yhyiotqklaj7626jfavnuky
此时可以看到node的状态
让被移除的node离开集
# 在被离开的节点上操作
[root@app01 ~]# docker swarm leave
Node left the swarm.
删除node节点
# 在master节点操作
[root@zhongjianjian03 ~]# docker node rm i0yhyiotqklaj7626jfavnuky
此时节点列表为:
之后我们只需要使⽤类似的命令就能删掉主节点:
[root@zhongjianjian03 ~]# docker node update --availability drain rsj6jxbm1fwz7dsbn0pxillxj
rsj6jxbm1fwz7dsbn0pxillxj
[root@zhongjianjian03 ~]# docker swarm leave --force
Node left the swarm.
之后再次查看集状态
集已移除!。
如果master节点未被删除,现在有新节点要加⼊集,应该如何获取Token呢?
# 在master节点上使⽤命令 docker swarm join-token 可以查看或更换join token。
docker swarm join-token worker:查看加⼊woker的命令。
docker swarm join-token manager:查看加⼊manager的命令
docker swarm join-token --rotate worker:重置woker的Token。
docker swarm join-token -q worker:仅打印Token。
需要注意的⼏个点,我们介绍了。docker-compose占位符的使⽤。
⽽再docker swarm的l⽂件中,除了部分配置有差别外,docker-compose的占位符也是不能直接使⽤的。
如果你直接使⽤了,你在启动的容器中使⽤inspect查看容器信息。是看不到占位符的信息的。
因此总体解决思路是这样的,先使⽤docker-compose -l config > l
先使⽤docker-compose config命令输出⽂件,到l 然后再使⽤docker stack deploy -l <stack name>来启动。
可以
同时,docker swarm 与docker-compose本⾝也是有区别的,当然显著的区别是docker-compose 是单机的,swarm是集的,同时,对于docker-compose来说,每个服务是container ⽽docker swarm是每个service,虽然在docker-compose 也可以使⽤service,这个在 portainer ⼯具中是可以查看的,有⼀个能想到的点是,如果我docker swarm发布了很多应⽤,这个时候我想更改某个服务的端⼝映射,那么停⽌服务,更新脚本,重启启动,明显是很⿇烦的。其实还是可以通过docker命令来更新的。
更新运⾏中容器端⼝映射。
#添加端⼝映射,第⼀个为宿主机端⼝,servicename需要注意,看使⽤的是swarm集还是直接的compose,如果是swarm集需要加上stack 名
docker service update --publish-add '5050:8080' <service_name>
由上所述服务在单副本的情况下,是没有问题的,但是多副本时,就会涉及到服务的负载均衡。简单来讲,docker swarm的负载均衡有两种⽅式1.vip
vip这种形式为swarm的默认形式,简单说,如果swarm集⾥,部署了⼀个nginx应⽤,并且配置容器与宿主机的端⼝映射,此时你访问集的任意节点,都可以访问该服务。
2.dnsrr
dnsrr需要单独进⾏配置,对应命令⾏中的--endpoint-mode dnsrr 。这种模式下不⽀持端⼝映射,也就是说如果你是前端应⽤就不能使⽤该模式了。该模式的是使⽤DNS轮询的⽅法进⾏的负载均衡。因此⽐较适合做后端服务。也就是说在⼀个swarm的stack中,后端service有多个副本,适合使⽤该⽅式,前端发送的请求后均匀发送到后端的容器中。然⽽并⾮每次请求都会均匀分布,⽐如⼗次请求,前5次⾛A容器后5次⾛B容器,如果manager节点也运⾏了服务,则manager节点不处理请求。
#version: "3" #这⾥需要注意版本,如果是3则报错:error endpoint_mode Additional property endpoint_mode is not allowed
version: "3.3"
services:
wordpress:
image: wordpress
ports:
- 8080:80
networks:
- overlay
deploy:
mode: replicated
replicas: 2
endpoint_mode: vip #wordpress是前端应⽤(准确说是前后端在⼀起的应⽤)使⽤默认的vip⽅式
mysql:
image: mysql
volumes:
- db-data:/var/lib/mysql/data
networks:
- overlay
deploy:
mode: replicated
replicas: 2
endpoint_mode: dnsrr #mysql是后端服务,不与宿主机映射端⼝,可以使⽤dns轮询的⽅式
volumes:
db-data:
networks:
overlay:
compose-file
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论