Docker管理工具之Swarm


【编者的话】本文首先介绍了Swarm结构及主要命令,然后介绍了如何简单的把Swarm跑起来并使用。接着分析了Swarm最重要的3个技术点:Discovery、Filter和Strategy。最后给出了作者学习Swarm过程中想到或遇到的一些问题。

一、架构解析

swarm架构图如下,参考自宏亮同学的深入浅出Swarm
YRG](NX[FK24EWSXFU~ZVY0.png

Swarm目前主要支持4种命令:swarm create、swarm manage、swarm join和swarm list。

swarm create
  • 用于创建一个集群标志。发起该命令之后,Swarm会前往Docker
    Hub上内建的发现服务中获取一个全球唯一的token,用以唯一的标识Swarm管理的Docker集群。
  • 该命令只用于token模式下。Token发现服务内建于Docker Hub,该服务发现机制目前还在alpha版本,站点为:http://discovery-stage.hub/docker.com
  • 其实这个cluster id也可以自己随意指定。当然这样有可能会出现冲突的情况,只适用于测试。


swarm manage
  • swarm manage是该最为重要的管理命令。请求入口为Api Server,调度引擎为Scheduler,服务发现依靠Discovery。
  • Api Server就是一个http server,主要用于监听请求,处理并路由。
  • Scheduler主要用于调度出一个可用的node去创建container。它依赖于两个核心组件filter、strategy。
  • filter目前提供了5种过滤器:constraint、affinity、health、port、 dependency。默认都使用。
  • strategy目前提供了2种放置策略:binpack、random。默认使用binpack。
  • Discovery是Swarm用于维护Docker集群状态的机制。目前提供了6种discovery机制:token(默认)、node、file、consul、etcd、Zookeeper。


Swarm manage逻辑如下:
  1. 初始化scheduler调度模块。依据所有node状态以及具体信息,filter出满足要求的nodes,并通过一定的strategy得出一个最终的node。
  2. 初始化cluster。Swarm通过一定的discovery发现机制,发现所有注册的node,收集所有node的状态以及具体信息,并通过一个定时任务定期heatbeat更新。
  3. 初始化API监听服务模块并开始监听。


docker -H ${swarm_ip:swarm_port} run逻辑如下:
  1. filter。用filters层层过滤,最终过滤出一批满足所有要求的nodes。
  2. strategy。用一定的strategy,通过随机或权重计算并排序,得出一个最终的node。
  3. create。调用docker remote api,在这个node上创建container,并更新内存维护的node元信息。


参考


二、部署运行

环境要求
  • docker version 1.5.0 or later;
  • configured to listen to a tcp port that the Swarm manager can access;


编辑/etc/sysconfig/docker,添加-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock到OPTIONS
stop firewalld;

构建Docker集群(基于token发现后端)

1)添加节点到集群
docker run -d swarm join --addr=10.13.131.27:2375 token://cluster1

2)开启swarm manager(任意一台机器,这里使用10.13.131.22)
docker run -d -p 8888:2375 swarm manage token://cluster1

3)查看集群节点列表
docker run --rm swarm list token://cluster1

4)使用docker cli
docker -H 10.13.131.22:8888 info
docker -H 10.13.131.22:8888 ps
docker -H 10.13.131.22:8888 run --name swarm_test registry.docker.sce.sina.com/centos:6 /bin/bash -c "echo hello ..."
docker -H 10.13.131.22:8888 stats <container>
docker -H 10.13.131.22:8888 rename <container>


参考


三、Discovery backends用法

token
swarm join --addr=<node_ip:2375> token://<cluster_id>
swarm manage token://<cluster_id>

static list of ips
swarm manage nodes://<node_ip1:2375>,<node_ip2:2375>
or swarm manage <node_ip1:2375>,<node_ip2:2375>

file
echo <node_ip1:2375> >> /tmp/my_cluster
echo <node_ip2:2375> >> /tmp/my_cluster
echo <node_ip3:2375> >> /tmp/my_cluster
swarm manage file:///tmp/my_cluster

etcd
swarm join --addr=<node_ip:2375> etcd://<etcd_ip>/<path>
swarm manage etcd://<etcd_ip>/<path>

consul
swarm join --addr=<node_ip:2375> consul://<consul_ip>/<path>
swarm manage consul://<consul_ip>/<path>

zookeeper
swarm join --addr=<node_ip:2375> zk://<zk_ip1>,<zk_ip2>/<path>
swarm manage zk://<zk_ip1>,<zk_ip2>/<path>

参考


四、Filter解析

过滤器用途:过滤出若干符合要求的nodes。支持的5个filter:Constraint、Affinity、Port、Dependency、Health
使用方法:Swarm manage --filter。不指定--filter默认会使用所有filter。

Constraint Filter
用途:过滤出来符合指定属性的node。

使用场景:
  • 指定node属性(如:storage=ssd)
  • 指定node物理位置(如:region=bx)
  • 指定集群类型(如:env=production)


使用案例一:
docker -d --label storage=ssd # restart node1 docker daemon
docker -d --label storage=sata # restart node2 docker daemon
docker -H 10.13.131.22:8888 run --name mysql -d -P -e constraint:storage==ssd mysql #start a mysql server and make sure it gets good I/O performance
docker -H 10.13.131.22:8888 run --name apache -d -P -e constraint:storage==sata apache #start a apache server and make sure it gets common I/O perf
docker ps

Affinity Filter

用途:过滤出来container所在node/过滤出来已pull下来指定image的node。
使用案例一:
docker -H 10.13.131.22:8888 run --name app-apache -d -P apache
docker -H 10.13.131.22:8888 run --name app-mysql -d -P -e affinity:container==app-apache mysql

使用案例二:
docker -H node1:2375 pull mysql
docker -H node2:2375 pull apache
docker -H 10.13.131.22:8888 run --name mysql1 -d -P -e affinity:image==mysql mysql
docker -H 10.13.131.22:8888 run --name mysql2 -d -P -e affinity:image==mysql mysql
docker -H 10.13.131.22:8888 run --name mysql3 -d -P -e affinity:image==mysql mysql
docker ps

注意:constraint filter和affinity filter支持表达式模式匹配。

支持的操作符:==和!=。例子如下:
constraint:node==node1 匹配node1
constraint:node!=node1 匹配除node1外所有节点
constraint:region!=bx* 匹配所有以bx开头的region
constraint:node==/node-[12]/ 匹配node-1和node-2

Port Filter

用途:过滤出port可用的node。
使用案例:
docker -H 10.13.131.22:8888 run --name apache -d -p 80:80 apache #比如这次创建在了node1上
docker -H 10.13.131.22:8888 run --name apache -d -p 80:80 apache #这次肯定不会创建在node1上
docker -H 10.13.131.22:8888 run --name apache -d -p 80:80 apache #如果所有node的这个80port资源都已使用,则创建失败

Dependency Filter

用途:过滤出依赖container所在的node,将这些有依赖的container创建在一个node上。

被视为有依赖的情况:
  • Shared volumes: --volumes-from=dependency
  • Links: --link=dependency:alias
  • Shared network stack: --net=container:dependency


Health Filter

用途:过滤出healthy node

参考:


五、Strategies解析

放置策略用途:选出一个最终的node。支持的2个strategy:binpack、random。使用方法:swarm manage --strategy。不指定--strategy默认会使用binpack。

Random Stragegy

用途:随机选择一个。

Binpack Strategy

用途:从cpu、memory两方面计算node权重,排序并取出权重最大的那个node。

参考:


六、FAQ

1. Token模式下,docker node的注册信息存在哪了?

存在Docker Hub上了。Token发现服务内建与Docker Hub,目前还在alpha版本,地址是:http://discovery-stage.hub/docker.com 。Docker node的一次注册,仅仅是将自己的ip地址及端口号注册进backend。

2. Token模式下,Docker node的健康状态及lable等信息存储在哪了?

由Swarm master调用docker remote API获取,在内存中维护一个cluster集群节点数组,并由一个watch定时器定期heatbeat更新。cluster里的每一个node,都维护了三类元信息:id、name、cpus、memory、lables等元信息;containers列表;images列表;

3. swarm join接口为什么要实现为无限循环d.Register(addr)?
4. binpack strategy的weighNodes接口实现中,node cpu权重为什么要用cpushare去计算?
5. swarm manage没有指定--host的情况下,host默认值是什么?

host默认是tcp://127.0.0.1:2375(在flags.go里面定义的)

参考

6 个评论

从其他地方拿图过来的时候呢,最好把参考出处标明,比如说第一张图
谢谢指正,已更新
请按照DockerOne的格式来发布文章,有问题私信我哈。
谢谢指正,已更新
谢谢,o(∩_∩)o
东西不错。收了。呵呵

要回复文章请先登录注册