Docker Swarm
Swarm 是 Docker 官方提供的一款集群管理工具,其主要作用是把若干台 Docker 主机抽象为一个整体,并且通过一个入口统一管理这些 Docker 主机上的各种 Docker 资源。
Swarm 和 Kubernetes 比较类似,但是更加轻,具有的功能也较 kubernetes 更少一些。
概念
节点(Nodes)
节点是参与 swarm 的 Docker 引擎的一个实例。你可以在单个物理计算机或云服务器上运行一个或多个节点,但生产环境中swarm部署通常包括分布在多个物理和云计算机上的 Docker 节点。
节点分为管理节点和工作节点。
节点的有效性有三种:
Active
调度程序可以分配任务给节点。Pause
调度程序不分配新任务给节点,但现有任务继续运行。Drain
调度程序不分配新任务给节点,调度程序关闭任何现有任务并将它们调度到可用节点上。
管理节点(Manager nodes)
管理器节点执行编排和集群管理功能。要将应用程序部署到 swarm,需要向管理节点提交服务定义,管理节点将称为任务的工作单元分派给工作节点。Docker建议一个Swarm最多7个管理节点。
工作节点(Worker nodes)
工作节点接收和执行管理节点分发的任务。默认情况下,管理节点也是工作节点,但可以通过配置让它仅作为管理节点。
服务(Services)和任务(tasks)
服务是要在管理节点或工作节点上执行的任务的定义。 它是 swarm 系统的中心结构,也是用户与 swarm 交互的主要根源。
创建服务时,需要指定要使用的容器映像以及在运行的容器中执行的命令。
一个任务携带一个 Docker 容器和在容器内运行的命令。 它是 swarm 的原子调度单元。 Manager 节点根据服务规模中设置的副本数将任务分配给工作节点。 一旦任务被分配给一个节点,它就不能移动到另一个节点。 它只能在分配的节点上运行或失败。
高可用(HA)
Swarm 的管理节点内置有对 HA 的支持,使用了 Raft 共识算法的一种具体实现来支持管理节点的HA,即使一个或多个节点发生故障,剩余管理节点也会继续保证 Swarm 的运转。
即使有多个管理节点,但始终只有一个处于活动状态,称为主节点(leader),其他管理节点称为follower。只有主节点才会变更配置或发送任务到工作节点。如果非主节点收到了Swarm命令,则会将命令转发给主节点。
关于 HA,有以下两条最佳实践原则:
- 部署奇数个管理节点。
- 不要部署太多管理节点(建议 3 个或 5 个)。
部署奇数个管理节点有利于减少脑裂(Split-Brain)情况的出现机会。假如有 4 个管理节点,当网络发生分区时,可能会在每个分区有两个管理节点。这种情况被称为脑裂。部署奇数个管理节点,掌握多数管理节点的分区能够继续对集群进行管理。
初始化Swarm
没有加入Swarm集群时,docker节点运行单引擎模式,加入Swarm集群,则切换成Swarm模式。
-
初始化Swarm
[root@localhost ~]# docker swarm init --advertise-addr <MANAGER-IP>
-
列出Swarm中的节点
[root@localhost ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION r0xhp3biurh9o67pjfn1enr0b * kaka.com Ready Active Leader 19.03.13
-
查看当前Swarm状态
[root@localhost ~]# docker info
-
获取添加工作节点或管理节点的命令和Token
[root@localhost ~]# docker swarm join-token worker To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-2s8kg8ppmqbsmxl3v8naqfjigh97pw42kgpsqt9v5mlp4p9zxp-ef5t2aume09pahiuyke1l7w60 192.168.15.138:2377 [root@localhost ~]# docker swarm join-token manager To add a manager to this swarm, run the following command: docker swarm join --token SWMTKN-1-2s8kg8ppmqbsmxl3v8naqfjigh97pw42kgpsqt9v5mlp4p9zxp-6vn2y4aro0jyfve63t4n6hyqa 192.168.15.138:2377
部署服务
-
连接到管理节点
-
运行下面的命令:
[root@localhost ~]# docker service create --replicas 1 --name helloworld alpine ping docker.com
- 命令
docker service create
创建服务。 --name
指定service的名字为helloworld
。--replicas
指定一个运行实例。- 参数
alpine ping docker.com
将服务定义为一个执行命令ping docker.com
的Alpine Linux容器。
- 命令
-
列出运行的服务
[root@localhost ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS v0ckm856yrda helloworld replicated 1/1 alpine:latest
副本服务和全局服务
服务的默认复制模式(Replication Mode)是副本模式(replicated)。这种模式会部署期望数量的服务副本,并尽可能均匀地将各个副本分布在整个集群中。
另一种模式是全局模式(global),在这种模式下,每个节点上仅运行一个副本。全局服务是在每个节点上运行一个任务的服务。 没有预先指定的任务数量。 每次将节点添加到 swarm 时,编排器都会创建一个任务,调度器会将任务分配给新节点。 全局服务的良好候选者是监控代理、防病毒扫描程序或您希望在集群中的每个节点上运行的其他类型的容器
可以通过给 docker service create
命令传递 --mode global
参数来部署一个全局服务。
检查服务
-
连接到管理节点
-
运行命令
docker service inspect --pretty <SERVICE-ID>
可以查看服务详细信息,--pretty
选项是以一个易于阅读的格式来显示服务的详细信息。[root@localhost ~]# docker service inspect --pretty helloworld
-
运行命令
docker service ps <SERVICE-ID>
可以查看哪些节点在运行指定的服务。[root@localhost ~]# docker service ps helloworld ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS er44utjelha1 helloworld.1 alpine:latest kaka.com Running Running 4 hours ago
-
在节点上运行
docker ps
命令,查看正在运行任务的容器详情。[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c6528d59b1d3 alpine:latest "ping docker.com" 5 hours ago Up 5 hours helloworld.1.er44utjelha1r7o1gsdrhu0ok
服务扩容
服务部署到Swarm后,可以使用Docker CLI来对服务的容器数进行扩容。在服务中运行的容器称为“任务”。
-
连接到管理节点
-
运行
docker service scale <SERVICE-ID>=<NUMBER-OF-TASKS>
命令,设置服务的容器实例数。[root@localhost ~]# docker service scale helloworld=2 helloworld scaled to 2 overall progress: 2 out of 2 tasks 1/2: running [==================================================>] 2/2: running [==================================================>] verify: Service converged
-
运行
docker service ps <SERVICE-ID>
命令,查看任务列表。[root@localhost ~]# docker service ps helloworld ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS er44utjelha1 helloworld.1 alpine:latest kaka.com Running Running 2 days ago r58n0obkcjll helloworld.2 alpine:latest kaka.com Running Running 2 minutes ago
-
运行
docker ps
命令,查看运行中的容器。[root@localhosts ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2b4745f2177d alpine:latest "ping docker.com" 4 minutes ago Up 4 minutes helloworld.2.r58n0obkcjll9me5smemo3d16 c6528d59b1d3 alpine:latest "ping docker.com" 2 days ago Up 2 days helloworld.1.er44utjelha1r7o1gsdrhu0ok
删除服务
-
连接到管理节点
-
运行
docker service rm <SERVICE-ID>
命令,删除服务。[root@localhosts ~]# docker service rm helloworld
-
即使该服务不再存在,任务容器也需要几秒钟来清理。 可以在节点上使用 docker ps 来验证任务何时被删除。
服务滚动更新
-
连接到管理节点
-
运行
docker service create --update-delay 10s
命令,部署并配置延迟更新服务。[root@localhost ~]# docker service create --replicas 3 --name helloworld --update-delay 10s alpine
--update-delay
标志配置更新服务任务或任务集之间的时间延迟。 您可以将时间 T 描述为秒数Ts
、分钟数Tm
或小时数Th
的组合。10m30s
秒表示延迟 10 分 30 秒。默认情况下,调度程序一次更新 1 个任务。 您可以通过
--update-parallelism
标志来配置调度程序同时更新的最大服务任务数。默认情况下,当单个任务的更新返回
RUNNING
状态时,调度程序会安排另一个任务进行更新,直到所有任务都更新完毕。 如果在更新期间的任何时间任务返回FAILED
,调度程序会暂停更新。 您可以使用docker service create
或docker service update
的--update-failure-action
标志来控制行为。 -
现在你可以更新 alpine 的容器映像。 swarm manager 根据 UpdateConfig 策略将更新应用到节点。
[root@localhost ~]# docker service update --image alpine:latest helloworld
默认情况下,调度程序按如下方式应用滚动更新:
- 停止第一个任务。
- 为已停止的任务安排更新。
- 启动已更新任务的容器。
- 如果对任务的更新返回
RUNNING
,则等待指定的延迟时间然后启动下一个任务。 - 如果在更新期间的任何时间任务返回
FAILED
,则暂停更新。
-
运行
docker service inspect --pretty helloworld
命令查看新镜像。[root@localhost ~]# docker service inspect --pretty helloworld ID: v0ckm856yrdadzcj0jyg11aui Name: helloworld Service Mode: Replicated Replicas: 2 Placement: UpdateConfig: Parallelism: 1 On failure: pause Monitoring Period: 5s Max failure ratio: 0 Update order: stop-first RollbackConfig: Parallelism: 1 On failure: pause Monitoring Period: 5s Max failure ratio: 0 Rollback order: stop-first ContainerSpec: Image: alpine:latest@sha256:4edbd2beb5f78b1014028f4fbb99f3237d9561100b6881aabbf5acce2c4f9454 Args: ping docker.com Init: false Resources: Endpoint Mode: vip
要想重新启动被暂停的更新,运行
docker service update <SERVICE-ID>
。 -
运行
docker service ps <SERVICE-ID>
命令查看更新。
清空节点
swarm manager 可以将任务分配给任何 ACTIVE 节点。
有时,例如计划的维护时间,您需要将节点的可用性设置为 DRAIN
。 DRAIN
可用性阻止节点从集群管理器接收新任务。 这也意味着管理器停止在节点上运行的任务并在具有 ACTIVE
可用性的节点上启动副本任务。
-
查看所有节点
[root@localhost ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION r0xhp3biurh9o67pjfn1enr0b * worker1 Ready Active Leader 19.03.13
-
运行命令设置节点为
DRAIN
状态。[root@localhost ~]# docker node update --availability drain worker1
-
查看节点状态。
[root@localhost ~]# docker node inspect --pretty worker1
-
运行命令设置节点为
ACTIVE
状态。[root@localhost ~]# docker node update --availability active worker1
节点管理
列出节点
[root@loclhost ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
r0xhp3biurh9o67pjfn1enr0b * kaka.com Ready Active Leader 19.03.13
检查节点
[root@loclhost ~]# docker node inspect self --pretty
更新节点
-
修改节点可用性
[root@loclhost ~]# docker node update --availability drain node-1
-
提升或降级节点
可以把工作节点提升为管理节点,也可以把管理节点降级为工作节点。
-
提升节点:
[root@loclhost ~]# docker node promote node-3 node-2
-
降级节点:
[root@loclhost ~]# docker node demote node-3 node-2
-
离开集群
[root@loclhost ~]# docker swarm leave
当一个节点离开 swarm 时,Docker Engine 停止在 swarm 模式下运行。 编排器不再将任务调度到节点。
如果节点是管理节点,您会收到有关维护仲裁的警告。 要覆盖警告,请传递 --force 标志。 如果最后一个管理节点离开 swarm,swarm 将变得不可用,需要您采取灾难恢复措施。
有关维护仲裁和灾难恢复的信息,请参阅 Swarm 管理指南。
节点离开 swarm 后,您可以在管理节点上运行 docker node rm 命令将该节点从节点列表中删除。