文章目录
前言
Docker swarm简介
- Swarm是Docker官方提供的一款集群管理工具,其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口统一管理这些Docker主机上的各种Docker资源。Swarm和Kubernetes比较类似,但是更加轻,具有的功能也较kubernetes更少一些。
- Swarm的基本架构如下图所示
- 这个图作为一个整体实际上都处于一个所谓的集群中,它可能对应了一到多台的实际服务器。每台服务器上都装有Docker并且开启了基于HTTP的DockerAPI。这个集群中有一个SwarmManager的管理者,用来管理集群中的容器资源。管理者的管理对象不是服务器层面而是集群层面的,也就是说通过Manager,我们只能笼统地向集群发出指令而不能具体到某台具体的服务器上要干什么(这也是Swarm的根本所在)。至于具体的管理实现方式,Manager向外暴露了一个HTTP接口,外部用户通过这个HTTP接口来实现对集群的管理。对于稍微大一点的集群,最好是拿出一台实际的服务器作为专门的管理者,作为学习而言,也可以把管理者和被管理者放在一台服务器上。
- Swarm 在 Docker 1.12 版本之前属于一个独立的项目,在 Docker 1.12 版本发布之后,该项目合并到了 Docker 中,成为 Docker 的一个子命令。目前,Swarm 是 Docker 社区提供的唯一一个原生支持 Docker 集群管理的工具。它可以把多个 Docker 主机组成的系统转换为单一的虚拟 Docker 主机,使得容器可以组成跨主机的子网网络。
- Docker Swarm 是一个为 IT 运维团队提供集群和调度能力的编排工具。用户可以把集群中所有 Docker Engine 整合进一个「虚拟 Engine」的资源池,通过执行命令与单一的主 Swarm 进行沟通,而不必分别和每个 Docker Engine 沟通。在灵活的调度策略下,IT 团队可以更好地管理可用的主机资源,保证应用容器的高效运行。
Docker Swarm 优点
-
任何规模都有高性能表现
对于企业级的 Docker Engine 集群和容器调度而言,可拓展性是关键。任何规模的公司——不论是拥有五个还是上千个服务器——都能在其环境下有效使用 Swarm。
经过测试,Swarm 可拓展性的极限是在 1000 个节点上运行 50000 个部署容器,每个容器的启动时间为亚秒级,同时性能无减损。 -
灵活的容器调度
Swarm 帮助 IT 运维团队在有限条件下将性能表现和资源利用最优化。Swarm 的内置调度器(scheduler)支持多种过滤器,包括:节点标签,亲和性和多种容器部策略如 binpack、spread、random 等等。 -
服务的持续可用性
Docker Swarm 由 Swarm Manager 提供高可用性,通过创建多个 Swarm master 节点和制定主 master 节点宕机时的备选策略。如果一个 master 节点宕机,那么一个 slave 节点就会被升格为 master 节点,直到原来的 master 节点恢复正常。
此外,如果某个节点无法加入集群,Swarm 会继续尝试加入,并提供错误警报和日志。在节点出错时,Swarm 现在可以尝试把容器重新调度到正常的节点上去。 -
和 Docker API 及整合支持的兼容性
Swarm 对 Docker API 完全支持,这意味着它能为使用不同 Docker 工具(如 Docker CLI,Compose,Trusted Registry,Hub 和 UCP)的用户提供无缝衔接的使用体验。
Docker Swarm 为 Docker 化应用的核心功能(诸如多主机网络和存储卷管理)提供原生支持。开发的 Compose 文件能(通过 docker-compose up )轻易地部署到测试服务器或 Swarm 集群上。Docker Swarm 还可以从 Docker Trusted Registry 或 Hub 里 pull 并 run 镜像。 -
综上所述,Docker Swarm 提供了一套高可用 Docker 集群管理的解决方案,完全支持标准的 Docker API,方便管理调度集群 Docker 容器,合理充分利用集群主机资源。
-
注意:并非所有服务都应该部署在Swarm集群内。数据库以及其它有状态服务就不适合部署在Swarm集群内。
相关概念
1.节点
运行 Docker 的主机可以主动初始化一个 Swarm 集群或者加入一个已存在的 Swarm 集群,这样这个运行 Docker 的主机就成为一个 Swarm 集群的节点 (node) 。节点分为管理 (manager) 节点和工作 (worker) 节点。
管理节点用于 Swarm 集群的管理,docker swarm 命令基本只能在管理节点执行(节点退出集群命令 docker swarm leave 可以在工作节点执行)。一个 Swarm 集群可以有多个管理节点,但只有一个管理节点可以成为 leader,leader 通过 raft 协议实现。
工作节点是任务执行节点,管理节点将服务 (service) 下发至工作节点执行。管理节点默认也作为工作节点。你也可以通过配置让服务只运行在管理节点。下图展示了集群中管理节点与工作节点的关系。
2.服务和任务
任务 (Task)是 Swarm 中的最小的调度单位,目前来说就是一个单一的容器。
服务 (Services) 是指一组任务的集合,服务定义了任务的属性。服务有两种模式:
replicated services 按照一定规则在各个工作节点上运行指定个数的任务。
global services 每个工作节点上运行一个任务
两种模式通过 docker service create 的 --mode 参数指定。下图展示了容器、任务、服务的关系。
实验环境
主机名(IP) | 服务 |
---|---|
server1(172.25.24.1) | manager |
server2(172.25.24.2) | node1 |
server3(172.25.24.3) | node3 |
真机(172.25.24.24) | 测试 |
Docker swarm集群的搭建
server1
- 1.搭建yum源,下载docker:
[root@server1 ~]# cat /etc/yum.repos.d/docker.repo
[docker]
name=docker
gpgcheck=0
baseurl=http://172.25.24.24/docker
[root@server1 ~]# yum install docker-ce -y
- 2.开启服务:
[root@server1 ~]# systemctl start docker
[root@server1 ~]# systemctl enable docker
- 3.创建Swarm集群:
[root@server1 ~]# docker swarm init #初始化集群
- 4.查看桥接信息以及网络配置:
[root@server1 ~]# yum install bridge-utils -y
[root@server1 ~]# brctl show
[root@server1 ~]# docker network ls
server2和server3
- 1.Server2和server3搭建yum源。下载docker并开启服务,这里不再赘述。
- 2.Server2和server3加入集群,使用刚刚server1初始化给的信息添加:
- Server2:
docker swarm join --token SWMTKN-1-1is4ic18j3r5wvu43u89uiybtetq3ea5e9w8ikqi0qftw0maqd-77f2dlpp8xj8p65pn1gx1r0a7 172.25.24.1:2377
- server3:
- 在server1上查看swarm集群节点信息:
[root@server1 ~]# docker node ls
使用swarm集群部署web服务
- 1.给三个节点导入nginx镜像
[root@server1 ~]# ls
nginx.tar
[root@server1 ~]# docker load -i nginx.tar
[root@server1 ~]# docker images
[root@server1 ~]# docker tag nginx:1.16 nginx:latest
[root@server2 ~]# docker tag nginx:1.16 nginx:latest
[root@server3 ~]# docker tag nginx:1.16 nginx:latest
- 2.创建集群服务,并创建一个覆盖网络,保证在不同主机上的容器互通。在集群上部署三个nginx容器,用来提供服务。
[root@server1 ~]# docker network create -d overlay webnet # 创建驱动为overlay的网络
[root@server1 ~]# docker service create --name web --network webnet --replicas 3 -p 80:80 nginx #创建集群服务
[root@server1 ~]# docker service ps web
命令解释:
- docker service create 命令创建一个服务
- –name 服务名称命名为 web
- –network 指定服务使用的网络模型
- –replicas 设置启动的示例数为3,部署几个完全一样的容器(副本)
- 3.查看80端口的开启情况,docker服务列表以及docker集群的web列表。
[root@server1 ~]# netstat -antlp | grep 80
[root@server1 ~]# docker service ls
[root@server1 ~]# docker service ps web
- 4.Server1~3做以下操作:复制发布页面到容器nginx的默认发布目录下
- Server1:
[root@server1 ~]# vim index.html
[root@server1 ~]# cat index.html
server1---nginx
[root@server1 ~]# docker cp index.html web.1.nhmzxhdvn2cee47ddrmbxku73:/usr/share/nginx/html
- server2:
- server3:
- 5.在真机上测试负载均衡(容器部署在集群上,所以任何一个ip都可以访问到)。
[root@foundation10 ~]# curl 172.25.24.1
[kiosk@foundation11 ~]$ for i in {1..10};do curl http://172.25.11.1;done
[kiosk@foundation11 ~]$ for i in {1..10};do curl http://172.25.11.2;done
[kiosk@foundation11 ~]$ for i in {1..10};do curl http://172.25.11.3;done
弹性伸缩(增加或减少服务数目)
- 1.拉伸(增加scale数目)
[root@server1 ~]# docker service scale web=6
[root@server1 ~]# docker ps
可以看到容器1,5部署在了server1上。
容器2,6部署在了server2上。
容器3,4部署在了server3上。
- 查看docker集群的web服务列表
[root@server1 ~]# docker service ps web
- 2.真机测试
[root@foundation10 ~]# curl 172.25.24.1
server1---nginx
[root@foundation10 ~]# curl 172.25.24.1
- 3.缩减
[root@server1 ~]# docker service scale web=3
[root@server1 ~]# docker service ps web
- 4.真机测试
[root@foundation10 ~]# curl 172.25.24.1
监控
- 1.在server1上导入镜像visualizer
[root@server1 ~]# docker load -i visualizer.tar
- 2.创建swarm的监控容器
[root@server1 ~]# 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
- 查看viz容器以及8080端口是否开放
[root@server1 ~]# docker ps
[root@server1 ~]# netstat -antlp | grep 8080
- 3.测试:web界面去监控管理的集群以及每个集群的状态。
http://172.25.24.1:8080/
- 当我们关闭server3的docker服务时,再查看监控
[root@server3 ~]# systemctl stop docker
- 我们可以发现当server3停掉后,它上面的服务跑到了server2上
当增加服务的数目时,Docker swarm集群会自动分配每个节点的web数目,并展示到监控界面
[root@server3 ~]# systemctl start docker
[root@server1 ~]# docker service scale web=12
注意:集群中的每个节点都应该有拉起容器的镜像,因为每个节点都有承担任务的可能性。
滚动更新(灰度发布)
更新的过程中始终保持业务连续性,用户感觉不到。可以回滚
- 1.给server1~3导入要更新的镜像。(以httpd镜像为例,也可以使用game2048,只要该镜像也开启的是80端口即可。)
[root@server1 ~]# docker load -i httpd.tar
[root@server2 ~]# docker load -i httpd.tar
[root@server3 ~]# docker load -i httpd.tar
- 2.增加集群的规模
[root@server1 ~]# docker service scale web=30
- 这里是没有更新的,拉伸的30个服务全是nginx的容器。
- 3.更新,并且设定每5s更新一次,每次更新5个。这时,所有的nginx容器已经释放,现在的容器都是基于httpd镜像建立的。
- 参数含义解释:
- –image 指定要更新的镜像
- –update-parallelism 指定最大同步更新的任务数
- –update-delay 指定更新间隔
[root@server1 ~]# docker service scale web=30
[root@server1 ~]# docker service update --image httpd --update-delay 5s --update-parallelism 5 web
swarm的global模式的部署
- 某些特殊的以用场景,比如说:大型集群当中要对每个节点进行zabbix监控,那么只需要给每个节点部署一个zabbix-agent容器即可,global也就是保证每个节点时刻有且只有一个容器。
- 给三个节点导入game2048的镜像。
[root@server1 ~]# docker load -i game2048.tar
[root@server2 ~]# docker load -i game2048.tar
[root@server3 ~]# docker load -i game2048.tar
- 我们在server1上以global模式部署集群。
[root@server1 ~]# docker service rm web
[root@server1 ~]# docker service create --name web --publish 80:80 --mode global game2048
- 在三个节点查看,此时三个节点都只运行了一个容器
- 在浏览器中查看。
- 如果集群当中自动加入一个节点,那么管理节点就会自动在刚进来的节点上面运行一个容器
接下来实现一下 - 在真机当中再开启一台server4,给server4安装并开启服务,导入镜像game2048并加入集群,这里不再赘述。
- server1上查看
- 在server4查看,此时game2048容器已经运行。
- 在浏览器里面查看,可以看到已经自动为server4添加web服务
补充:对节点设置状态(“active”正常|“pause”暂停|“drain”排除自身work任务)
[root@server1 ~]# docker load --help
[root@server1 ~]# docker node update --help
- 将server4设置为drain状态,也就是worker不再工作。
[root@server1 ~]# docker node update --availability drain server4
server4
[root@server1 ~]# docker node ls
- 在浏览器里面查看各个节点的状态
- 恢复server4为active状态
[root@server1 ~]# docker node update --availability active server4
server4
[root@server1 ~]# docker node ls
- 在浏览器里面查看各个节点的状态
- 将server1设置为drain状态,server1上的worker容器会释放,但是监控的容器会正常工作
[root@server1 ~]# docker node update --availability drain server1
server1
[root@server1 ~]# docker node ls
- 在浏览器里面查看各个节点的状态
- 查看容器的状态
- 恢复server1的状态
[root@server1 ~]# docker node update --availability active server1
server1
[root@server1 ~]# docker node ls
[root@server1 ~]# docker service ps viz