Docker Swarm Mode简介

2,133 阅读6分钟

在上一篇文章中我们介绍了如何通过compose来定义并运行一组service(容器),如果是在分布式的应用场景中,通常会有一个集群的概念,即在集群中部署并管理我们的应用程序。同样的Docker也提供了相应的模式来管理我们的一组容器,即Swarm Mode。

从Docker 1.12开始Swarm mode已经内嵌入了Docker引擎中,成为了docker的子命令docker swarm,不再需要我们单独去安装Docker Swarm。Swarm使用SwarmKit构建,是Docker引擎内置(原生)的集群管理和编排工具。提供了对Docker容器集群的管理服务。在开始动手实践之前让我们先来了解几个概念。

节点(Node)

之前做过分布式开发和部署的小伙伴对节点的概念一定不会陌生。在分布式开发和部署中我们管一台服务器称为一个节点。同样的在Docker Swarm Mode中也有节点的概念。运行Docker的主机可以主动初始化一个Swarm集群或者加入一个已存在的Swarm集群,这样这个运行Docker的主机就成为一个Swarm集群的节点(node)。

节点分为管理(manager)节点和工作(worker)节点。

管理节点用于Swarm集群的管理,工作节点是任务执行节点,管理节点将服务(service)以任务(task)的形式下发至工作节点执行。管理节点默认也作为工作节点。引用docker官网的图片来展示集群中管理节点与工作节点的关系,如下图所示:


服务(Service)和任务(Task)

任务(Task): 是Swarm中最小的调度单位,可以把他理解成一个单一的容器。

服务(Services): 是一组任务的集合,服务定义了任务的属性。服务有两种模式:

replicated services: 按照一定规则在各个工作节点上运行指定个数的任务。

global services: 每个工作节点上运行一个任务。

下方来自Docker官网的图片形象的展示了容器,任务,服务的关系, 如图所示:



开启Swarm集群

docker内置了docker swarm的相关指令,我们可以通过docker swarm init来开启swarm集群,如下图所示:


执行docker swarm init命令的节点会自动成为管理节点。

注意: 如果你的docker主机有多个网卡,拥有多个IP,需要在docker swarm init后面加入

--advertise--addr,以指定被监听的ip和port,以便其他节点可以加入到集群中。

这样就创建了一个单节点的集群,我们可以通过指令docker node ls来查看集群中的节点信息,如图所示:


向集群中部署服务

单节点集群已经创建好,接下来我们来看如何向集群中部署服务,上篇文章中我们讲到通过compose file部署启动多个容器,同样在Swarm中我们也可以使用compose文件来配置,启动多个服务。我们继续使用上节课的docker-compose.yml文件,并在文件中加入一些部署相关的信息,新的文件内容如下图所示:


红色框中是我们新添加的节点信息:

deploy节点定义了service(包含某个业务功能的镜像或docker容器)的部署策略,replicas表示在docker集群的节点中运行2个服务实例(容器实例),具体在哪些节点运行由docker内部进行分配,limits限制了每个实例所使用的最大cpus为10%,最大memory为50MB RAM,并设置服务实例的重启机制为一旦某个容器发生故障,则立即重启容器。

现在让我们在创建的单节点集群中部署这组服务。docker提供了docker stack deploy指令来利用compose文件部署服务,让我们进入到docker-compose.yml所在的文件夹,并执行如下指令:docker stack deploy -c docker-compose.yml servicestacklab ,结果如图所示:


该指令所表达的意思是通过执行docker-compose.yml文件中的脚本来创建一个名为servicestacklab的stack的服务组。我们可以通过指令docker stack ls来查看当前swarm中有哪些stack服务组,结果如图所示:


我们可以看到在当前的swarm中只有一个名为servicestacklab的服务组,并且这个服务组中只有一个service。

我们可以通过执行docker stack services 指令来查看stack中有哪些服务,执行指令docker stack services servicestacklab,结果如图所示:


service的命名规则为:stackname_servicename, stackname为我们docker stack deploy中定义的servicestacklab,servicename是我们compose文件中定义的每一个service的name,在该实例的compose文件中我们只定义了一个名为weblab的service,因此最终的服务名称为servicestacklab_weblab, 可以参照上方compose file内容的截图。

上面我们提到过,管理节点将服务(service)以任务(task)的形式下发至工作节点执行,在我们的部署策略中我们设置的在每个node中部署一个服务的两个task,那么我们可以通过指令docker service ps servicename来查看一个服务的task情况,指令为docker service ps servicestacklab_weblab, 结果如图所示:


我们可以看到在node名为linuxkit-00155d6f91aa的节点上以task的形式运行了两个servicestacklab_weblab服务的实例,task的名为servicestacklab_weblab.1和servicestacklab_weblab.2。

我们通过docker ps -a指令来查看当前运行的容器实例信息,结果如图所示:


可以看到当前有两个正在运行的容器,大家记住这两个容器实例的ContainerID分别为:

037776ed23d3和9f3fcf0ba7d9

接下来,我们通过在文件中暴露的5000端口来访问这个服务:http://localhost:5000,在页面中我打印出了当前machine的name(即container的id),我们多刷新几次页面查看MachineName的变化,得到如下两张图:





可以发现Swarm为我们实现了服务访问的负载均衡。除了负载均衡之外,Swarm mode还内置了服务发现,路由网格,动态伸缩,滚动更新,安全传输等功能。大家在听说docker的同时也一定听说过Kubernetes,Swarm Mode与Kubernetes类似,K8S也提供了对docker集群管理的相关功能,后期会找时间为大家介绍一下如何通过K8S来管理Docker集群。

本篇文章我们就介绍到这里,希望能让大家对Docker的Swarm Mode有一定的了解,下一篇文章会为大家讲解如何在单台机器上实现包含多docker主机的集群,以实现模拟在多docker主机之间的分布式部署。


相关资料:

yeasy.gitbooks.io/docker_prac…


上一篇(Docker Compose介绍)

下一篇(单主机上实现多Docker虚拟主机的创建和服务部署)