Docker Swarm学习教程
原创作品,转载请注明出处:点我
Swarm介绍
Swarm是Docker公司在2014年12月初发布的一套较为简单的工具,用来管理Docker集群,它将一群Docker宿主机变成一个单一的,虚拟的主机。Swarm使用标准的Docker API接口作为其前端访问入口,换言之,各种形式的Docker Client(dockerclient in go, docker_py, docker等)均可以直接与Swarm通信。Swarm几乎全部用Go语言来完成开发,上周五,4月17号,Swarm0.2发布,相比0.1版本,0.2版本增加了一个新的策略来调度集群中的容器,使得在可用的节点上传播它们,以及支持更多的Docker命令以及集群驱动。
Swarm deamon只是一个调度器(Scheduler)和路由器(router),Swarm自己不运行容器,它只是接受docker客户端发送过来的请求,调度适合的节点来运行容器,这意味着,即使Swarm由于某些原因挂掉了,集群中的节点也会照常运行,当Swarm重新恢复运行之后,它会收集重建集群信息。下面是Swarm的结构图:


如何使用Swarm
有3台机器,sclu083,IP地址是10.13.181.83,sclu084,IP地址是10.13.181.84,atsg124 ,IP地址是10.32.105.124,利用这三台机器创建一个Docker集群,其中sclu083同时充当swarm manager管理集群.
Swarm安装
最简单的安装Swarm的方式就是用Docker官方提供的Swarm镜像:
sudo docker pull swarm
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进行集群管理之前,需要先把准备加入集群的所有的节点的docker deamon的监听端口修改为0.0.0.0:2375,可以直接使用 sudo docker –H tcp://0.0.0.0:2375 &命令,也可以在配置文件中修改
sudo vim /etc/default/docker
在文件的最后面添加下面这句
D0OCKER_OPTS=”-H 0.0.0.0:2375 –H unix:///var/run/docker.sock”

注意:一定是要在所有的节点上进行修改,修改之后要重启docker deamon
sudo service docker restart
第一种方法:使用Docker Hub上面内置的服务发现功能
第一步:在任何一台节点上面执行swarm create命令来创建一个集群标志。这条命令执行完毕之后,swarm会前往Docker Hub上内建的发现服务中获取一个全球唯一的token,用以唯一的标识swarm管理的Docker集群。
sudo docker run –-rm swarm create
我们在sclu084 这台机器上执行上面的命令,效果如下:

返回的token是d947b55aa8fb9198b5d13ad81f61ac4d,这个token一定要记住,因为接下来的操作都会用到这一个token。
第二步:在所有的要加入集群的机器上面执行swarm join命令,把机器加入集群
本次试验就是要在所有的三台机器上执行命令:
sudo docker run –-rm swarm join –addr=ip_address
:2375 token://d947b55aa8fb9198b5d13ad81f61ac4d
在IP地址为10.13.181.84机器上面执行的效果如下图:

执行这条命令后不会立即返回 ,我们手动通过Ctrl+C返回。
第三步:启动swarm manager
因为我们是要让sclu083充当Swarm管理节点,所以我们要在这条机器上面执行swarm manage这条命令:
sudo docker run –d –p 2376:2375 swarm manage token:// d947b55aa8fb9198b5d13ad81f61ac4d
需要注意的是:在这条命令中,第一:要以daemon的形式运行swarm。第二:端口映射:2376可以更换成任何一个本机没有占用的端口,一定不能是2375。否则就会出问题。
执行结果如下如所示:

执行完这个命令之后,整个集群已经启动起来了。
现在可以在任何一台节点上查看集群上的所有节点了。

之后可以在任何一台安装了docker的机器上面通过命令(命令中要指明swarm maneger 机器的IP地址和端口)在这个集群上面运行Dcoker容器操作。
现在在10.13.181.85这台机器上面查看集群的节点的信息。info命令可以换成任何一个Swarm支持的docker命令,这些命令可以查看官方文档
sudo docker –H 10.13.181.83:2376 info

由上图的结果,我们可以发现一个问题:明明这个小集群中是有3个节点的,但是info命令只显示了2个节点。还缺少节点10.32.105.124。为什么会出现这个情况呢?
因为10.32.105.124这台机器没有设置上面的docker daemon监听0.0.0.0:2375这个端口,所以Swarm没办法吧这个节点加入集群中来。
在使用Docker Hub内置的发现服务时,会出现一个问题,就是使用swarm create时会出现
time="2015-04-21T08:56:25Z" level=fatal msg="Get https://discovery-stage.hub.docker.com/v1/clusters/d947b55aa8fb9198b5d13ad81f61ac4d: dial tcp: i/o timeout"
类似于这样的错误,不知道是什么原因,有待解决。
当使用Docker Hub内置的服务发现功能出现问题时,可以使用下面的第二种方法。
第二种方法:使用文件
第二种方法相对而言比第一种方法要简单,也更不容易出现timeout的问题。
第一步:在sclu083这台机器上新建一个文件,把要加入集群的机器的IP地址写进去

第二步:在sclu083这台机器上面执行swarm manage命令:
sudo docker run –d –p 2376:2375 –v $(pwd)/cluster:/tmp/cluster swarm manage file:///tmp/cluster

注意:这里一定要使用-v命令,因为cluster文件是在本机上面,启动的容器默认是访问不到的,所以要通过-v命令共享。还有,file:///千万不能忘记了
可以看到,swarm已经运行起来了。现在可以查看下集群节点信息了,使用命令:
sudo docker run –rm –v $(pwd)/cluster:/tmp/cluster swarm list file:///tmp/cluster

(在使用文件作为服务发现的时候,貌似manage list命令只能在swarm manage节点上使用,在其他节点上好像是用不了)
好了,现在集群也已经运行起来了,可以跟第一种方法一样在其他机器上使用集群了。同样在sclu085 机器上做测试:

可以看到,成功访问并且节点信息是正确的。接下来可以把上面的info命令替换成其他docker可执行命令来使用这个晓得Docker集群了。
Swarm调度策略
Swarm在schedule节点运行容器的时候,会根据指定的策略来计算最适合运行容器的节点,目前支持的策略有:spread,binpack,random.
Random顾名思义,就是随机选择一个Node来运行容器,一般用作调试用,spread和binpack策略会根据各个节点的可用的CPU,RAM以及正在运行的容器的数量来计算应该运行容器的节点。
在同等条件下,Spread策略会选择运行容器最少的那台节点来运行新的容器,binpack策略会选择运行容器最集中的那台机器来运行新的节点(The binpack strategy causes Swarm to optimize for the container which is most packed.)。
使用Spread策略会使得容器会均衡的分布在集群中的各个节点上运行,一旦一个节点挂掉了只会损失少部分的容器。
Binpack策略最大化的避免容器碎片化,就是说binpack策略尽可能的把还未使用的节点留给需要更大空间的容器运行,尽可能的把容器运行在一个节点上面。
Constraint Filter
通过label来在指定的节点上面运行容器。这些label是在地洞docker daemon时指定的,也可以卸载/etc/default/docker这个配置文件里面。
sudo docker run –H 10.13.181.83:2376 run –name redis_083 –d –e constraint:label==083 redis
Affinity Filter
使用-e affinity:container==container_name / container_id –-name container_1可以让容器container_1紧挨着容器container_name / container_id执行,也就是说两个容器在一个node上面执行(You can schedule 2 containers and make the container #2 next to the container #1.)
先在一台机器上启动一个容器
sudo docker -H 10.13.181.83:2376 run --name redis_085 -d -e constraint:label==085 redis
接下来启动容器redis_085_1,让redis_085_1紧挨着redis_085容器运行,也就是在一个节点上运行
sudo docker –H 10.13.181.83:2376 run –d –name redis_085_1 –e affinity:container==redis_085 redis
通过-e affinity:image=image_name命令可以指定只有已经下载了image_name的机器才运行容器(You can schedule a container only on nodes where the images are already pulled)
下面命令在只有redis镜像的节点上面启动redis容器:
sudo docker –H 100.13.181.83:2376 run –name redis1 –d –e affinity:image==redis redis
下面这条命令达到的效果是:在有redis镜像的节点上面启动一个r名字叫做redis的容器,如果每个节点上面都没有redis容器,就按照默认的策略启动redis容器。
sudo docker -H 10.13.181.83:2376 run -d --name redis -e affinity:image==~redis redis
Port filter
Port也会被认为是一个唯一的资源
sudo docker -H 10.13.181.83:2376 run -d -p 80:80 nginx
执行完这条命令,任何使用80端口的容器都是启动失败。
结束语:
本文详细介绍了两种方法来使用Swarm管理Docker集群。但是Swarm是一个比较新的项目,目前还处于研发阶段,Swarm的发展十分快速,功能和特性的变更迭代还非常频繁。因此,可以说Swarm还不推荐被用于生产环境中,但可以肯定的是Swarm是一项很有前途的技术。
最近在学Go,准备抽时间好好研究下Swarm源码。Go是一门很有前途的语言。
参考资料:Docker官方文档
Docker Swarm学习教程的更多相关文章
- Docker Swarm学习教程【转载】
Swarm介绍 Swarm是Docker公司在2014年12月初发布的一套较为简单的工具,用来管理Docker集群,它将一群Docker宿主机变成一个单一的,虚拟的主机.Swarm使用标准的Docke ...
- [置顶]
Docker学习总结(5)——超实用Docker入门学习教程
Docker是什么 Docker是一种容器技术,它可以将应用和环境等进行打包,形成一个独立的,类似于iOS的APP形式的"应用",这个应用可以直接被分发到任意一个支持Docker的 ...
- Docker Toolbox 学习教程【转载】
最近在研究虚拟化,容器和大数据,所以从Docker入手,下面介绍一下在Windows下怎么玩转Docker.Docker本身在Windows下有两个软件,一个就是Docker,另一个是Docker T ...
- docker swarm学习命令
引用自:https://blog.csdn.net/wanglei_storage/article/details/77508620 引用自:https://www.cnblogs.com/wj563 ...
- Docker 三剑客之 Docker Swarm
上一篇:Docker 三剑客之 Docker Compose 阅读目录: Docker Machine 创建 Docker 主机 Docker Swarm 配置集群节点 Docker Service ...
- docker swarm英文文档学习-3-开始
https://docs.docker.com/engine/swarm/swarm-tutorial/ 1)Getting started with swarm mode 本教程向你介绍Docker ...
- docker swarm英文文档学习-5-在swarm模式中运行Docker引擎
Run Docker Engine in swarm mode在swarm模式中运行Docker引擎 当你第一次安装并开始使用Docker引擎时,默认情况下禁用swarm模式.在启用集群模式时,需要处 ...
- Docker swarm集群搭建教程
一.什么是Swarm Swarm这个项目名称特别贴切.在Wiki的解释中,Swarm behavior是指动物的群集行为.比如我们常见的蜂群,鱼群,秋天往南飞的雁群都可以称作Swarm behavio ...
- Docker集群管理(三)—— docker swarm mode基础教程
docker从1.12版(及后续版本)集成了swarmkit.可以方便的实现docker集群.它有哪些特点呢: 集成了集群功能 分散设计:manager和worker两种节点. 声明式服务模式 可伸缩 ...
随机推荐
- Java保存简单偏好的类
该类利用Preferences保存文本,数字等简单数据,在Windows平台下,它就保存到了系统注册表中,而Linux中它存在于用户目录下的一个隐藏文件中. public class Pref{ ...
- (剑指Offer)面试题58:二叉树的下一个结点
题目: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 思路: 考虑中序遍历的过程, 如果当前结点存在右子节点, ...
- C#基础视频教程7.5 如何编写简单游戏
有一些BUG需要处理,比如小鸟太高或者太低都应该报错(不然直接掉到窗口下面去了),这个方法跟前面的HitTest应该独立开来,而不是掺和在一起 测试确实可以检测是否超过边界(如果要非常精确,那么就 ...
- vue - 子路由-路由嵌套
描述:子路由,也叫路由嵌套,采用在children后跟路由数组来实现,数组里和其他配置路由基本相同,需要配置path和component,然后在相应部分添加<router-view/>来展 ...
- Python: Soft_max 分类器
我们能够建立例如以下的loss function: Li=−log(pyi)=−log⎛⎝efyi∑jefj⎞⎠ L=1N∑iLi+12λ∑k∑lW2k,l 以下我们推导loss对W,b的偏导数,我们 ...
- Android开发牛刀小试之“AA算钱软件”开发(一)
事实上想去做android开发已经有非常长一段时间了,可是因为还在上课,加上老板那边的项目接连不断.也一直都没有机会抽出身来做.可是,楼主当然也不会闲着,首先我了解到android开发须要java学习 ...
- Python线程指南(转)
1. 线程基础 1.1. 线程状态 线程有5种状态,状态转换的过程如下图所示: 1.2. 线程同步(锁) 多线程的优势在于可以同时运行多个任务(至少感觉起来是这样).但是当线程需要共享数据时,可能存在 ...
- C# 之 FTPserver中文件上传与下载(一)
近期接手这样一个文件上传到ftpserver的一个功能,接下来就给大家解析一下这一功能. 首先,今天我们要讲的是怎么创建一个FTPserver. 1.首先我们创建一个用户,当然不想创建 ...
- VS2010/MFC编程入门之四十四:定时器Timer
前面一节鸡啄米讲了CTime类和CTimeSpan类的使用,本节继续讲与时间有关的定时器.定时器并不是一个类,主要考虑到,提起时间的话就不能不说定时器,所以就把它放到CTime和CTimeSpan之后 ...
- mysql数据类型与运算符
一.数据类型 1.整型 MySQL数据类型 含义(有符号) tinyint(m) 1个字节 范围(-128~127) smallint(m) 2个字节 范围(-32768~32767) mediu ...