Docker Swarm模式(跨主机容器集群管理)
Docker Swarm模式是Docker引擎内置的网络支持,其前身是Docker Swarm项目。该模式旨在提供Docker容器的跨主机集群管理,是Docker官方对容器云生态的核心支持方案。使用Docker Swarm功能,用户可以将多个Docker主机抽象为大规模的虚拟Docker集群服务,轻松构建一套容器云平台。
本章将介绍Docker Swarm模式的相关概念和使用方法,并结合服务来展示Docker Swarm的多主机集群管理功能。
1、Swarm模式简介
Swarm模式的前身---Docker Swarm项目是Docker公司于2014年年底推出的容器集群平台,使用Go语言开发。2016年2月重构的V2版本增强了扩展性,支持数千个节点。同年,Docker自1.12版本起内置SwarmKit,将原先单独的Swarm软件升级为Swarm模式,更为方便和强大。
作为容器集群管理器,Swarm的最大优势之一是原生支持Docker API。这使得用户可以非常便捷地使用各种基于Docker标准API的工具,例如Compose、SDK等,轻松操作多个主机上的容器。这极大地方便了用户将原本基于单节点的应用移植到Swarm集群上。同时,Swarm还内置了对Docker网络插件的支持,这使得用户可以轻松地部署跨主机的容器集群服务。
Swarm在实现上采用了典型的主从结构,如图所示,通过Raft协议在多个管理节点(manager node)之间实现共识。工作节点(worker node)上运行的代理接受管理节点的统一管理和任务分配。用户只需要向管理节点提交服务请求,管理节点会按照调度策略在集群中分配节点来运行服务相关的任务。这种结构和流程的设计使得Swarm具有高可用性和可扩展性,同时为用户提供了便利和灵活性。

另外,在Swarm集群中,会自动通过Raft协议分布式选出管理节点,无须额外的发现服务支持,避免了单点瓶颈。同时,Swarm还内置了基于DNS的负载均衡和对外部负载均衡机制的集成支持。
2、基本概念
Swarm构建在Docker基础之上,扩展了对多节点的支持,同时兼容了大部分Docker操作。Swarm以集群为单位进行管理,并提供了服务层面的操作。
下面介绍一些Swarm使用中的基本概念。
2.1、Swarm集群
Swarm集群是一组被统一管理的Docker主机,是Swarm所管理的资源对象。这些主机通过Docker引擎的Swarm模式相互沟通,其中一些主机作为管理节点响应外部的管理请求,其他主机作为工作节点来实际运行Docker容器。当然,同一主机也可以既作为管理节点,又作为工作节点。生产环境中为了确保稳定性,建议区分两种主机节点。
使用Swarm集群时,首先要定义服务,指定状态、副本数、网络、存储、暴露端口等信息。然后通过管理节点发出启动服务的指令,管理节点按照指定的服务规则进行调度,在集群中启动整个服务,并确保其正常运行。
Swarm集群的一个关键特性是高可用性。集群中至少需要有3个管理节点,这样即使一个管理节点出现故障,仍然可以保证集群正常运行。同时,Swarm还提供了自动化的服务发现和负载均衡功能,可自动将流量路由到可用的容器实例,提高应用程序的可靠性和性能。
2.2、节点
节点是Swarm集群的最小资源单位。每个节点都是一台Docker主机。
Swarm集群中的节点分为两种:
- 管理节点:负责响应外部对集群的操作请求,并维持集群中的资源,分发任务给工作节点。同时,多个管理节点之间通过Raft协议构成共识。一般推荐为每个集群设置5个或7个管理节点。
- 工作节点:负责执行管理节点安排的具体任务。默认情况下,管理节点自身同时也是工作节点,在每个工作节点上运行代理(agent)来汇报任务完成情况。
当一个节点加入Swarm集群时,它默认是一个工作节点。用户可以使用docker swarm join-tokenworker|manager命令来获取加入集群所需的命令,并在节点上运行该命令来加入集群。
用户可以通过docker node promote命令来提升一个工作节点为管理节点,或者通过docker node demote命令来将一个管理节点降级为工作节点。需要注意的是,在将管理节点降级为工作节点之前,应该先确保降级后集群的管理节点至少为3个,且都处于健康状态,以确保集群的高可用性和稳定性。
2.3、服务
服务是Docker在Swarm模式下支持复杂多容器协作场景的利器。
一个服务由若干个任务组成,每个任务为某个具体的应用。服务还包括对应的存储、网络、端口映射、副本个数、访问配置、升级配置等附加参数。
通常情况下,服务需要面向特定的场景,例如一个典型的Web服务可能包括前端应用、后端应用以及数据库等。这些应用都属于该服务的管理范畴。
在Swarm集群中,服务类型分为两种(可以通过-mode参数指定):
- 复制服务(replicated service)模式:默认模式,每个任务在集群中会存在若干副本,这些副本会被管理节点按照调度策略分发到集群中的工作节点上。在此模式下可以使用-replicas参数设置副本数量。
- 全局服务(global service)模式:每个可用节点都会执行一个相同的任务。该模式适合运行节点的检查,如监控应用等。
通过定义服务并指定启动参数,用户可以方便地创建、管理和升级多容器应用。
2.4、任务
任务是Swarm集群中最小的可调度单元,即一个特定的应用容器。举例来说,仅仅运行前端业务的前端容器就是一个任务。
任务具有多种不同的状态,例如创建(NEW)、等待(PENDING)、分配(ASSIGNED)、接受(ACCEPTED)、准备(PREPARING)、开始(STARTING)、运行(RUNNING)、完成(COMPLETE)、失败(FAILED)、关闭(SHUTDOWN)、拒绝(REJECTED)和孤立(ORPHANED)等。
Swarm集群中的管理节点会按照调度要求将任务分配到工作节点上。例如,当指定副本为2时,管理节点可能会被分配到两个不同的工作节点上。一旦某个任务被分配到一个工作节点,它就无法被转移到另一个工作节点上,也就是说Swarm中的任务不支持迁移。
2.5、服务的外部访问
Swarm集群中的服务要被集群外部访问,必须能允许任务的响应端口映射出来。
最简单的方式是在用户创建服务时,通过-p或者-publish参数将容器端口映射到主机端口上,从而通过该主机端口访问服务。
另外,Swarm集群还支持通过网络模式来进行服务访问。用户可以创建一个覆盖网络(overlay network),并将服务加入该网络中。然后,用户可以通过其他加入该网络的服务名来访问该服务,而不需要关注服务实际运行在哪个节点上。
为了实现高可用性和横向扩展,Swarm还支持入口负载均衡(ingress load balancing)模式。在该模式下,每个服务都会被分配若干公开端口(默认范围为30000~32767),该端口在集群中任意节点上都可以访问到,并被保留给该服务。
当外部请求到达负载均衡器时,它会将请求路由到关联的服务中任何可用的实例上。这样可以确保负载均衡器根据预定义的规则自动将请求路由到可用的服务实例,从而实现高可用性和可伸缩性。
2.6、使用Swarm
用户在安装Docker最新版本后,即可直接尝试Swarm模式的相关功能。示例集群包括两个Linux主机,作为管理节点(同时具备工作节点功能)和工作节点。
Swarm集群的主要操作包括:
- swarm ca:显示或替换根CA。
- swarm init:在管理节点上创建一个集群。
- swarm join:加入一个新的节点到已有集群中。
- swarm join-token:管理加入集群的口令。
- swarm leave:离开一个swarm集群。
- swarm unlock:解锁自动锁定的管理节点。
- swarm unlock-key:管理解锁口令。
- swarm update:更新一个Swarm集群。
集群启动后,可以使用docker service命令部署Docker应用服务到集群中。
2.7、创建集群
在管理节点上执行如下命令来创建一个新的Swarm集群,创建后会自动提示如何加入更多节点到集群中:


注意返回的token串,这是集群的唯一id,加入集群的各个节点将需要这个信息。
另外,默认的管理服务端口为2377,需要能被工作节点访问到;另外,为了支持集群的成员发现和外部服务映射,还需要在所有节点上开启7946 TCP/UDP端口和4789UDP端口。
swarm init命令支持的参数包括:
-advertise-addr[:port]:指定服务监听的地址和端口。-autolock:自动锁定管理服务的启停操作,对服务进行启动或停止都需要通过口令来解锁。-availability string:节点的可用性,包括active、pause、drain三种,默认为active。-cert-expiry duration:根证书的过期时长,默认为90天。-data-path-addr:指定数据流量使用的网络接口或地址。-data-path-port:指定数据流量使用的端口号(1024~49151),默认为4789。-default-addr-pool-mask-length:默认的子网掩码长度,默认为24。-external-ca external-ca:指定使用外部的证书签名服务地址。-force-new-cluster:强制创建新的集群。-listen-addr[:port]:监听地址,默认为0.0.0.0:2377。-max-snapshots uint:Raft协议快照保留的个数。-snapshot-interval uint:Raft协议进行快照的间隔(单位为事务个数),默认为10000个事务。-task-history-limit int:任务历史的保留个数,默认为5。
2.8、查看集群信息
此时通过docker info命令可以查看到集群的信息:

使用docker node ls命令列出集群中的所有节点,此时只有一个管理节点:

2.9、加入集群
在要加入集群的节点上执行swarm join命令,表示把这台机器加入指定集群当中。例如在工作节点上,将其加入刚创建的集群,则可以通过以下命令实现:

此时,在管理节点上再次查看集群中节点的情况,可以看到新加入的工作节点:

2.10、使用集群服务
那么,怎样使用Swarm提供的服务呢?
有两种方法,一种是使用Docker原来的客户端命令。在加入集群的任意节点上执行Docker命令,例如ps、info、run等。
另外一种方法更为推荐,即使用新的docker service命令,可以获得包括多主机网络等更高级的特性支持。
创建好Swarm集群后,可以在管理节点上执行如下命令来快速创建一个应用服务,并制定服务的复制份数为2。如下命令所示,默认会自动检查、确认服务状态都正常:

- (1)查看服务
此时使用service ls查看集群中的服务情况,会发现新创建的ping_app服务,还可以通过service inspect命令来查看服务的具体信息:


同时,管理节点和工作节点上都运行了一个容器,镜像为debian:jessie,命令为ping docker.com:

- (2)扩展服务
用户还可以通过docker service scale<SERVICE-ID>=<NUMBER-OF-TASKS>命令来对服务进行伸缩,例如将服务复制个数从2改为1:

服务使用完成后可以通过docker service rm<SERVICE-ID>命令删除。服务命令的更多参数可以通过dockerservice help命令查看。 - (3)使用外部服务地址
创建服务时使用--publish参数,将容器端口映射到节点上:

之后,用户访问集群中任意节点的,都会被Swarm的负载均衡器代理到对应的服务实例。用户也可以配置独立的负载均衡服务,后端指向集群中各个节点对应的外部端口,获取高可用特性。
2.11、更新集群
用户可以使用docker swarm update[OPTIONS]命令来更新一个集群,主要包括如下配置信息。
-autolock:启动或关闭管理节点的自动锁定。-cert-expiry duration:根证书的过期时长,默认为90天。-dispatcher-heartbeat duration:分配组件的心跳时长,默认为5s。-external-ca external-ca:指定使用外部的证书签名服务地址。-max-snapshots uint:Raft协议快照保留的个数。-snapshot-interval uint:Raft协议进行快照的间隔(单位为事务个数),默认为10000个。-task-history-limit int:任务历史的保留个数,默认为5。
2.12、离开集群
节点可以在任何时候通过swarm leave命令离开一个集群。命令格式为docker swarm leave[OPTIONS],支持-f,--force,意味着强制离开集群。
3、使用服务命令
Swarm提供了对应用服务的良好支持,使用Swarm集群可以充分满足应用服务可扩展、高可用的需求。
配合Swarm集群,Docker提供service命令来管理应用服务,主要包括以下子命令:
create:用于创建新的服务。通过该命令可以指定服务的名称、使用的镜像、启动参数、服务的副本数量、服务的网络等属性。inspect:用于查看服务的详细信息,例如服务的名称、ID、副本数量、任务信息等。logs:用于查看服务的日志信息,可以通过该命令获取服务的输出信息,便于排查问题。ls:用于列出当前Swarm集群中的所有服务,以及服务的相关信息,例如名称、ID、副本数量等。ps:用于列出指定服务的所有任务信息,例如任务的状态、运行时间、所在节点等。rm:用于删除指定的服务。rollback:用于回滚服务的更新,可以将服务回滚到指定的版本。scale:用于调整服务的副本数量,可以通过该命令来扩容或缩容服务。update:用于更新服务的配置信息,例如镜像版本、环境变量、容器启动参数等。
通过这些子命令,可以方便地管理Swarm集群中的服务,实现应用服务的可扩展和高可用。
3.1、create
docker service create命令用于在Swarm集群中创建应用服务,命令格式为docker service create [OPTIONS] IMAGE [COMMAND][ARG...]。
该命令支持许多参数,其中一些最有用的选项包括:
-config config:指定暴露给服务的配置。-constraint list:应用实例在集群中被放置时的位置限制。-d,-detach:不等待创建后对应用进行状态探测即返回。-dns list:自定义使用的DNS服务器地址。-endpoint-mode string:指定外部访问的模式,包括vip(虚拟IP自动负载均衡)或dnsrr(DNS轮询)。-e,-env list:环境变量列表。-health-cmd string:进行健康检查的指令。-l,-label list:执行服务的标签。-mode string:服务模式,包括replicated(默认)或global。-replicas uint:指定实例的副本数量。-secret secret:向服务暴露的机密数据。-u,-user string:指定用户信息,UID:GID。-w,-workdir string:指定容器中的工作目录位置。
用户可以通过docker service create-help命令查看完整的使用选项。
3.2、inspect
用户可以使用docker service inspect命令来查看指定服务的详细信息。命令格式为docker service inspect [OPTIONS] SERVICE [SERVICE...]。
其中,SERVICE参数为要查看详细信息的服务名或ID,也可以指定多个服务。
docker service inspect命令支持的选项包括:
-f,-format string:使用Go模板指定格式化输出。-pretty:以适合阅读的格式输出。
用户可以使用-f选项来自定义输出格式,使用-pretty选项可以以易读的方式输出详细信息。
3.3、logs
docker service logs用于获取某个服务或任务的日志信息,命令格式为docker service logs [OPTIONS] SERVICE|TASK。支持的参数主要包括:
-details:输出所有的细节日志信息。-f,-follow:持续跟随输出。-no-resolve:在输出中不将对象的ID映射为名称。-no-task-ids:输出中不包括任务的ID信息。-no-trunc:不截断输出信息。-raw:输出原始格式信息。-since string:输出自指定时间开始的日志,如2018-01-02T03:04:56或42m。-tail string:只输出给定行数的最新日志信息。-t,-timestamps:打印日志的时间戳。
3.4、ls
docker service ls命令用于列出Swarm集群中的所有服务信息,命令格式为docker service ls[OPTIONS]。支持的参数主要包括:
-f,-filter filter:只输出符合过滤条件的服务。-format string:按照Go模板格式化输出。-q,-quiet:只输出服务的ID信息。
3.5、ps
docker service ps用于查看服务的任务列表及其状态,命令格式为docker service ps [OPTIONS] SERVICE。支持的参数包括:
-filter value,-f value:指定筛选条件,如dockerservice ps-f desired-state=running SERVICE。-format string:指定输出格式,如docker service ps-format "{{.ID}}:{{.Name}}" SERVICE。-no-trunc:不截断输出信息。-no-resolve:在输出中不将对象的ID映射为名称。
3.6、rm
删除指定的若干服务。在执行该命令时,Swarm会首先将服务从集群中移除,然后停止所有服务实例,并最终删除服务及其关联的任何资源,命令格式为docker servicerm SERVICE [SERVICE...],支持的参数包括:
-f,-force:强制删除服务,即使它正在运行中。-no-prune:在删除服务后不清理其关联的未使用资源。-with-deps:同时删除服务所依赖的其他服务。
3.7、rollback
回滚服务的配置到上一个配置。如果回滚成功,那么输出的信息将包含回滚操作的ID和服务名称,命令格式为 docker service rollback [OPTIONS] SERVICE,支持的参数包括:
-d,-detach:在服务配置回滚后立即返回而不等待校验完成。-q,-quiet:安静模式,禁止输出进度信息。
3.8、scale
对服务进行横向扩展或缩减调整,命令格式为docker service scale SERVICE=REPLICAS [SERVICE=REPLICAS...],支持的参数主要为:-d,-detach,表示执行后返回,不等待服务状态校验完整。
3.9、update
该命令用于更新一个服务的配置信息,命令格式为docker service update [OPTIONS] SERVICE,支持的参数包括:
-args command:更新服务的命令参数。-config-add config:增加或更新一个服务的配置信息。-config-rm list:删除一个配置文件。-constraint-add list:增加或更新服务放置的限制条件。-constraint-rm list:删除一个限制条件。-d,-detach:执行命令后立即返回,不等待服务状态校验完整。-dns-add list:增加或更新服务的DNS服务信息。-dns-rm list:删除服务的DNS服务信息。-endpoint-mode string:指定服务外部访问的模式,包括vip(虚地址自动负载均衡)或dnsrr(DNS轮询)。-entrypoint command:指定服务的默认入口命令。-env-add list:添加或更新服务的一组环境变量。-env-rm list:删除服务的一组环境变量。-health-cmd string:更新服务的健康检查指令。-label-add list:添加或更新服务的一组标签信息。-label-rm list:删除服务的一组标签信息。-no-healthcheck:禁用服务的健康检查。-publish-add port:添加或更新服务的外部端口信息。
更新服务后可以使用docker service inspect命令查看当前服务的详细配置信息,以便更好地了解如何更新服务的配置。