节点名称 相关服务 ip地址
master1/node1 swarm manager(master) / consul 192.168.132.131
master2/node2 swarm manager(backup),node1 192.168.132.133
node3 node2 192.168.132.134

下载镜像

Docker 官方已经提供了 Swarm 镜像使用,需要在所有被 Swarm 管理的 Docker 主机上下载该镜像。

$ docker pull swarm

#查看 Swarm 版本,验证是否成功下载 Swarm 镜像。
$ docker run --rm swarm -v
swarm version 1.2.8 (48d86b1)

注意:在使用Swarm进行集群管理之前,需要进行一些简单配置,添加 Docker daemon 的网络监听:

需要先把准备加入集群的所有的节点的docker deamon的监听端口修改为0.0.0.0:2375,可以直接使用 docker –H tcp://0.0.0.0:2375 &命令,也可以在配置文件(/etc/default/docker)中修改(添加:-H 0.0.0.0:2375 –H unix:///var/run/docker.sock")

centos7 配置文件路径 /lib/systemd/system/docker.service,修改完之后:

然后重启docker服务

[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl restart docker.service

启动集群

Docker 集群管理需要使用服务发现(Service Discover)功能,Swarm 支持以下的几种方式:DockerHub、本地文件、etcd、consel、zookeeper 和手动指定节点 IP 地址信息等。

本地配置集群推荐使用 consel 作为服务发现后端。利用社区提供的 Docker 镜像,整个过程只需要三步即可完成。

启动 Consel 服务后端(master端)

启动 consel 服务容器,映射到主机的 8500 端口。

$ docker run -d -p 8500:8500 --name=consul progrium/consul -server -bootstrap

获取到本地主机的地址作为 consul 的服务地址:<consul_ip>:8500

启动管理节点(master端)

首先,启动一个主管理节点,映射到主机的 4000 端口,并获取所在主机地址为 <manager0_ip>。其中 4000 端口是 Swarm 管理器的默认监听端口,用户也可以指定映射为其它端口。

#语法格式:
$ docker run -d -p 4000:4000 swarm manage -H :4000 --replication --advertise <manager0_ip>:4000 consul://<consul_ip>:8500 [root@localhost ~]# docker run -d -p 4000:4000 swarm manage -H :4000 --replication --advertise 192.168.132.131:4000 consul://192.168.132.131:8500
e9721e5895e27866762b825e67f40d27ed4820e7aed7d7442d639e50bd37cc51

为了提高高可用性,也可以启动从管理节点。假定获取所在主机地址为 <manager1_ip>

#语法格式与上面一样
$ docker run -d swarm manage -H :4000 --replication --advertise <manager1_ip>:4000 consul://<consul_ip>:8500 [root@localhost ~]# docker run -d swarm manage -H :4000 --replication --advertise 192.168.132.133:4000 consul://192.168.132.131:8500
9fde195d5a63667adfb42e49bebad72f2b4f0605c810f12dd60d23d05d73ad2a

启动工作节点

需要在每个工作节点上启动 agent 服务。获取节点的主机地址为 <node_ip>,并指定前面获取到的 consel 服务地址。

#语法格式
$ docker run -d swarm join --advertise=<node_ip>:2375 consul://<consul_ip>:8500 [root@localhost ~]# docker run -d swarm join --advertise=192.168.132.133:2375 consul://192.168.132.131:8500  #此处133 为工作节点ip
f0ab7702df27100d6c8dabef07456a78d5a8487eab6d0d49cb48c1c113dec57b

工作节点1(管理节点2)

工作节点2

工作节点3(管理节点1)

节点启动后,用户可以指定 Docker 服务地址为 <manager0_ip>:4000> 来测试各种 Docker 命令,可以看到整个 Swarm 集群就像一个虚拟的 Docker 主机一样正常工作。

由于 Swarm 实际上是通过 agent 调用了本地的 Docker daemon 来运行容器,当 Swarm 集群服务出现故障时,无法接受新的请求,但已经运行起来的容器将不会受到影响。

测试集群

查看所有的节点信息

在管理节点上使用 docker run 来启动若干容器,例如

[root@localhost ~]# docker -H 192.168.132.131:4000 run -d finance/centos6.8-base ping 127.0.0.1
add0667ac57f563b2e2a8db7d705255993b91dd76440577a18819a9d6ac9ba76
[root@localhost ~]# docker -H 192.168.132.131:4000 ps

会随机在某个docker宿主机上启动 一个容器

其他服务后端发现

使用中可以通过不同的路径来选择特定的服务发现后端机制。
token://<token>:使用 DockerHub 提供的服务,适用于可以访问公网情况;
file://path/to/file:使用本地文件,需要手动管理;
consul://<ip>/<path>:使用 consul 服务,私有环境推荐;

etcd://<ip1>,<ip2>/<path>:使用 etcd 服务,私有环境推荐;
zk://<ip1>,<ip2>/<path>:使用 zookeeper 服务,私有环境推荐;

[nodes://]<ip1>,<ip2>:手动指定集群中节点的地址,方便进行服务测试。

使用文件

使用本地文件的方式十分简单,就是将所有属于某个集群的节点的 Docker daemon 信息写入一个文件中,然后让 manager 从这个文件中直接读取相关信息。

首先,在 Swarm 管理节点(192.168.132.131)上新建一个文件,把要加入集群的机器的 Docker daemon 信息写入文件:

$ tee /tmp/cluster_info <<-'EOF'
192.168.132.133:2375
192.168.132.133:2375
192.168.132.134:2375
EOF

然后,本地执行 swarm manage 命令,并指定服务发现机制为本地文件,注意因为是容器方式运行 manager,需要将本地文件挂载到容器内。

$ docker run -d -p 12375:2375 -v /tmp/cluster_info:/tmp/cluster_info swarm manage file:///tmp/cluster_info

接下来就可以通过使用 Swarm 服务来进行管理了,例如使用 info 查看所有节点的信息。

$ docker -H 192.168.132.131:12375 info

etcd

#快速部署一个 consul 服务的命令为:
$ docker run -d -p 8500:8500 --name=consul progrium/consul -server -bootstrap #之后创建 Swarm 的管理服务,指定使用 consul 服务,管理端口监听在本地的 4000 端口。
$ docker run -d -p 4000:4000 swarm manage -H :4000 --replication --advertise <manager_ip>:4000 consul://<consul_ip>:8500 #Swarm 节点注册时候命令格式类似于
$ docker run -it -d swarm join --advertise=<node_ip:2375> consul://<consul_addr>/<optional path prefix>

对于 etcd 服务后端来说,节点注册时候命令格式类似于:

$ swarm join --addr=<node_addr:2375> etcd://<etcd_addr1>,<etcd_addr2>/<optional path prefix>

#示例
docker run -ti -d swarm join --addr 10.211.55.20:2375 etcd://10.211.55.20:4001

启动管理服务时候,格式类似于:

$ swarm manage -H tcp://<manager_ip>:4000 etcd://<etcd_addr1>,<etcd_addr2>/<optional path prefix>

地址和端口的范围匹配

对于基于文件,以及手动指定节点信息两种服务发现后端机制来说,其中地址和端口域可以支持指定一个范围,以一次性指定多个地址。 例如:

192.168.0.[2:10]:2375 代表 192.168.0.2:2375 -- 192.168.0.10:2375 一共 9 个地址;
192.168.0.2:[2:9]375 代表 192.168.0.2:2375 -- 192.168.0.2:9375 一共 8 个地址。

swarm DockerHub

  • create:创建一个集群;
  • list:列出集群中的节点;
  • manage:管理一个集群;
  • join:让节点加入到某个集群。
  • 注意,使用 DockerHub 的服务发现后端,需要各个节点能通过公网访问到 DockerHub 的服务接口。
$ docker run --rm swarm create
a94a649f002a0c3d9ddf7c9e4de4be82

注意返回的字符串,这是集群的唯一 id,加入集群的各个节点将需要这个信息。

1、配置集群节点

在所有要加入集群的普通节点上面执行 swarm join 命令,表示把这台机器加入指定集群当中。

[root@localhost ~]# docker run --rm swarm join --addr=192.168.132.131:2375 token://a94a649f002a0c3d9ddf7c9e4de4be82

按ctrl+c 返回

注:其中 --addr 指定的 IP 地址信息将被发送给服务发现后端,用以区分集群不同的节点。manager 服务必须要通过这个地址可以访问到该节点。

上述命令执行后,默认每隔 20 秒(可以通过 --heartbeat 选项指定),会输出一条心跳信息。对于发现服务后端来说,默认如果超过 60 秒(可以通过 --ttl 选项指定)没有收到心跳信息,则将节点从列表中删除。

如果不希望看到输出日志信息,则可以用 -d 选项替换 --rm 选项,让服务后台执行。
执行 swarm join 命令实际上是通过 agent 把自己的信息注册到发现服务上,因此,此时对于后端的发现服务来说,已经可以看到有若干节点注册上来了。那么,如何管理和使用这些节点呢,这就得需要 Swarm 的 manager 服务了。

后端运行:

docker run -d swarm join --addr=192.168.132.131:2375 token://a94a649f002a0c3d9ddf7c9e4de4be82

在每个节点上执行此命令

2、配置管理节点

配置管理节点需要通过 swarm manage 命令,该命令将启动 manager 服务,默认监听到 2375 端口,所有对集群的管理可以通过该服务接口进行。

manager 服务默认监听的端口跟 Docker 服务监听端口是一样的,这是为了兼容其它基于 Docker 的服务,可以无缝地切换到 Swarm 平台上来。

仍然在节点 192.168.132.131进行操作。由于我们是采用 Docker 容器形式启动 manager 服务,本地的 2375端口已经被 Docker Daemon 占用。我们将 manager 服务监听端口映射到本地一个空闲的 12375 端口。(如果没有被占用可略过)

docker run -d -p 12375:2375 swarm manage token://a94a649f002a0c3d9ddf7c9e4de4be82

命令如果执行成功会返回刚启动的 Swarm 容器的 ID,此时一个简单的 Swarm 集群就已经搭建起来了,包括一个普通节点和一个管理节点。

3、查看集群节点列表

[root@localhost ~]# docker run --rm swarm list token://a94a649f002a0c3d9ddf7c9e4de4be82
192.168.132.133:2375
192.168.132.134:2375
192.168.132.131:2375

简单运行一个容器

[root@localhost ~]# docker -H 192.168.132.131:12375 run -d ubuntu whoami
3973d807f5c1555dede0fa3681cdec7a5789e6892aa5685e813ca4dd97032677

134 上

swarm调度器

Swarm 目前支持三种调度策略:spread、binpack 和 random。

在执行swarm manage命令启动管理服务的时候,可以通过 --strategy 参数指定调度策略,默认的是 spread。

简单来说,这三种调度策略的优化目标如下:
spread:如果节点配置相同,选择一个正在运行的容器数量最少的那个节点,即尽量平摊容器到各个节点;
binpack:跟 spread 相反,尽可能的把所有的容器放在一台节点上面运行,即尽量少用节点,避免容器碎片化。
random:直接随机分配,不考虑集群中节点的状态,方便进行测试使用。

启动方法:

docker run -d -p 12375:2375 swarm manage --strategy "spread" token://946d65606f7c2f49766e4dddac5b4365

Swarm过滤器

Swarm 的调度器可以按照指定调度策略自动分配容器到节点。但有些时候希望能对这些分配加以干预。比如说,让 IO 敏感的容器分配到安装了 SSD 的节点上;让计算敏感的容器分配到 CPU 核数多的机器上;让网络敏感的容器分配到高带宽的机房;让某些容器尽量放同一个节点……。

这可以通过过滤器(filter)来实现,目前支持 Constraint、Affinity、Port、Dependency、Health等五种过滤器。

Constraint 过滤器

Constraint 过滤器是绑定到节点的键值对,相当于给节点添加标签。

可在启动 Docker 服务的时候指定,例如指定某个节点颜色为 red

$ sudo docker daemon --label color=red -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

#同样的,可以写在 Docker 服务的配置文件里面(以 centos7 为例是 /lib/systemed/system/docker.service)。
--label color=red -H 0.0.0.0:2375 -H unix:///var/run/docker.sock

使用 Swarm 启动容器的时候,采用 -e constarint:key=value 的形式,可以过滤选择出匹配条件的节点。

例如,我们将 192.168.132.133 节点打上红色标签,192.168.132.134 节点打上绿色标签。
然后,分别启动两个容器,指定使用过滤器分别为红色和绿色。

$ docker -H 192.168.132.131:12375 run -d -e constraint:color==red ubuntu:14.04 ping 127.0.0.1
252ffb48e64e9858c72241f5eedf6a3e4571b1ad926faf091db3e26672370f64 $ docker -H 192.168.132.131:12375 run -d -e constraint:color==green ubuntu:14.04 ping 127.0.0.1
3d6f8d7af8583416b17061d038545240c9e5c3be7067935d3ef2fbddce4b8136

注:指定标签中间是两个等号

另外,Docker 内置了一些常见的过滤器,包括 node、storagedriver、executiondriver、kernelversion、operatingsystem 等。这些值可以通过 docker info 命令查看。

Affinity 过滤器

Affinity 过滤器允许用户在启动一个容器的时候,让它分配到某个已有容器的节点上。

现在启动一个 nginx 容器,让它跟容器 sick_galileo 放在一起,都放到 Host-2 节点上。可以通过 -e affinity:container==<name or id> 参数来实现。

$ docker -H 192.168.0.2:12375 run -d -e affinity:container==sick_galileo nginx

即指定某docker宿主机上正在运行的容器的容器名或者container id

然后启动一个 redis 容器,让它跟容器 compassionate_ritchie 放在一起,都放到 Host-3 节点上。

$ docker -H 192.168.0.2:12375 run -d -e affinity:container==compassionate_ritchie redis

查看所有容器运行情况。

$ docker -H 192.168.132.131:12375 ps

其他

例如通过 -e affinity:image==<name or id> 来选择拥有指定镜像的节点;通过 -e affinity:label_name==value 来选择拥有指定标签的容器所允许的节点。

docker swarm 简易版的更多相关文章

  1. docker swarm英文文档学习-7-在集群中管理节点

    Manage nodes in a swarm在集群中管理节点 List nodes列举节点 为了查看集群中的节点列表,可以在管理节点中运行docker node ls: $ docker node ...

  2. Docker集群管理(三)—— docker swarm mode基础教程

    docker从1.12版(及后续版本)集成了swarmkit.可以方便的实现docker集群.它有哪些特点呢: 集成了集群功能 分散设计:manager和worker两种节点. 声明式服务模式 可伸缩 ...

  3. Docker Swarm 让你事半功倍

    2016 年 DockerCon (天啊……我多么希望我当时在场)上展示的最重大的变革之一就是 1.12 版本引擎的 Swarm 模式.它意味着什么呢?它意味着:如果你在运行 Docker 1.12时 ...

  4. docker 1.12 版本 docker swarm 集群

    博客已经迁移到 个人博客中 个人博客 更新地址: http://www.xf80.com/2016/10/25/docker-swarm-1.12/ docker 1.12 版本 的新特性 (1)do ...

  5. 云计算之路-阿里云上:docker swarm 集群故障与异常

    在上次遭遇 docker swarm 集群故障后,我们将 docker 由 17.10.0-ce 升级为最新稳定版 docker 17.12.0-ce . 前天晚上22:00之后集群中的2个节点突然出 ...

  6. 云计算之路-阿里云上:针对 docker swarm 故障的部署调整以及应急措施

    针对这周 docker swarm 集群的频繁故障(详见故障一 .故障二.故障三),我们今天对 docker swarm 集群的部署进行了如下调整. 将 docker engine 由  “17.12 ...

  7. 云计算之路-阿里云上-容器难容:容器服务故障以及自建 docker swarm 集群故障

    3月21日,由于使用阿里云服务器自建 docker swarm 集群的不稳定,我们将自建 docker swarm 集群上的所有应用切换阿里云容器服务 swarm 版(非swarm mode). 3月 ...

  8. 云计算之路-阿里云上-容器难容:优化自建 docker swarm 集群的部署

    在上周六遭遇阿里云容器服务 swarm 版的故障之后,我们决定还是走自建 docker swarm 之路,只要不是阿里云底层的问题,我们相信会找到办法解决或避开自建 docker swarm 不稳定的 ...

  9. docker~swarm搭建docker高可用集群

    回到目录 Swarm概念 Swarm是Docker公司推出的用来管理docker集群,它将一群Docker宿主机变成一个单一的,虚拟的主机.Swarm使用标准的Docker API接口作为其前端访问入 ...

随机推荐

  1. 洛谷P2055假期的宿舍

    题目 此题主要是考察二分图匹配,而二分图匹配最主要的就是建图,而图一般都是要分成两个部分来分,比如该题就需要先将在学校住的人和床连在一起,因为在学校住就会与一个床.然后每两个人之间假如他们相互认识就可 ...

  2. Matplotlib学习---用seaborn画矩阵图(pair plot)

    矩阵图非常有用,人们经常用它来查看多个变量之间的联系. 下面用著名的鸢尾花数据来画一个矩阵图.从sklearn导入鸢尾花数据,然后将其转换成pandas的DataFrame类型,最后用seaborn画 ...

  3. codeforces1096G Lucky Tickets

    题目链接:https://codeforces.com/problemset/problem/1096/G 大意:给出\(k\)个数码\(d_1,d_2,\cdots,d_k\),构造一个由这\(k\ ...

  4. Ionic的页面堆栈与Tabs菜单相遇的问题(页面堆栈有多个)

    本来的需求: 新建的Ionic项目是Tabs菜单,假设有两个选项卡 A 和 B(从左到右),对应的两个页面的代码完全一样,使用了echarts 插件,并且使用了一个获取页面元素的方法,给自己的一个变量 ...

  5. gulp 技巧

    install npm install --save-dev jshint gulp-jshint 压缩js npm install --save-dev gulp-minify-css xxCSS ...

  6. Luogu P4643 【模板】动态dp(矩阵乘法,线段树,树链剖分)

    题面 给定一棵 \(n\) 个点的树,点带点权. 有 \(m\) 次操作,每次操作给定 \(x,y\) ,表示修改点 \(x\) 的权值为 \(y\) . 你需要在每次操作之后求出这棵树的最大权独立集 ...

  7. [NOIP提高组2011day1t2]选择客栈

    我看到有人用线段树来写而且想法和我的差不多,但是代码有一点复杂,所以我就贴一下我的做法. 思路 首先一定知道纯暴力50分差不多了,所以看到k非常的小,那么就从k入手. 不知道有没有人和我一样是先枚举颜 ...

  8. 「SCOI2014」方伯伯的 OJ 解题报告

    「SCOI2014」方伯伯的 OJ 和列队有点像,平衡树点分裂维护即可 但是需要额外用个set之类的对编号查找点的位置 插入完了后记得splay,删除时注意特判好多东西 Code: #include ...

  9. LOJ#6277. 数列分块入门 1

    分块思想,先把原来的序列分成根号n快,然后对于更新的部分,先操作这个序列边上的部分,然后再中间部分整块操作,这样复杂度就是O(根号N) #include<map> #include< ...

  10. django rest framework ViewSets & Routers

    Using viewsets views.py from rest_framework import viewsets from rest_framework import mixins from r ...