一、介绍
docker swarm是创建服务器集群的工具,只需要几条命令就可以创建一个服务器集群。它内置一些服务器集群需要的工具,比如说:服务查找,网络,负载均衡等等。
docker swarm
先初始化一个集群(docker swarm init
),然后让服务器加入到这个集群里面(docker swarm join
),这样就可以在这个集群服务器上面与创建服务(docker service create
),一个服务可以用一个或多容器来支持,容器之间会通过overlay网络类型进行通信。每一个服务器节点都知道这个集群里的其他服务器,如果某一个服务器节点出了问题,docker会将出了问题的服务器上面运行的容器,转移到集群里的其他服务器上面。我们不需要配置容器之间和服务器之间的负载均衡,因为它是docker swarm内置的功能。
二、集群
我在本地使用虚拟机创建了3个Linux系统的虚拟机,模拟三台服务器(node1[192.168.33.10], node2[192.168.33.11], node3[192.168.33.12])。
1. 创建集群 - swarm init##
首先进入到node1中,初始化一个集群:
docker swarm init --advertise-addr 192.168.33.10:2377
说明:192.168.33.10是node1的ip地址,--advertise-addr选项是设置监听的IP和端口号。执行完,看到提示「集群已经初始完,当前节点是管理员」表示初始化成功。后面还有添加woker节点的指示和命令。
docker swarm join \\
--token SWMTKN-1-6cqcc65jtfmldojryxg7s4rpljekcdrobz288mycgyu12gfxlf-bg27cxk75qhbgwjngxn500lqg \\
192.168.33.10:2377
初始化完,查看集群上节点的列表,可以执行:
docker node ls
目前只有node1一个节点,状态为Ready,是个Leader。
2. 添加服务器到集群里 - swarm join##
接着登录到node2中,执行初始化完成后返回的指令。
这里会提示「这个节点已作为worker加入到集群中」,再登录到node3,同样的也把它加入到集群中。
然后回到node1,查看集群的节点列表:
现在这个集群里一共有三个服务器。node1为管理员,node2,node3为worker。
3. 创建集群网络 - overlay##
在集群节点中运行的容器需要一种overlay类型的网络,我们可以先去创建一个overlay网络,然后在创建服务的时候使用这个网络。
docker network create --driver overlay skynet
可以看到新创建的网络skynet,类型为overlay。
4. Swarm - 状态的图形界面##
为了更好的理解集群,我们可以创建一个visualizer,可以即时的查看集群中服务器的状态和服务器上面运行容器的状态。
登录到manager node1上,执行:
docker run -itd -p 5000:5000 -e HOST=192.168.33.10 -e PORT=5000 -v /var/run/docker.sock:/var/run/docker.sock manomarks/visualizer
(这之前我已经pull过manomarks/visualizer的镜像)
打开浏览器,访问http://192.168.33.10:5000:
三、服务
1. 创建服务 - service create##
创建好集群服务器以后就可以创建服务了,创建服务可以执行:
docker service create --name web --network skynet --publish 3000:3000 --replicas 1 ninghao/node
创建一个名字叫web,网络使用刚刚创建的skynet,使用--publish
指定发布的端口号,这里的3000:3000是ninghao/node镜像里的nodejs应用使用的端口号,--replicas
指定需要的数量。
接着查看一下服务的列表:
docker service ls
刚创建完成的服务web,REPLICASE的值为0/1,表示正处于prepare的状态,还没正式运行。
查看服务的状态可以执行:
docker service ps web
等待状态变为Running的时候,在浏览器打开http://192.168.33.10:5000 就可以查看到新增的服务:
访问http://192.168.33.10:3000 :
2. 负载均衡 - load balancing##
现在我们已经在集群里创建一个web服务,服务现在只有一个容器,使用docker service ps web
可以查看到容器在node1机器上面。上面我们通过访问node1的ip:192.168.33.10:3000查看到页面,那么尝试访问node2(192.168.33.11)和node3(192.168.33.12)的3000端口看看。
你会发现虽然在node2和node3上没有容器运行那个应用,但还是可以打开页面,观察页面显示的Container ID是一样的,可见页面是同一个容器提供的服务。这就docker里面的routing mesh技术,而且还内置了负载均衡的功能。如果访问的服务器上没有提供服务的容器,那docker会重定向到有这个服务容器的机器上面。
3. 扩展服务 - service scale##
scale up一下web服务,现在这个服务只有一个容器,在node1上面执行:
docker service scale web=6
web表示服务名称,= 右边表示容器的数量,执行完,回到浏览器查看,会陆陆续续出现其他的5个容器,分别分布在3台机器上:
重新访问一下:http://192.168.33.10:3000 ,留意Container ID会有变化,现在同时使用多个容器提供服务:
scale可以增加容器,也可以减少容器。执行:
docker service scale web=3
现在每台服务器上都只有一个容器提供服务,总共3个容器。这是我们设置的web的状态,docker会维护这个状态,现在我们关闭node3的机器:
node3关闭后,它上面的容器也不见了,但过了一会,少了的容器,会出现在集群里其他机器上面。这里是跑到了node2上面:
更新服务 - service update
如果我们想要更新提供服务的容器中的一些信息,比如:端口、数据卷、镜像等等,可以使用:
docker service update [OPTIONS]
先scale up 到6个,下面我们更新一下服务使用的镜像:
docker service update web --image ninghao/node:hola
开始更新:
完成更新:
你会发现docker会使用我们指定的镜像去逐个逐个更新(旧版本好像会一次全部停掉,再逐个更新),新的容器创建好以后,我们再去浏览一下。
已更新,hello会变成hola。这个更新的动作过程我们可以指定,比如说想一次更新两个容器,每次更新的时候中间停几秒。这次换回原来的hello
docker service update web --image ninghao/node --update-parallelism 2 --update-delay 6s
--update-parallelism
指定每次更新的容器数。
--update-delay
指定容器更新的间隔。
执行的一开始会消失掉两个容器,随后更新完成两个容器后,会等待6秒,然后再更新两个。具体可以在http://192.168.33.10:5000 观察完整过程。