docker swarm 简易版
节点名称 | 相关服务 | 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 来选择拥有指定标签的容器所允许的节点。