使用Swarm进行Docker集群的部署
作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处:https://andyyoung01.github.io/ 或 http://andyyoung01.16mb.com/
如果你有很多主机,并且这些主机上都安装了Docker,则需要有一种方法来管理这些主机上的容器。比如说启动一个容器时,如何选择容器运行的主机,容器启动后怎样访问部署在某台主机上的容器。Swarm是为了解决这些问题而开发的。在一个有很多主机的集群中,使用Swarm可以将这些机器看做一个Docker daemon,并且像运行普通Docker命令那样使用。
使用Swarm管理容器集群,可以使你不必关心某个容器应该启动在某台主机上,Swarm通过其调度策略自动选择出最合适的主机来运行容器(当然也可以手动指定约束条件来限制容器启动在某台主机上)。Docker Swarm由三部分组成:agents,a discovery service和master。下图说明了在一个有3个主机节点的docker集群上,这三个部分是如何交互的:
在每台想要加入Swarm集群的主机上,都运行了一个agent,它是一个程序,发送连接信息到master上的discovery service,从而将该主机变为Docker Swarm集群中的节点。每台安装了agent的主机都需要将Docker daemon的端口开放到网络上(默认的端口号为2375),而不是使用本地的socket。当master启动后,它将与discovery service进行通信,来查找集群中的节点。从那时开始,你可以直接连接到master上,针对集群运行命令,而master会将请求发送到一个通过调度算法选定的agent上。
在Swarm集群中的Docker程序版本最少需要1.4.0版。默认情况下Swarm集群中只有一个master。如果需要集群中的master高可用,可以参考Docker的文档(https://docs.docker.com/swarm/multi-manager-setup/)。
在实验环境下,可以通过sudo /usr/bin/docker daemon -H 0.0.0.0:2375
命令将Docker daemon的端口开放到网络上,虽然这样做有严重的安全问题,但为了理解swarm的部署并且为了简单起见,可以暂时这样做一下;在生产环境中禁止这样做,在生产环境中需要启用tls的安全认证。
部署Swarm集群的第一步是选择将要使用的discovery service。有几种方式可以选择:从存储在文件中的IP地址列表到使用ZooKeeper,或者是使用Docker Hub提供的服务发现机制。这里我们选择內建到Docker Hub里的discovery Service,它是通过使用tokens实现的。
Swarm的服务发现机制 - Swarm可以使用很多方法实现服务发现。可以把节点注册到Docker Hub discovery service上,是Swarm提供的一个便利的方式,为了可以快速部署集群。如果你不习惯于将你集群中节点的IP地址存储在一个潜在的公共服务上,可以选择其他的方式。详细信息可以参考https://docs.docker.com/swarm/discovery/。
Docker Hub的discovery Service需要你通过命令行取得一个token来标识你的集群。所以在创建集群时,需要有能访问到Docker Hub的外网连接。下面我们就从头搭建一个Docker Swarm集群。本示例使用了三台主机,一个master和两个agent。机器名分别为centos7(master),centos7-A(agent),centos7-B(agent),IP地址分别为192.168.71.131,192.168.71.167,192.168.71.168。
Swarm的可执行程序是以docker镜像的形式提供的,所以在master上可以使用如下命令创建集群:
上面最后swarm create命令返回的长字符串就是用于标识你的集群的标识符。它非常重要,后面其它机器加入集群都需要使用它,请记下来!下面可以检查一下新创建的集群:
这两条命令是等效的,都用来检查集群中所包括的节点。正如你所看到的,现在还没有机器加入集群,所以命令的结果没有任何内容,swarm list命令没有返回任何数据,curl命令返回了一个空列表。这里curl命令直接查询了Docker Hub的Discovery Service,绕过了swarm提供的方法。
下面在centos7-A主机上启动第一个agent,如下:
在加入集群的命令行参数中,-H参数指定docker命令发送到本机的2375端口上,这是因为前面通过sudo /usr/bin/docker daemon -H 0.0.0.0:2375
命令将Docker daemon的端口开放到网络上了; addr参数指定了master用来连接agent的IP地址及端口;token参数指定了集群所使用的标识符。
在master主机上再次查询集群中的节点列表:
可见centos7-A主机的ip已经加入到了集群中,master会使用此ip地址和端口号连接该主机上的docker daemon。前面在master上创建了集群,但是还没有启动管理容器对集群进行管理,下面就需要在master节点上运行swarm manage来管理集群:
上面第1行命令启动了master节点上的swarm manage容器,并且将该容器的端口映射到主机的相同端口上;第3行的命令使用了-H的命令行参数,使得docker命令连接到swarm manage容器中运行info命令,从而得到的是swarm集群中的信息,而不是master主机上的本地docker信息。通过信息可知,现在集群中有一个agent加入了集群,这个agent的主机名是centos7-A,IP是192.168.71.167。
使用同样的方式,将centos7-B主机加入到集群中:
可见centos-B也加入了集群。注意,第二个命令在agent节点上远程连接到了master上的swarm manage容器中查询到了Swarm集群的信息。
最后,通过Swarm启动一个容器,Swarm根据自己的调度算法自动选择一个主机来运行容器:
通过上面输出的容器名,可以知道Swarm自动选择了centos7-B主机来启动容器。这样就完成了整个Swarm集群的部署,并且使用Swarm运行了一个容器。