本文是SpringCloud实战(十)-容器自动化集群部署(Swarm),若要关注前文,请点击传送门:
SpringCloud实战(九)-容器自动化部署与持续集成(Docker)
前文我们介绍了容器自动化部署与持续集成。在我们成功搭建好了前文的容器自动化部署之后,不知道大家有没有考虑过,那如果我要部署集群怎么办?难道在Jenkins中对同一个工程新建多个实例,然后每个实例采用不同的配置文件吗?这样不是很麻烦并且非常不合理吗?目前比较流行的集群部署方案是Kubernetes、Docker-Swarm、Docker-Compose,这三种方案对比,Kubernetes学习难度大,但是可解决的场景非常多,而Swarm是Docker官方推荐的轻量级集群部署工具,并且Docker 1.12以上版本已经集成了Swarm,不过相对于kubernetes没有那么多的解决方案但是上手简单,一周就可以轻松掌握。这里我结合项目组实际情况,选择Swarm来作为自动化集群部署工具。
一、Swarm简介
Swarm是Docker官方提供的一款集群管理工具,其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口统一管理这些Docker主机上的各种Docker资源。Swarm和Kubernetes比较类似,但是更加轻,具有的功能也较kubernetes更少一些。
Swarm的基本架构如下图所示,
这个图作为一个整体实际上都处于一个所谓的集群中,它可能对应了一到多台的实际服务器。每台服务器上都装有Docker并且开启了基于HTTP的DockerAPI。这个集群中有一个SwarmManager的管理者,用来管理集群中的容器资源。管理者的管理对象不是服务器层面而是集群层面的,也就是说通过Manager,我们只能笼统地向集群发出指令而不能具体到某台具体的服务器上要干什么(这也是Swarm的根本所在)。至于具体的管理实现方式,Manager向外暴露了一个HTTP接口,外部用户通过这个HTTP接口来实现对集群的管理。对于稍微大一点的集群,最好是拿出一台实际的服务器作为专门的管理者,作为学习而言,也可以把管理者和被管理者放在一台服务器上。
二、准备工作
本文是基于SpringCloud实战(九)-容器自动化部署与持续集成(Docker)工程的基础上进行的改造,所以在阅读本文之前读者需要基于前文搭建单点自动化部署环境。
三、Swarm安装
Docker 1.12及以上版本已将swarm内置到了Docker Engine中,所以你只需要安装Docker 1.12以上版本的就直接自带swarm,Docker安装传送门双手奉上:
Docker集群管理需要服务发现(Discovery service backend)功能.Swarm支持以下几种discovery service backend:Docker Hub上面内置的服务发现功能,本地的静态文件描述集群(static file describing the cluster),etcd(顺带说一句,etcd这玩意貌似很火很有前途,有时间研究下),consul,zookeeper和一些静态的ip列表(a static list of ips).本文会详细介绍前面两种方法backend的使用。
到此swarm配置完成(其实也没配置什么)。
二、管理节点(Master)
节点分为管理节点和工作节点。
管理节点用于Swarm集群的管理,docker swarm命令基本只能在管理节点执行。一个Swarm集群可以有多个管理节点,但只能有一个管理节点可以成为leader,leader通过raft协议实现。
工作节点是任务执行节点,管理节点将服务(service)下发给工作节点执行、管理节点默认也作为工作节点。
首先我们需要初始化一个swarm集群,然后将节点添加到集群中,我们就可以在集群里创建服务。
1、初始化群组
$ docker swarm init --advertise-addr 192.168.3.206
该命令执行完成后,会自动将该节点加入到swarm集群。这个命令会创建一个集群token,作为集群唯一标识。
后续将其他节点加入集群都会用到这个token值。其中,–advertise-addr参数表示其它swarm中的worker节点使用此ip地址与manager联系,图示如下:
2、添加集群节点
docker swarm join --token SWMTKN-1-4rrfljgbpv43mbbrbn23jnhzvs8cmommfqioinnb94632hnae9-dvcuwhl5mpixh28of550rvpby 192.168.3.206:2377
根据上图中给出的命令去添加节点到集群中,当前的192.168.3.206节点在上一步的初始化命令已经添加成功了,这里如果要添加其他节点到集群中只需要更换一下命令中的ip就可以了。
3、查看集群节点
$ docker node ls
通过上述命令我们就可以查看到刚才添加到集群组的节点了,图示如下:
此时我们发现hostname是ubuntu,如果我们再添加一个ubuntu系统的节点,我们就会傻傻分不清两个节点分别对应的是什么服务,所以我们需要修改主机名来区分。
$ hostnamectl set-hostname applicationserver
$ echo -e "192.168.3.206\tApplicationServer\n127.0.0.1\tApplicationServer" >> /etc/hosts
echo -e的意思是要求处理特殊字符,还有一种写法是echo -n,它的意思是不换行输出。
注意你需要打开2377端口,每个节点都需要打开,开启端口可以参照下面这篇文章
或者你也可以直接关闭防火墙
systemctl stop firewalld
setenforce 0
到这里我们就成功创建了一个swarm集群。
三、工作节点(Worker)
1、创建节点
docker swarm join --token SWMTKN-1-4rrfljgbpv43mbbrbn23jnhzvs8cmommfqioinnb94632hnae9-dvcuwhl5mpixh28of550rvpby 192.168.3.206:2377
首先我们要连接到到192.168.3.202去执行加入集群的命令,此时192.168.3.202自动作为一个工作节点加入集群
上图就说明我们已经将192.168.3.202加入之前的集群里了。
2、查看节点
$ docker node ls
我们可以切换到master节点上去查看我们刚刚创建的节点,图示如下:
此时的bogon节点就是我们刚刚添加的worker节点了。
四、部署服务
首先我们准备好上文中改造好的eureka-server工程,如果大家上一篇文章还没有看,最好会去看一下,此时我在192.168.3.206节点上已经存在之前构建好的eureka-server镜像了,通过以下命令可以查看
$ docker images
然后我们看一下正在运行的容器有没有占用8761端口
$ docker ps
如果占用了就将容器停止一下
$ docker stop eureka-server
然后我们就可以执行下面的命令,将eureka-server部署为3个实例的集群。
$ docker service create --mount type=bind,src=/usr/local/logs,dst=/usr/local/logs --replicas 3 -p 8761:8761 --name eureka-server 192.168.3.202:8088/oascloud/eureka-server
启动完成的图示如下:
然后我们通过以下命令查看服务部署情况
$ docker service ls
$ docker service ps eureka-server
$ docker service logs eureka-server
部署情况图示如下:
上图说明我们已经成功将eureka-server的三个实例部署到两台机器上了,此时我们访问 http://192.168.3.206:8761/,浏览器效果图如下:
说明部署成功了,同时我们也可以通过swarm提供给我们的命令调整副本部署数量
$ docker service scale eureka-server=4
这样的话我们的副本就平均部署到两台机器上了
swarm还提供了其他的命令
1、不间断滚动升级服务
$ docker service update --image xiaopeng163/python-flask-demo:2.0 web
2、变更节点角色
$ docker node update xx --role worker
3、离开集群
$ docker swarm leave -f
4、删除节点
$ docker node rm eureka-server
5、删除服务
$ docker service rm eureka-server
注意:所有命令的执行都是基于master和worker所在节点的docker版本一致的大前提下进行的,否则会出现各种异常问题,这里我遇到的问题就是在删除服务的时候,master上的容器可以正常删除,而worker上的容器不能删除,最后我发现是因为两台机器的docker版本不一样,一个是18.09.6,一个是1.13.0,大家这里特别注意一下。
更多的命令我们可以通过--help来查看,图示如下:
我们具体需要用到啥命令的时候再去详细了解一下就可以了,不需要死记硬背。
五、Jenkins自动化集群部署
自动化部署比较简单,首先关闭selinux
$ setenforce 0
然后改掉之前Jenkins远端shell脚本
docker service rm eureka-server
docker rmi 192.168.3.202:8088/oascloud/eureka-server | true
docker pull 192.168.3.202:8088/oascloud/eureka-server
docker service create --update-delay 10s --mount type=bind,src=/usr/local/logs,dst=/usr/local/logs --replicas 2 -p 8761:8761 --name eureka-server 192.168.3.202:8088/oascloud/eureka-server
点击构建,图示如下:
还有一种是通过docker-compose文件启动集群的方式,我还需要再研究一下。