一、swarm
1.简介
Swram是Docker公司推出的官方容器集群平台,基于go语言实现,代码开源在 https://github.com/docker/swarm .2016年2月对架构进行重新设计,推出了v2版本,支持超过1千个节点。作为容器集群管理器,Swarm最大的优势之一就是100%支持标准的Docker API及工具(如Compose,docker-py等),Docker本身就可以很好地与Swarm进行集成。
从上图可以看出,Swarm有两个角色(Manager、agent(也可称为worker)),简单说一下这两个角色的作用:
- Manager:接收客户端服务定义,将任务发送到agnet节点,维护集群期望状态和集群管理功能以及leader选举。默认情况下manager节点也会运行任务,也可以配置只做管理任务。
- agent:接收并执行从管理节点分配的任务,并报告任务当前的状态,以便Manager节点维护每个服务期望状态。
从上图还可以看出,Manager收到的请求可发细分为4大类:
- 第一类,针对已创建容器的操作,Swarm只是起到一个转发请求到特定宿主机的作用。
- 第二类,针对Docker镜像的操作。
- 第三类,创建新的容器docker create这一命令,其中涉及的集群调度会在下面的内容中分享;
- 第四类,其他获取集群整体信息的操作,比如获取所有容器信息、查看Docker版本等。
2.swarm集群调度策略
Swarm管理了多台Docker宿主机,用户在这些宿主机上创建容器时,究竟会与哪台宿主机产生交互呢?
Filter
Swarm的调度策略可以按照指定调度策略分配容器到节点,但是有时候希望能对这些分配加以干预。比如,让I/O敏感的容器分配到安装了SSD的节点上;让计算敏感的容器分配到CPU核数多的机器上;让网络敏感的容器分配到高带宽的机房上,等等。
这时可以通过过滤器(filter)来实现,,用来帮助用户筛选出符合他们条件的宿主机。目前支持五种过滤器:
- Constraint
- Affinity
- Port
- Dependency
- Health
本文为大家介绍前两种过滤器。
1、Constraint过滤器
Constraint过滤器是绑定到节点的键值对,相当于给节点添加标签。可以在启动Docker容器的时候指定,使用swarm启动容器的时候,采用-e constarint:key=value的形式,可以过滤出匹配条件的节点。
下面用个场景为例,我们将分别启动两个容器busybox容器,分别使用过滤器打上红色标签、绿色标签。
#docker service create --replicas 1 -e constraint:color=red busybox ping 127.0.0.1
#docker service create --replicas 1 -e constraint:color=green busybox ping 127.0.0.1
如果目前大家看着上面的命令不太理解,等看完了这篇文章之后,在回过头来看上面的命令就会明白了。
2、Affinity过滤器
Affinity过滤器允许用户在启动一个容器的时候,让它分配到某个已有容器的节点上。
strategy
使用了filter之后,Swarm还提供了strategy(策略)来选出最终运行容器的宿主机,目前swarm已经提供了有如下几种策略:
- random策略:random就是在候选宿主机中(agnet中)随机选择一台的策略;
- binpacking策略:binpacking则会在权衡宿主机CPU和内存的占用率之后选择能分配到最大资源的那台候选宿主机;
- spread策略:spread尝试把每个容器平均地部署到每个节点上。
与此同时,调度策略支持对节点的信任机制,如果一个节点总是处于工作状态,没有失败连接的情况,那么相同条件下,该节点将会优先被选择。目前对宿主机资源的调度策略还在不断开发中,使用filter和strategy这种组合方式,对容器的部署仍然保留了Docker宿主机粒度的操作,已能满足大多数的需求了。
二、部署swarm
环境:
docker1:rhel7 作为leader
docker2:rhel7 作为worker
docker3:rhel7 作为worker
1.docker1
[root@docker1 ~]# docker swarm init
Swarm initialized: current node (pvnqtenq6gqg8xawqw4vo217w) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-53aymw8hr1pea6pctbfl0yiavd199qqakrowmm0pyzk0qb9sq7-aj5svqoo3f5g9z90edthqhstt 172.25.1.1:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
2.docker2、3
[root@docker2 docker]# systemctl start docker
[root@docker3 docker]# docker swarm join --token SWMTKN-1-53aymw8hr1pea6pctbfl0yiavd199qqakrowmm0pyzk0qb9sq7-aj5svqoo3f5g9z90edthqhstt 172.25.1.1:2377
This node joined a swarm as a worker.
3.查看
三、使用docker-swarm建立管理nginx集群
环境:
docker2、docker3:添加了nginx镜像
如果你的虚拟机出现了终端无法补全的情况
yum install bash* -y
1.在docker1上建立nginx集群
查看docker1的docker网络
[root@docker1 ~]# docker network ls ##如下图的swarm就是docker的网络
这里我们先使用docker自己的网卡设备,不进行新建
[root@docker1 ~]# docker service create --name web --publish 80:80 --replicas 3 nginx
image nginx:latest could not be accessed on a registry to record
its digest. Each node will access nginx:latest independently,
possibly leading to different nodes running different
versions of the image.
1um2165841mwk3n4tw0gfaiep
overall progress: 3 out of 3 tasks
1/3: running
2/3: running
3/3: running
verify: Service converged
这里还可以查看docker的桥接
[root@docker1 ~]# yum install bridge-utils -y
[root@docker1 ~]# brctl show
2.查看集群状态
docker1
docker2
docker3
3.编写网页设置
docker1
[root@docker1 ~]# vim index.html
docker1
[root@docker1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2d9069dc838b nginx:latest "nginx -g 'daemon of…" 33 minutes ago Up 33 minutes 80/tcp web.2.351dht0cm0yassn1q4nys1hkp
[root@docker1 ~]# docker cp index.html 2d9069dc838b:/usr/share/nginx/html ##将刚编辑的index文件链接道容器内
docker2
[root@docker2 ~]# vim index.html
[root@docker2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
209a8a99db9b nginx:latest "nginx -g 'daemon of…" 29 minutes ago Up 29 minutes 80/tcp web.1.aknx69sk0iamjioygg0j8fart
[root@docker2 ~]# docker cp index.html 209a8a99db9b:/usr/share/nginx/html
docker3
[root@docker3 ~]# vim index.html
[root@docker3 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
99b973e68cb2 nginx:latest "nginx -g 'daemon of…" 31 minutes ago Up 31 minutes 80/tcp web.3.nk69qdi6h1obbwrx20tfgkww5
[root@docker3 ~]# docker cp index.html 99b973e68cb2:/usr/share/nginx/html
4.测试
我们这里使用一个for循环来测试
我们可以修改集群中nginx服务器的数量,时非常简单的
[root@docker1 ~]# docker service scale web=6
5.部署web端监控工具visualizer
docker1
导入镜像
[root@docker1 images]# docker load -i visualizer.tar
5bef08742407: Loading layer 4.221MB/4.221MB
5f70bf18a086: Loading layer 1.024kB/1.024kB
0a19bde117a5: Loading layer 60.01MB/60.01MB
f7e883283ebc: Loading layer 3.942MB/3.942MB
dfd8ee95c7e7: Loading layer 1.536kB/1.536kB
300a6cad969a: Loading layer 8.704kB/8.704kB
d1627040da6d: Loading layer 489kB/489kB
00ed018016c5: Loading layer 2.56kB/2.56kB
d5aa1ab1b431: Loading layer 4.096kB/4.096kB
2d6a463420f7: Loading layer 4.608kB/4.608kB
53888d7f4cca: Loading layer 2.56kB/2.56kB
ea93ed99abca: Loading layer 2.598MB/2.598MB
fa467b43abc0: Loading layer 4.096kB/4.096kB
94cd25765710: Loading layer 96.48MB/96.48MB
Loaded image: dockersamples/visualizer:latest
部署visualizer
[root@docker1 images]# docker service create \
> --name=viz \
> --publish=8080:8080/tcp \
> --constraint=node.role==manager \
> --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
> dockersamples/visualizer
image dockersamples/visualizer:latest could not be accessed on a registry to record
its digest. Each node will access dockersamples/visualizer:latest independently,
possibly leading to different nodes running different
versions of the image.
o718bfvn48wky58wlwagtuqc0
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged
浏览器查看
四、更新集群
[root@docker1 images]# docker service update --image httpd:latest --update-delay 5s --update-parallelism 6 web ##更新延迟5s,并行更新数6个
image httpd:latest could not be accessed on a registry to record
its digest. Each node will access httpd:latest independently,
possibly leading to different nodes running different
versions of the image.
web
overall progress: 4 out of 6 tasks
1/6: running
2/6: ready
3/6: ready
4/6: running
5/6: running
6/6: running
这样就更新成功了,接下来我们试着自己新建docker网络,进行上述实验~
五、新建docker网络
首先删除之前的web服务
[root@docker1 images]# docker service rm web
web
[root@docker1 images]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
o718bfvn48wk viz replicated 1/1 dockersamples/visualizer:latest *:8080->8080/tcp
接下来可以进行新建网络了
[root@docker1 images]# docker network create -d overlay my_net1 ##新建全局网络my_net1
4kmbap0iwessxzbpenuphh1jg
[root@docker1 images]# docker service create --name web --network my_net1 --publish 80:80 --replicas 30 nginx ##用新建的网络新建服务web
image nginx:latest could not be accessed on a registry to record
its digest. Each node will access nginx:latest independently,
possibly leading to different nodes running different
versions of the image.
rou3rlcxuj82ok8y3vssx44cm
overall progress: 30 out of 30 tasks
verify: Service converged
查看浏览器
接下俩尝试更新
[root@docker1 images]# docker service update --image httpd:latest --update-delay 5s --update-parallelism 10 web
image httpd:latest could not be accessed on a registry to record
its digest. Each node will access httpd:latest independently,
possibly leading to different nodes running different
versions of the image.
web
overall progress: 0 out of 30 tasks
service update paused: update paused due to failure or early termination of task jz8fww4o9bmzfjfihq1aj72f4
失败了,查找原因发现是,docker2和docker3上没有导入httpd.tar镜像,docker2和docker3导入后
[root@docker1 images]# docker service update --image httpd:latest --update-delay 5s --update-parallelism 10 web
image httpd:latest could not be accessed on a registry to record
its digest. Each node will access httpd:latest independently,
possibly leading to different nodes running different
versions of the image.
web
overall progress: 30 out of 30 tasks
verify: Service converged
成功了,ok~