Docker Swarm是Docker官方的三剑客项目之一,提供Docker容器集群服务,是Docker官方对容器云生态进行支持的核心方案。
使用它,用户可以将多个Docker主机封装为单个大型的虚拟Docker主机,快速打造一套容器云平台。
Docker Swarm是Docker公司推出的官方容器集群平台,基于Go语言实现。
目前,包括Rackspace在内的许多平台都采用了Swarm,用户很容易在AWS等公有云平台使用Swarm。
Swarm的前身是Beam项目和libswarm项目,首个正式版本(Swarm V1)在2014年12初发布。
为了提高可扩展性,2016年2月对架构进行重新设计,推出V2版本,支持超过1000个节点。
最新的Docker Engine已经集成了Swarm Kit,加强了对Swarm的协调支持。
作为容器集群管理器,Swarm最大的优势就是100%支持标准的Docker API。
各种基于标准API工具,如Compose、docker.py,各种管理软件,甚至Docker本身都可以很容易地与Swarm集成。
这大大方便了用户将原先基于单节点地系统移植到Swarm上。
同时Swarm内置了对Docker网络插件地支持,用户可以很容易地部署跨主机地容器集群服务。
Swarm是典型地master-slave结构,通过发现服务来选举manager。manager是中心管理节点,各个node上运行agent接受manager地统一管理。
在v2中,集群会自动通过Raft协议分布式选举manager节点,无需额外地发现服务地支持,避免了单节点瓶颈。
同时v2内置了基于DNS地负载均衡和外部负载均衡机制地集群支持。
一、构建集群
对于Docker1.12已经更新的版本,swarm相关命令已经原生嵌入到了Docker Engine中,因此我们可以直接使用。
首先查看docker swarm的帮助信息:
[root@centos003 ~]# docker swarm --help Usage: docker swarm COMMAND Manage Swarm Commands: ca Display and rotate the root CA init 初始化一个集群 join 将swarm作为节点或者管理器加入集群 join-token 管理连接令牌 leave 退出集群 unlock 解锁集群 unlock-key 管理解锁密钥 update 更新集群 使用'docker swarm COMMAND --help' 来查看每个命令的详细信息
在构建集群之前首先应该保证的是每台机器(不论是虚拟机还是物理机)上面都已经安装Docker Engine并且已经启动,当然你可以使用docker machine来快速构建。
1.初始化集群
为了更加清晰的使用docker swarm init进行初始化,我们首先依旧是查看帮助信息。
[root@centos003 ~]# docker swarm init --help Usage: docker swarm init [OPTIONS] Initialize a swarm Options: --advertise-addr string 广播地址 (format: <ip|interface>[:port]) --autolock 启用管理器自动锁定(需要解锁密钥才能启动已停止的管理器) --availability string 节点的可用性(“active”|“pause”|“drain”)(默认为“active”) --cert-expiry duration 节点证书的有效期(ns | us | ms | s | m | h)(默认为2160h0m0s) --data-path-addr string 用于数据路径流量的地址或接口(格式:<ip | interface>) --default-addr-pool ipNetSlice CIDR格式的默认地址池(默认为[]) --default-addr-pool-mask-length uint32 uint32默认地址池子网掩码长度(默认为24) --dispatcher-heartbeat duration Dispatcher心跳周期(ns | us | ms | s | m | h)(默认为5s) --external-ca external-ca 一个或多个证书签名端点的规范 --force-new-cluster 从当前状态创建新集群 --listen-addr node-addr 监听地址(格式:<ip | interface> [:port])(默认为0.0.0.0:2377) --max-snapshots uint uint要保留的其他Raft快照数 --snapshot-interval uint uint Raft快照之间的日志条目数(默认10000) --task-history-limit int int任务历史记录保留限制(默认值为5)
需要说明的是节点可用性的三种状态:
• Active:集群中该Node可以被指派TASK;
• Pause:集群中该Node不可以被指派新的Task,但是其它已经存在的TASK保持运行;
• Drain:集群中该Node不可以被指派新的Task,Swarm Scheduler停掉已经存在的Task;
下面具体代码:
[root@centos003 ~]# docker swarm init --advertise-addr 129.204.16.68 Swarm initialized: current node (vsxiq5bqs1htj12wv7jdths7m) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-0pnmvu8zc31j1fnl3qtb3xsakgdnraiuxvzw7zax4kiaw8mefy-dbk5n56wwa03gov4dwgsrqskp 129.204.16.68:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
上面–advertise-addr选项指定Manager Node会publish它的地址为192.168.1.107,后续Worker Node加入到该Swarm集群,必须要能够访问到Manager的该IP地址。
该结果中给出了后续操作引导信息,告诉我们如何将Worker Node加入Swarm集群中.
2.加入节点
查看帮助信息:
[root@centos003 ~]# docker swarm join --help Usage: docker swarm join [OPTIONS] HOST:PORT Join a swarm as a node and/or manager Options: --advertise-addr string 广播地址(格式:<ip | interface> [:port]) --availability string 节点的可用性(“active”|“pause”|“drain”)(默认为“active”) --data-path-addr string 用于数据路径流量的地址或接口(格式:<ip | interface>) --listen-addr node-addr 监听地址(格式:<ip | interface> [:port])(默认为0.0.0.0:2377) --token string 用于进入群体的令牌
加入test节点:
[root@test ~]# docker swarm join --token SWMTKN-1-0pnmvu8zc31j1fnl3qtb3xsakgdnraiuxvzw7zax4kiaw8mefydbk5n56wwa03gov4dwgsrqskp 129.204.16.68:2377 This node joined a swarm as a worker.
加入test2节点:
[root@test2 ~]# docker swarm join --token SWMTKN-1-0pnmvu8zc31j1fnl3qtb3xsakgdnraiuxvzw7zax4kiaw8mefydbk5n56wwa03gov4dwgsrqskp 129.204.16.68:2377 This node joined a swarm as a worker.
对于token后面的一长串字符是集群初始化的时候生成的令牌,每个想要加入这个集群的机器都需要拿着这个令牌才能加入到该集群.
可以通过docker node查看当前集群的所有节点:
[root@centos003 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION vsxiq5bqs1htj12wv7jdths7m * centos003 Ready Active Leader 18.09.0 yjaslsxqfnvpq8zjvjpdabi7x test Ready Active 18.09.0 poyqgaqkc1byucsa5q2rppck2 test2 Ready Active 18.09.0
名词解释:
• ID:swarm会为集群中的每台机器分配一个唯一ID;
• HOSTNAME:主机名
• STATUS:当前状态
• AVAILABILITY:节点的可用性
• MANAGER STATUS:是否是管理节点
• ENGINE:Docker的版本
二、节点管理
通过查看帮助信息可以知道节点的相关操作:
[root@centos003 ~]# docker node --help Usage: docker node COMMAND Manage Swarm nodes Commands: demote 将一个或多个管理节点降级 inspect 显示一个或多个节点的详细信息 ls 列出Swarm集群中的所有节点 promote 将Swarm中的一个或多个节点升级为管理节点 ps 列出一个或多个节点上运行的任务,默认为当前节点 rm 从集群中删除一个或多个节点 update 更新节点 运行 'docker node COMMAND --help' 命令可以查看更多节点的相关信息
Swarm支持设置一组Manager Node,通过支持多Manager Node实现HA。
那么这些Manager Node之间的状态的一致性就非常重要了,多Manager Node的Warm集群架构,如下图所示(出自Docker官网):
通过上图可以看出,Swarm使用了Raft协议来保证多个Manager之间状态的一致性.
基于Faft协议,Mananger Node具有一定的容错功能,假设Swarm集群中有N个Manager Node,那么整个集群可以容忍最多(N-1)/2个节点失效,如果是一个三个Manager Node的Swarm集群,最多只能容忍一个Manager Node挂掉.
下面是对一些常规操作的解释:
1.节点更新
查看帮助信息:
[root@centos003 ~]# docker node update --help Usage: docker node update [OPTIONS] NODE Update a node Options: --availability string 节点的可用性(“active”|“pause”|“drain”) --label-add list 添加或更新节点标签(key = value) --label-rm list 删除节点标签(如果存在) --role string 节点的角色(“worker”|“manager”)
(1)修改节点的可用性
[root@centos003 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION vsxiq5bqs1htj12wv7jdths7m * centos003 Ready Active Leader 18.09.0 yjaslsxqfnvpq8zjvjpdabi7x test Ready Active 18.09.0 poyqgaqkc1byucsa5q2rppck2 test2 Ready Active 18.09.0
将test可用性修改为pasue,返回主机名:
[root@centos003 ~]# docker node update --availability "pause" test test
再次查看状态信息:
[root@centos003 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION vsxiq5bqs1htj12wv7jdths7m * centos003 Ready Active Leader 18.09.0 yjaslsxqfnvpq8zjvjpdabi7x test Ready Pause 18.09.0 poyqgaqkc1byucsa5q2rppck2 test2 Ready Active 18.09.0
常见的变更操作:
• 设置Manager Node只具有管理功能
• 对服务进行停机维护,可以修改AVAILABILITY为Drain状态
• 暂停一个Node,然后该Node就不再接收新的Task
• 回复一个不可用或暂停的Node
(2)标签操作
每个Node的主机配置情况可能不同,比如有的适合运行CPU密集型应用,有的适合运行IO密集型应用,
Swarm支持给每个Node添加标签元数据,这样可以根据Node的标签,来选择性地调度某个服务部署到期望的一组Node上。
添加或者更新标签:
[root@centos003 ~]# docker node update --label-add author=kebi test
test
可以通过docker node inspect 命令来查看标签信息
删除节点标签:
[root@centos003 ~]# docker node update --label-rm author test test
(3)角色操作
[root@centos003 ~]# docker node update --role "manager" test test [root@centos003 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION vsxiq5bqs1htj12wv7jdths7m * centos003 Ready Active Leader 18.09.0 yjaslsxqfnvpq8zjvjpdabi7x test Ready Pause Reachable 18.09.0 poyqgaqkc1byucsa5q2rppck2 test2 Ready Active 18.09.0
2.提权/降权
Usage: docker node demote/promote NODE [NODE...]
目前集群的状态信息:
[root@centos003 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION vsxiq5bqs1htj12wv7jdths7m * centos003 Ready Active Leader 18.09.0 yjaslsxqfnvpq8zjvjpdabi7x test Ready Active 18.09.0 poyqgaqkc1byucsa5q2rppck2 test2 Ready Active 18.09.0
将test升级为manager节点:
3.查看节点任务
查看帮助信息:
查看帮助信息: [root@centos003 ~]# docker node ps --help Usage: docker node ps [OPTIONS] [NODE...] List tasks running on one or more nodes, defaults to current node Options: -f, --filter filter 过滤输出 --format string 使用Go模板打印任务 --no-resolve 不将ID映射到名称 --no-trunc 不截断输出 -q, --quiet 仅显示任务ID
示例:
[root@centos003 ~]# docker node ps test ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS e78xw9zleb9n myredis.3 redis:latest test Running Running 26 minutes ago
4.查看节点信息
查看帮助信息:
[root@centos003 ~]# docker node ls --help Usage: docker node ls [OPTIONS] List nodes in the swarm Aliases: ls, list Options: -f, --filter filter 过滤输出 --format string 使用Go模板打印任务 -q, --quiet 仅显示任务ID
三、服务管理
在Swarm集群上部署服务,必须在Manager Node上进行操作。
先说明一下Service、Task、Container(容器)这个三个概念的关系,如下图(出自Docker官网)非常清晰地描述了这个三个概念的含义:
在Swarm mode下使用Docker,可以实现部署运行服务、服务扩容缩容、删除服务、滚动升级等功能。
Docker服务的功能比较丰富,通过查看帮助信息可以很清楚的到它有那些操作。
[root@centos003 ~]# docker service --help Usage: docker service COMMAND Manage services Commands: create 创建一个新的服务 inspect 显示一个或多个服务的详细信息 logs 获取服务或任务的日志 ls 列出服务 ps 列出一个或多个服务的任务 rm 删除一项或多项服务 rollback 还原对服务配置的更改 scale 缩放一个或多个复制的服务 update 更新服务 Run 'docker service COMMAND --help' for more information on a command.
下面是部分命令的讲解:
1.创建服务
[root@centos003 ~]# docker service create --replicas 2 --name myredis redis y36sco45lvt28zotx6m7owzh4 overall progress: 2 out of 2 tasks 1/2: running [==================================================>] 2/2: running [==================================================>] verify: Service converged
可以通过docker service ls来查看已经创建的服务。
[root@centos003 ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS y36sco45lvt2 myredis replicated 2/2 redis:latest
2.扩容服务
Docker Swarm支持服务的扩容缩容,Swarm通过 --mode
选项设置服务类型,提供了两种模式:
一种是replicated,我们可以指定服务Task的个数(也就是需要创建几个冗余副本),这也是Swarm默认使用的服务类型;
另一种是global,这样会在Swarm集群的每个Node上都创建一个服务。
格式:
docker service scale 服务ID=服务Task总数
[root@centos003 ~]# docker service scale myredis=3 myredis scaled to 3 overall progress: 3 out of 3 tasks 1/3: running [==================================================>] 2/3: running [==================================================>] 3/3: running [==================================================>] verify: Service converged
通过docker service ps可以查看各个副本的状况。
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS wxufrk2enzjo myredis.1 redis:latest test2 Running Running 10 minutes ago suhfn7azj6da myredis.2 redis:latest centos003 Running Running 10 minutes ago e78xw9zleb9n myredis.3 redis:latest test Running Running about a minute ago