您现在的位置是:首页 > 文章详情

docker CE on Linux示例浅析(四)swam群集配置

日期:2019-05-24点击:317

概述

github项目地址:https://github.com/superwujc

尊重原创,欢迎转载,注明出处:https://my.oschina.net/superwjc/blog/3053478

历史系列:

docker CE on Linux示例浅析(一)安装与基本运行

docker CE on Linux示例浅析(二)数据存储与持久化

docker CE on Linux示例浅析(三)镜像与容器管理

    每一个宿主机(包括物理机与虚拟机)通常仅运行一个docker主进程(单宿主机可以配置为运行多个docker主进程,但截至18.09.6版本,这一功能仍处于实验阶段,且存在诸多问题尚未解决,生产环境中应避免以该方式部署)。默认情况下,多个宿主机上的docker主进程之间相互独立,每个docker主进程仅可管理本地容器,称为独立容器( standalone container)模式。docker-ce自1.12版本起引入群集(swarm)模式,实现了docker主进程的集群化管理,包括容器分配,规模伸缩,负载均衡,更新回滚,以及网络设置等功能。

节点(node)

    群集内包含一或多个运行于swarm模式的宿主机,每个宿主机称为一个节点,分为2种角色等级:管理(manager)与工作(worker),具有相同角色的节点可以存在多个。角色可以在群集初始化时分配,或在群集初始化后更改。

    管理节点负责群集管理,包括维持群集状态,调度服务,以及处理swarm模式API调用(包括http请求与命令行接口),工作节点负责执行容器。除退出群集之外,非管理节点无法执行任何与群集、节点、服务相关的操作。默认情况下,管理节点同时也作为工作节点。swarm允许群集内仅存在单个管理节点,但不允许仅存在工作节点而无任一管理节点。

    swarm调度器根据节点的可用性(availability)决定是否为某个节点指派任务,包括:

  • Active:节点期望接受新任务。
  • Pause:节点不期望接受新任务,但现存的任务仍将在当前节点继续运行。
  • Drain:节点不期望接受新任务,现存的任务将被关闭,调度器重新分配相应数量的任务并指派至其他可用节点。

    节点的可用性可以在群集初始化时指定,默认为Active,或在群集初始化后更改。

    群集内包含多个管理节点时,仅其中一个为主管理节点,状态为Leader,其他均为备用管理节点,状态为Reachable。swarm通过Raft Consensus算法提供了管理节点的容错机制,可以实现管理节点在失效配额内的自动选举与切换功能。假设管理节点总数量为N,失效配额为M,则二者之间的关系为M = (N - 1) / 2,M的值向下取整。例如管理节点总数为5或6时,最多允许其中2个同时失效。失效的管理节点数量若在配额范围内,则swarm将在其他管理状态为Reachable的节点内自动选举一个新的主管理节点;若超出配额范围(包括仅存在单个管理节点的情况),则群集功能将不可用,必须手动重建群集以恢复故障。群集内容器的运行状态不受管理节点失效的影响,除非所有节点(包括管理节点与工作节点)在物理层面不可用。

    生产环境中应避免使用单管理节点群集,但管理节点之间执行的状态同步操作会产生额外的网络开销。docker官方推荐管理节点数量应尽量为奇数,且最大值为7,以更好地发挥swarm的容错功能。因此,群集内应至少部署3个管理节点,以提供基本的可用性与容错性。

服务(service)

    服务是swarm群集的主要操作对象,用于定义容器的期望运行状态,包括容器运行所使用的镜像与容器内部执行的命令,以及其他可配置的参数,如环境变量,开放端口,网络模式,系统资源,挂载选项,回滚更新策略等。服务的状态可以在命令行或配置文件中指定,swarm调度器根据服务状态的定义,将任务指派给可用的工作节点。

    服务分为2种运行模式:副本(replicated)与全局(global)。副本模式在所有工作节点中运行指定数量的任务,每个可用的节点上运行的任务数量由调度器分配;全局模式则在每一个可用的工作节点上都运行一个任务,任务的数量依赖于可用节点的数量。某一特定的服务仅可运行于两种模式之一,默认为副本模式。

任务(task)

    任务是swarm群集的原子性调度单元,容器从启动到终止构成对应任务的整个生存周期。容器是任务的实例化,二者之间具有一一对应的关系,而与容器相关的操作由工作节点上的docker主进程完成,因此任务与节点之间同样具有一一对应的关系。

    任务经分配后,具有以下状态,调度器根据这些状态持续监视容器与节点的运行情况:

  • NEW:任务已初始化。
  • PENDING:任务已就绪,等待指派。
  • ASSIGNED:任务已指派至节点。
  • ACCEPTED:任务已被工作节点接受,等待执行。
  • PREPARING:节点正在准备执行任务。
  • STARTING:任务正在启动。
  • RUNNING:任务正在运行。
  • COMPLETE:任务因执行成功而退出。
  • FAILED:任务因执行出错而退出。
  • SHUTDOWN:任务被节点关闭。
  • REJECTED:任务被节点拒绝。
  • ORPHANED:任务已指派,但节点长时间不可达。
  • REMOVE:任务未终止,但与之相关联的服务被移除,或减小规模。

    容器启动失败或因错误而终止时,调度器将分配一个新的任务,并尝试重新运行该容器。由于任务、节点与容器之间的对应关系,同一个任务只能运行在被指派的特定节点上,直到终止,而无法从一个节点转移至另一节点。

示例

    本节以tomcat容器为例,简述群集、服务与任务的基本管理。

环境

  • 宿主机3台:dock_host_0(192.168.9.168/24),dock_host_1(192.168.9.169/24),dock_host_2(192.168.9.170/24),系统与软件环境一致,均为全新最小化安装,单物理网卡,操作系统版本CentOS Linux release 7.6.1810 (Core),内核版本3.10.0-957.12.2.el7.x86_64,关闭selinux与防火墙。docker为默认安装,版本18.09.6,无其他额外设置。
  • 基础镜像为最新版CentOS 7官方镜像。
  • jdk环境以命名卷jdks的方式挂载至容器的/opt/jdks目录。
  • 源码包jdk-8u212-linux-x64.tar.gz与apache-tomcat-8.5.40.tar.gz,位于宿主机的/opt/目录。
  • tomcat环境位于容器的/opt/apps/app_0目录。

初始化群集

    群集的初始化包括创建(docker swarm init)与加入(docker swarm join),二者均开启docker引擎的swarm模式。

1. 创建群集。

docker swarm init命令用于创建群集,并将自身节点设置为主管理角色。

    宿主机docker_host_0创建群集,节点的管理状态为Leader:

[root@docker_host_0 ~]# ip addr show eth0 | sed -n '/inet /p' | awk '{print $2}' 192.168.9.168/24 [root@docker_host_0 ~]# [root@docker_host_0 ~]# uname -r 3.10.0-957.12.2.el7.x86_64 [root@docker_host_0 ~]# [root@docker_host_0 ~]# docker -v Docker version 18.09.6, build 481bc77156 [root@docker_host_0 ~]# [root@docker_host_0 ~]# docker swarm init Swarm initialized: current node (5h6m2fspnhtg0lr0x6d481qdr) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-4nsmenxl72484akypkevpirfse35u2ouxusbgemzzkuz0otgyv-434u94ack6bd9gwgxbvf2dqiw 192.168.9.168:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. [root@docker_host_0 ~]#

2. 查看节点属性。

docker node ls命令用于查看群集内的节点属性,包括:
ID:节点ID。
HOSTNAME:节点主机名。
STATUS:节点状态,Ready表示该节点可用,Down表示该节点已退出群集,Unknown表示该节点与管理节点之间的session同步出错。
AVAILABILITY:节点可用性(Active/Pause/Drain)。
MANAGER STATUS:管理状态/角色,Leader表示主管理节点,Reachable表示备用管理节点,为空表示仅为工作节点。
ENGINE VERSION:docker引擎版本。

[root@docker_host_0 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr * docker_host_0 Ready Active Leader 18.09.6 [root@docker_host_0 ~]#

3. 查看群集的加入方式。

docker swarm join-token --rotate manager/worker命令用于查看或设置(--rotate)管理节点/工作节点加入群集时使用的token,输出中包含docker主进程以相应角色加入群集的方式。

[root@docker_host_0 ~]# docker swarm join-token manager To add a manager to this swarm, run the following command: docker swarm join --token SWMTKN-1-4nsmenxl72484akypkevpirfse35u2ouxusbgemzzkuz0otgyv-381n4jpj6ur4il4k6qo0wifhq 192.168.9.168:2377 [root@docker_host_0 ~]# docker swarm join-token worker To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-4nsmenxl72484akypkevpirfse35u2ouxusbgemzzkuz0otgyv-434u94ack6bd9gwgxbvf2dqiw 192.168.9.168:2377 [root@docker_host_0 ~]#

4. 加入群集。

    根据管理节点中docker swarm join-token manager/worker命令的输出,分别将宿主机docker_host_1与docker_host_2以管理/工作角色加入群集。

[root@docker_host_1 ~]# ip addr show eth0 | sed -n '/inet /p' | awk '{print $2}' 192.168.9.169/24 [root@docker_host_1 ~]# [root@docker_host_1 ~]# uname -r 3.10.0-957.12.2.el7.x86_64 [root@docker_host_1 ~]# [root@docker_host_1 ~]# docker -v Docker version 18.09.6, build 481bc77156 [root@docker_host_1 ~]# [root@docker_host_1 ~]# docker swarm join --token SWMTKN-1-4nsmenxl72484akypkevpirfse35u2ouxusbgemzzkuz0otgyv-381n4jpj6ur4il4k6qo0wifhq 192.168.9.168:2377 This node joined a swarm as a manager. [root@docker_host_1 ~]# [root@docker_host_1 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr docker_host_0 Ready Active Leader 18.09.6 cos4ftcikaykcit9m15kqmvlh * docker_host_1 Ready Active Reachable 18.09.6 [root@docker_host_1 ~]#
[root@docker_host_2 ~]# ip addr show eth0 | sed -n '/inet /p' | awk '{print $2}' 192.168.9.170/24 [root@docker_host_2 ~]# [root@docker_host_2 ~]# uname -r 3.10.0-957.12.2.el7.x86_64 [root@docker_host_2 ~]# [root@docker_host_2 ~]# docker -v Docker version 18.09.6, build 481bc77156 [root@docker_host_2 ~]# [root@docker_host_2 ~]# docker swarm join --token SWMTKN-1-4nsmenxl72484akypkevpirfse35u2ouxusbgemzzkuz0otgyv-434u94ack6bd9gwgxbvf2dqiw 192.168.9.168:2377 This node joined a swarm as a worker. [root@docker_host_2 ~]# [root@docker_host_2 ~]# docker node ls Error response from daemon: This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager. [root@docker_host_2 ~]#

5. 设置节点角色。

docker node promote/demote命令用于对指定节点的角色进行升级/降级。
备用管理节点与主管理节点具有相同的群集操作权限。

    提升docker_host_2节点的角色等级:

[root@docker_host_1 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr docker_host_0 Ready Active Leader 18.09.6 cos4ftcikaykcit9m15kqmvlh * docker_host_1 Ready Active Reachable 18.09.6 rvomnj0q7aari989o3c4t6w02 docker_host_2 Ready Active 18.09.6 [root@docker_host_1 ~]# [root@docker_host_1 ~]# docker node promote docker_host_2 Node docker_host_2 promoted to a manager in the swarm. [root@docker_host_1 ~]# [root@docker_host_1 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr docker_host_0 Ready Active Leader 18.09.6 cos4ftcikaykcit9m15kqmvlh * docker_host_1 Ready Active Reachable 18.09.6 rvomnj0q7aari989o3c4t6w02 docker_host_2 Ready Active Reachable 18.09.6 [root@docker_host_1 ~]#

docker info命令可以查看群集相关的信息,包括是否开启swarm模式,群集ID,管理节点数,节点总数,管理节点IP,当前节点角色/ID/IP等。

[root@docker_host_1 ~]# docker info ... Swarm: active NodeID: cos4ftcikaykcit9m15kqmvlh Is Manager: true ClusterID: odbfcfeayjogvdn34m3nruq2f Managers: 3 Nodes: 3 Default Address Pool: 10.0.0.0/8 SubnetSize: 24 Orchestration: Task History Retention Limit: 5 Raft: Snapshot Interval: 10000 Number of Old Snapshots to Retain: 0 Heartbeat Tick: 1 Election Tick: 10 Dispatcher: Heartbeat Period: 5 seconds CA Configuration: Expiry Duration: 3 months Force Rotate: 0 Autolock Managers: false Root Rotation In Progress: false Node Address: 192.168.9.169 Manager Addresses: 192.168.9.168:2377 192.168.9.169:2377 192.168.9.170:2377 ... [root@docker_host_1 ~]#

    至此,群集内包含3个管理节点,docker_host_0为主管理节点,其余为备用管理节点。

运行全局服务

1. 准备应用镜像。

    在docker_host_0中以dockerfile方式构建镜像,名称为tomcat_app:8.5.40。

    设置tomcat:

server.xml中的pattern字段用于设置默认的访问日志格式,更改为%A:%{local}p %a:%{remote}p,表示本端IP:端口 对端IP:端口,以区分访问来源。

[root@docker_host_0 ~]# cd /opt/ [root@docker_host_0 opt]# [root@docker_host_0 opt]# ls apache-tomcat-8.5.40.tar.gz containerd jdk-8u212-linux-x64.tar.gz [root@docker_host_0 opt]# [root@docker_host_0 opt]# tar axf apache-tomcat-8.5.40.tar.gz [root@docker_host_0 opt]# [root@docker_host_0 opt]# sed -i 's/pattern="%h %l %u %t/pattern="%A:%{local}p %a:%{remote}p %t/' apache-tomcat-8.5.40/conf/server.xml [root@docker_host_0 opt]# [root@docker_host_0 opt]# sed -n '/pattern="%A:%/p' apache-tomcat-8.5.40/conf/server.xml pattern="%A:%{local}p %a:%{remote}p %t "%r" %s %b" /> [root@docker_host_0 opt]#

    设置数据卷,用于挂载jdk环境:

[root@docker_host_0 opt]# docker volume create jdks jdks [root@docker_host_0 opt]# [root@docker_host_0 opt]# tar axf jdk-8u212-linux-x64.tar.gz -C /var/lib/docker/volumes/jdks/_data/ [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker volume ls DRIVER VOLUME NAME local jdks [root@docker_host_0 opt]#

    设置dockerfile:

[root@docker_host_0 opt]# vi dockerfile-for-tomcat FROM centos:latest COPY apache-tomcat-8.5.40 /opt/apps/app_0 EXPOSE 8080 ENV JAVA_HOME /opt/jdks/jdk1.8.0_212 WORKDIR /opt/apps/app_0 CMD bin/catalina.sh run [root@docker_host_0 opt]#

    编译镜像:

[root@docker_host_0 opt]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker build -f dockerfile-for-tomcat -t tomcat_app:8.5.40 . Sending build context to Docker daemon 219.1MB Step 1/6 : FROM centos:latest latest: Pulling from library/centos 8ba884070f61: Pull complete Digest: sha256:b5e66c4651870a1ad435cd75922fe2cb943c9e973a9673822d1414824a1d0475 Status: Downloaded newer image for centos:latest ---> 9f38484d220f Step 2/6 : COPY apache-tomcat-8.5.40 /opt/apps/app_0 ---> 155b18437d11 Step 3/6 : EXPOSE 8080 ---> Running in 93fdd5ea8433 Removing intermediate container 93fdd5ea8433 ---> 1c2487ffdd9b Step 4/6 : ENV JAVA_HOME /opt/jdks/jdk1.8.0_212 ---> Running in 2ef953a36a71 Removing intermediate container 2ef953a36a71 ---> 459c7c25ccc2 Step 5/6 : WORKDIR /opt/apps/app_0 ---> Running in 8dc1cde1177e Removing intermediate container 8dc1cde1177e ---> 35af515cc94f Step 6/6 : CMD bin/catalina.sh run ---> Running in 6733ba74c3d0 Removing intermediate container 6733ba74c3d0 ---> 74df48f4f0fc Successfully built 74df48f4f0fc Successfully tagged tomcat_app:8.5.40 [root@docker_host_0 opt]# [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE tomcat_app 8.5.40 74df48f4f0fc 5 seconds ago 216MB centos latest 9f38484d220f 2 months ago 202MB [root@docker_host_0 opt]#

2. 创建全局服务。

    在节点docker_host_0上,以tomcat_app:8.5.40镜像创建服务(docker service create),模式(--mode)为全局,名称(--name)为webapp_g,挂载(--mount)数据卷,开放端口(-p/--publish)8080:

[root@docker_host_0 opt]# docker service create --name webapp_g --mount type=volume,src=jdks,dst=/opt/jdks --mode global -p 8080:8080 tomcat_app:8.5.40 image tomcat_app:8.5.40 could not be accessed on a registry to record its digest. Each node will access tomcat_app:8.5.40 independently, possibly leading to different nodes running different versions of the image. kp6qdrzoswljwfmiphh19pogv overall progress: 1 out of 3 tasks 5h6m2fspnhtg: running rvomnj0q7aar: No such image: tomcat_app:8.5.40 cos4ftcikayk: No such image: tomcat_app:8.5.40 ^COperation continuing in background. Use `docker service ps kp6qdrzoswljwfmiphh19pogv` to check progress. [root@docker_host_0 opt]#

3. 查看服务属性。

docker service ls命令用于查看当前群集中运行的服务列表与相关信息,包括:
ID:服务ID。
NAME:服务名称。
MODE:服务运行模式(global/replicated)。
REPLICAS:成功分配的任务数/请求分配的任务数。
IMAGE:镜像名称。
PORTS:开放端口与协议。

[root@docker_host_0 opt]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS kp6qdrzoswlj webapp_g global 1/3 tomcat_app:8.5.40 *:8080->8080/tcp [root@docker_host_0 opt]#

4. 查看任务属性。

docker service ps命令用于查看指定服务中的任务执行情况,包括:
ID:任务ID。
NAME:任务对应的容器名称。
IMAGE:镜像名称。
NODE:任务指派的节点。
DESIRED STATE:任务的期望状态。
CURRENT STATE:任务的当前状态。
ERROR:错误信息。
PORTS:开放端口。
-f/--filter选项以键值对的方式过滤输出,当前支持的键包括id/name/node/desired-state,分别对应以上参数。

[root@docker_host_0 opt]# docker service ps -f "node=docker_host_0" webapp_g ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS ncd0lscuk5ts webapp_g.5h6m2fspnhtg0lr0x6d481qdr tomcat_app:8.5.40 docker_host_0 Running Running about a minute ago [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker service ps -f "node=docker_host_1" webapp_g ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS umkwfusbj5rt webapp_g.cos4ftcikaykcit9m15kqmvlh tomcat_app:8.5.40 docker_host_1 Ready Preparing 3 seconds ago bp49pjyqh5ku \_ webapp_g.cos4ftcikaykcit9m15kqmvlh tomcat_app:8.5.40 docker_host_1 Shutdown Rejected 3 seconds ago "No such image: tomcat_app:8.5…" qepo1tzhcz68 \_ webapp_g.cos4ftcikaykcit9m15kqmvlh tomcat_app:8.5.40 docker_host_1 Shutdown Rejected 8 seconds ago "No such image: tomcat_app:8.5…" 2gg2f0d8d3tk \_ webapp_g.cos4ftcikaykcit9m15kqmvlh tomcat_app:8.5.40 docker_host_1 Shutdown Rejected 15 seconds ago "No such image: tomcat_app:8.5…" rc41gutotc64 \_ webapp_g.cos4ftcikaykcit9m15kqmvlh tomcat_app:8.5.40 docker_host_1 Shutdown Rejected 21 seconds ago "No such image: tomcat_app:8.5…" [root@docker_host_0 opt]# [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker service ps -f "node=docker_host_2" webapp_g ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS k8iyvkp5iv14 webapp_g.rvomnj0q7aari989o3c4t6w02 tomcat_app:8.5.40 docker_host_2 Ready Rejected 1 second ago "No such image: tomcat_app:8.5…" wbxd2787npfl \_ webapp_g.rvomnj0q7aari989o3c4t6w02 tomcat_app:8.5.40 docker_host_2 Shutdown Rejected 5 seconds ago "No such image: tomcat_app:8.5…" tv7x0fl8qwpe \_ webapp_g.rvomnj0q7aari989o3c4t6w02 tomcat_app:8.5.40 docker_host_2 Shutdown Rejected 11 seconds ago "No such image: tomcat_app:8.5…" vatre7kv4ggt \_ webapp_g.rvomnj0q7aari989o3c4t6w02 tomcat_app:8.5.40 docker_host_2 Shutdown Rejected 16 seconds ago "No such image: tomcat_app:8.5…" xge3egwymkmj \_ webapp_g.rvomnj0q7aari989o3c4t6w02 tomcat_app:8.5.40 docker_host_2 Shutdown Rejected 22 seconds ago "No such image: tomcat_app:8.5…" [root@docker_host_0 opt]#

    全局模式的服务在每一个可用节点上都运行一个任务实例,但docker_host_1与docker_host_2节点的本地与镜像仓库不存在tomcat_app:8.5.40镜像,因此另2个任务实例一直因"No such image"错误而被节点拒绝(任务状态为Rejected),随后分配新的任务再次尝试执行。

    群集服务隐藏了容器的运行细节,对外表现为相同的形式。向任一节点发送请求均可访问,即使指定的容器未运行在该节点,调度器会将传入的连接分配至群集内成功运行的容器。

    docker_host_0节点上的任务成功执行,指定的容器运行且端口已开启:

[root@docker_host_0 opt]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8330cf1374db tomcat_app:8.5.40 "/bin/sh -c 'bin/cat…" 4 minutes ago Up 4 minutes 8080/tcp webapp_g.5h6m2fspnhtg0lr0x6d481qdr.ncd0lscuk5tsvsdmcqse3vibm [root@docker_host_0 opt]# [root@docker_host_0 opt]# ss -atn | grep 8080 LISTEN 0 128 :::8080 :::* [root@docker_host_0 opt]#

    docker_host_1与docker_host_2节点上的任务未成功执行,但端口依然开启,且可提供访问:

[root@docker_host_1 ~]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@docker_host_1 ~]# [root@docker_host_1 ~]# ss -atn | grep 8080 LISTEN 0 128 :::8080 :::* [root@docker_host_1 ~]# [root@docker_host_1 ~]# curl -I -o /dev/null -s -w %{http_code} 192.168.9.168:8080 200 [root@docker_host_1 ~]# curl -I -o /dev/null -s -w %{http_code} 192.168.9.169:8080 200 [root@docker_host_1 ~]# curl -I -o /dev/null -s -w %{http_code} 192.168.9.170:8080 200 [root@docker_host_1 ~]#
[root@docker_host_2 ~]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@docker_host_2 ~]# [root@docker_host_2 ~]# ss -atn | grep 8080 LISTEN 0 128 :::8080 :::* [root@docker_host_2 ~]# [root@docker_host_2 ~]# curl -I -o /dev/null -s -w %{http_code} 192.168.9.168:8080 200 [root@docker_host_2 ~]# curl -I -o /dev/null -s -w %{http_code} 192.168.9.169:8080 200 [root@docker_host_2 ~]# curl -I -o /dev/null -s -w %{http_code} 192.168.9.170:8080 200 [root@docker_host_2 ~]#

5. 设置节点可用性。

docker swarm init/join命令的--availability选项用于在创建/加入群集时设置节点的可用性,默认为active。

docker node update命令用于设置指定节点的可用性(--availability "active"|"pause"|"drain"),标签(--label-add/--label-rm)与角色(--role "worker"|"manager")

    将docker_host_1节点的可用性更改为pause,docker_host_2节点的可用性更改为drain:

[root@docker_host_1 ~]# docker node update --availability pause docker_host_1 docker_host_1 [root@docker_host_1 ~]# docker node update --availability drain docker_host_2 docker_host_2 [root@docker_host_1 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr docker_host_0 Ready Active Leader 18.09.6 cos4ftcikaykcit9m15kqmvlh * docker_host_1 Ready Pause Reachable 18.09.6 rvomnj0q7aari989o3c4t6w02 docker_host_2 Ready Drain Reachable 18.09.6 [root@docker_host_1 ~]#

    docker_host_1与docker_host_2节点因镜像不存在而拒绝了任务,处于关闭状态,因此将二者的节点可用性更改为pause与drain后,服务请求分配的任务数从3变为1,先前失败的2个任务不再尝试执行,结果为仅docker_host_1节点上运行了1个任务(容器)。

[root@docker_host_0 opt]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS kp6qdrzoswlj webapp_g global 1/1 tomcat_app:8.5.40 *:8080->8080/tcp [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker service ps -f 'desired-state=running' webapp_g ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS ncd0lscuk5ts webapp_g.5h6m2fspnhtg0lr0x6d481qdr tomcat_app:8.5.40 docker_host_0 Running Running 40 minutes ago [root@docker_host_0 opt]#

6. 节点角色降级。

    将docker_host_1与docker_host_2节点的角色降级为非管理节点:

[root@docker_host_0 opt]# docker node demote docker_host_1 Manager docker_host_1 demoted in the swarm. [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker node demote docker_host_2 Manager docker_host_2 demoted in the swarm. [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr * docker_host_0 Ready Active Leader 18.09.6 cos4ftcikaykcit9m15kqmvlh docker_host_1 Ready Pause 18.09.6 rvomnj0q7aari989o3c4t6w02 docker_host_2 Ready Drain 18.09.6 [root@docker_host_0 opt]#

7. 退出群集。

退出群集是非管理节点有权限执行的唯一群集相关操作,包括docker swarm leave命令与POST /swarm/leave接口,二者效果相同。执行退出操作后,swarm模式随之关闭。

docker守护进程默认监听在本地的UNIX域套接字/var/run/docker.sock。

    docker_host_1节点通过命令行接口退出群集:

[root@docker_host_1 ~]# docker swarm leave Node left the swarm. [root@docker_host_1 ~]# [root@docker_host_1 ~]# docker info -f '{{.Swarm}}' { inactive false [] 0 0 <nil>} [root@docker_host_1 ~]#

    docker_host_2节点执行HTTP API退出群集:

[root@docker_host_2 ~]# curl -0 -i -X POST --unix-socket /var/run/docker.sock http:/swarm/leave HTTP/1.0 200 OK Api-Version: 1.39 Docker-Experimental: false Ostype: linux Server: Docker/18.09.6 (linux) Date: Fri, 24 May 2019 05:04:55 GMT Content-Length: 0 [root@docker_host_2 ~]# docker info -f '{{.Swarm}}' { inactive false [] 0 0 <nil>} [root@docker_host_2 ~]#

    退出群集后,相应节点的信息条目仍然存在,但状态变为Down:

[root@docker_host_0 opt]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr * docker_host_0 Ready Active Leader 18.09.6 cos4ftcikaykcit9m15kqmvlh docker_host_1 Down Pause 18.09.6 rvomnj0q7aari989o3c4t6w02 docker_host_2 Down Drain 18.09.6 [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker info -f '{{.Swarm.Nodes}}' 3 [root@docker_host_0 opt]#

8. 移除节点。

docker node rm命令用于从群集内移除指定节点。

    将docker_host_1与docker_host_2节点从群集内移除:

[root@docker_host_0 opt]# docker node rm docker_host_1 docker_host_1 [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker node rm docker_host_2 docker_host_2 [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr * docker_host_0 Ready Active Leader 18.09.6 [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker info -f '{{.Swarm.Nodes}}' 1 [root@docker_host_0 opt]#

9. 移除服务。

docker service rm命令用于从群集内移除指定的服务。

    将webapp_g服务从群集内移除:

[root@docker_host_0 opt]# docker service rm webapp_g webapp_g [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@docker_host_0 opt]#

    将宿主机docker_host_1与docker_host_2重新以管理角色加入群集:

[root@docker_host_0 opt]# docker swarm join-token --rotate manager Successfully rotated manager join token. To add a manager to this swarm, run the following command: docker swarm join --token SWMTKN-1-4nsmenxl72484akypkevpirfse35u2ouxusbgemzzkuz0otgyv-cav7ypxfv6hzuyz5hq7jvn87l 192.168.9.168:2377 [root@docker_host_0 opt]#
[root@docker_host_1 ~]# docker swarm join --token SWMTKN-1-4nsmenxl72484akypkevpirfse35u2ouxusbgemzzkuz0otgyv-cav7ypxfv6hzuyz5hq7jvn87l 192.168.9.168:2377 This node joined a swarm as a manager. [root@docker_host_1 ~]# [root@docker_host_1 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr docker_host_0 Ready Active Leader 18.09.6 upn0vc4vx47224gxaxn6hwec9 * docker_host_1 Ready Active Reachable 18.09.6 [root@docker_host_1 ~]#
[root@docker_host_2 ~]# docker swarm join --token SWMTKN-1-4nsmenxl72484akypkevpirfse35u2ouxusbgemzzkuz0otgyv-cav7ypxfv6hzuyz5hq7jvn87l 192.168.9.168:2377 This node joined a swarm as a manager. [root@docker_host_2 ~]# [root@docker_host_2 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr docker_host_0 Ready Active Leader 18.09.6 upn0vc4vx47224gxaxn6hwec9 docker_host_1 Ready Active Reachable 18.09.6 jekdpdzmwcxrdfsxaudzbdp2z * docker_host_2 Ready Active Reachable 18.09.6 [root@docker_host_2 ~]#

    至此,群集内仍保持3个管理节点,docker_host_0为主管理节点。

运行副本服务

1. 导入镜像。

    在docker_host_0节点上将镜像tomcat_app:8.5.40打包,并传输至docker_host_1与docker_host_2节点:

[root@docker_host_0 opt]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE tomcat_app 8.5.40 74df48f4f0fc About an hour ago 216MB centos latest 9f38484d220f 2 months ago 202MB [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker image save tomcat_app:8.5.40 -o tomcat_app.tar [root@docker_host_0 opt]# [root@docker_host_0 opt]# ll -h tomcat_app.tar -rw------- 1 root root 214M May 24 05:28 tomcat_app.tar [root@docker_host_0 opt]# [root@docker_host_0 opt]# scp tomcat_app.tar root@192.168.9.169:/opt tomcat_app.tar 100% 214MB 78.5MB/s 00:02 [root@docker_host_0 opt]# scp tomcat_app.tar root@192.168.9.170:/opt tomcat_app.tar 100% 214MB 96.0MB/s 00:02 [root@docker_host_0 opt]#

    在docker_host_1与docker_host_2节点上分别导入镜像,并设置jdk环境所需的数据卷:

[root@docker_host_1 ~]# cd /opt/ [root@docker_host_1 opt]# [root@docker_host_1 opt]# ls containerd jdk-8u212-linux-x64.tar.gz tomcat_app.tar [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker image load -i tomcat_app.tar d69483a6face: Loading layer 209.5MB/209.5MB 59eb00de447b: Loading layer 14.39MB/14.39MB Loaded image: tomcat_app:8.5.40 [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE tomcat_app 8.5.40 74df48f4f0fc About an hour ago 216MB [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker volume create jdks jdks [root@docker_host_1 opt]# [root@docker_host_1 opt]# tar axf jdk-8u212-linux-x64.tar.gz -C /var/lib/docker/volumes/jdks/_data/ [root@docker_host_1 opt]#
[root@docker_host_2 ~]# cd /opt/ [root@docker_host_2 opt]# [root@docker_host_2 opt]# ls containerd jdk-8u212-linux-x64.tar.gz tomcat_app.tar [root@docker_host_2 opt]# [root@docker_host_2 opt]# docker image load -i tomcat_app.tar d69483a6face: Loading layer 209.5MB/209.5MB 59eb00de447b: Loading layer 14.39MB/14.39MB Loaded image: tomcat_app:8.5.40 [root@docker_host_2 opt]# [root@docker_host_2 opt]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE tomcat_app 8.5.40 74df48f4f0fc About an hour ago 216MB [root@docker_host_2 opt]# [root@docker_host_2 opt]# docker volume create jdks jdks [root@docker_host_2 opt]# [root@docker_host_2 opt]# tar axf jdk-8u212-linux-x64.tar.gz -C /var/lib/docker/volumes/jdks/_data/ [root@docker_host_2 opt]#

2. 创建副本服务。

docker service create命令不指定--mode选项,则默认创建副本模式的服务,且数量为1。

    以副本模式执行tomcat_app:8.5.40镜像,数量(--replicas)为3,名称为webapp_d:

[root@docker_host_1 opt]# docker service create --name webapp_d --mount type=volume,src=jdks,dst=/opt/jdks --replicas 3 -p 8080:8080 tomcat_app:8.5.40 image tomcat_app:8.5.40 could not be accessed on a registry to record its digest. Each node will access tomcat_app:8.5.40 independently, possibly leading to different nodes running different versions of the image. hmhqo34e46m1syf4eoawre3fx overall progress: 3 out of 3 tasks 1/3: running 2/3: running 3/3: running verify: Service converged [root@docker_host_1 opt]#

    任务被平均指派至3个节点并成功运行:

[root@docker_host_1 opt]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS hmhqo34e46m1 webapp_d replicated 3/3 tomcat_app:8.5.40 *:8080->8080/tcp [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker service ps webapp_d ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS e2eynnrned2j webapp_d.1 tomcat_app:8.5.40 docker_host_1 Running Running 6 minutes ago nd8qg74l4t7b webapp_d.2 tomcat_app:8.5.40 docker_host_2 Running Running 6 minutes ago e2ef0oc66sqh webapp_d.3 tomcat_app:8.5.40 docker_host_0 Running Running 6 minutes ago [root@docker_host_1 opt]#

3. 更改节点可用性(pause)。

    将docker_host_2节点的可用性更改为pause:

[root@docker_host_1 opt]# docker node update --availability pause docker_host_2 docker_host_2 [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr docker_host_0 Ready Active Leader 18.09.6 upn0vc4vx47224gxaxn6hwec9 * docker_host_1 Ready Active Reachable 18.09.6 jekdpdzmwcxrdfsxaudzbdp2z docker_host_2 Ready Pause Reachable 18.09.6 [root@docker_host_1 opt]#

    docker_host_2节点上正在运行的任务仍继续运行:

[root@docker_host_1 opt]# docker service ps webapp_d ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS e2eynnrned2j webapp_d.1 tomcat_app:8.5.40 docker_host_1 Running Running 15 minutes ago nd8qg74l4t7b webapp_d.2 tomcat_app:8.5.40 docker_host_2 Running Running 15 minutes ago e2ef0oc66sqh webapp_d.3 tomcat_app:8.5.40 docker_host_0 Running Running 15 minutes ago [root@docker_host_1 opt]#

4. 更改副本规模。

docker service scale命令用于更改副本服务的运行数量,参数格式为服务名或ID=值,指定的值为最终运行的副本数量,可以增大或减小。

    将服务的副本数量设置为6: 

[root@docker_host_1 opt]# docker service scale webapp_d=6 webapp_d scaled to 6 overall progress: 6 out of 6 tasks 1/6: running 2/6: running 3/6: running 4/6: running 5/6: running 6/6: running verify: Service converged [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS hmhqo34e46m1 webapp_d replicated 6/6 tomcat_app:8.5.40 *:8080->8080/tcp [root@docker_host_1 opt]#

    docker_host_2节点的可用性为pause,因此不再接受新的任务,新增的3个任务被指派至另2个节点:

[root@docker_host_1 opt]# docker service ps webapp_d ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS e2eynnrned2j webapp_d.1 tomcat_app:8.5.40 docker_host_1 Running Running 21 minutes ago nd8qg74l4t7b webapp_d.2 tomcat_app:8.5.40 docker_host_2 Running Running 21 minutes ago e2ef0oc66sqh webapp_d.3 tomcat_app:8.5.40 docker_host_0 Running Running 21 minutes ago 67mfqjvqgi7b webapp_d.4 tomcat_app:8.5.40 docker_host_0 Running Running 2 minutes ago qrdqrzm2f6si webapp_d.5 tomcat_app:8.5.40 docker_host_1 Running Running 2 minutes ago mejk0zee8ovy webapp_d.6 tomcat_app:8.5.40 docker_host_1 Running Running 2 minutes ago [root@docker_host_1 opt]#

5. 更改节点可用性(drain)。

    将docker_host_2节点的可用性更改为drain:

[root@docker_host_1 opt]# docker node update --availability drain docker_host_2 docker_host_2 [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr docker_host_0 Ready Active Leader 18.09.6 upn0vc4vx47224gxaxn6hwec9 * docker_host_1 Ready Active Reachable 18.09.6 jekdpdzmwcxrdfsxaudzbdp2z docker_host_2 Ready Drain Reachable 18.09.6 [root@docker_host_1 opt]#

    副本总数未改变,但docker_host_2节点上先前运行的任务(nd8qg74l4t7b)被关闭,新的任务(tuuq6q1tlcib)被指派至docker_host_0节点,结果为docker_host_0与docker_host_1节点各自运行3个任务:

[root@docker_host_1 opt]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS hmhqo34e46m1 webapp_d replicated 6/6 tomcat_app:8.5.40 *:8080->8080/tcp [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker service ps webapp_d ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS e2eynnrned2j webapp_d.1 tomcat_app:8.5.40 docker_host_1 Running Running 28 minutes ago tuuq6q1tlcib webapp_d.2 tomcat_app:8.5.40 docker_host_0 Running Running 13 seconds ago nd8qg74l4t7b \_ webapp_d.2 tomcat_app:8.5.40 docker_host_2 Shutdown Shutdown 15 seconds ago e2ef0oc66sqh webapp_d.3 tomcat_app:8.5.40 docker_host_0 Running Running 28 minutes ago 67mfqjvqgi7b webapp_d.4 tomcat_app:8.5.40 docker_host_0 Running Running 9 minutes ago qrdqrzm2f6si webapp_d.5 tomcat_app:8.5.40 docker_host_1 Running Running 9 minutes ago mejk0zee8ovy webapp_d.6 tomcat_app:8.5.40 docker_host_1 Running Running 9 minutes ago [root@docker_host_1 opt]#

    docker_host_2节点上的容器退出,但端口依然开放,且可对外提供访问:

[root@docker_host_2 opt]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 50187866b04e tomcat_app:8.5.40 "/bin/sh -c 'bin/cat…" 36 minutes ago Exited (143) 8 minutes ago webapp_d.2.nd8qg74l4t7b2oju7bzs9qsk1 [root@docker_host_2 opt]# [root@docker_host_2 opt]# ss -atn | grep 8080 LISTEN 0 128 :::8080 :::* [root@docker_host_2 opt]#
[root@docker_host_1 opt]# curl -I -o /dev/null -s -w %{http_code} 192.168.9.170:8080 200 [root@docker_host_1 opt]#

    至此,群集内依然保持3个管理节点,docker_host_0为主管理节点。

故障恢复

    3个管理节点的失效配额为(3 - 1) / 2 = 1,若失效数量若小于或等于配额,则swarm自动执行选举与切换;若超出配额范围,则须手动强制重建群集(docker swarm init -f/--force)。

    出现故障时,需要查看群集、节点、服务、任务等信息,结合命令行输出与日志对故障原因进行定位。CentOS 7下的docker日志文件默认为/var/log/message,可设置为单独的文件,参考docker CE on Linux示例浅析(一)安装与基本运行

    管理节点的/var/lib/docker/swarm/目录用于保存群集状态与管理日志,可以按备份目录-导入目录-重建群集的步骤执行故障恢复。docker官方建议备份与导入操作在docker主进程停用后执行。

1. 故障模拟。

    将主管理节点docker_host_0中的docker守护进程停止:

[root@docker_host_0 opt]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr * docker_host_0 Ready Active Leader 18.09.6 upn0vc4vx47224gxaxn6hwec9 docker_host_1 Ready Active Reachable 18.09.6 jekdpdzmwcxrdfsxaudzbdp2z docker_host_2 Ready Drain Reachable 18.09.6 [root@docker_host_0 opt]# [root@docker_host_0 opt]# systemctl stop docker [root@docker_host_0 opt]#

    主管理角色自动切换至docker_host_2节点,群集相关的功能不受影响,但docker_host_0节点的状态先后变为Unknown与Down,管理状态变为Unreachable:

[root@docker_host_1 opt]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr docker_host_0 Unknown Active Unreachable 18.09.6 upn0vc4vx47224gxaxn6hwec9 * docker_host_1 Ready Active Reachable 18.09.6 jekdpdzmwcxrdfsxaudzbdp2z docker_host_2 Ready Drain Leader 18.09.6 [root@docker_host_1 opt]#

    副本数量未改变,但先前运行在docker_host_0节点上的3个任务都被关闭,新分配的任务被指派至docker_host_1节点,结果为docker_host_1节点上运行了6个任务:

[root@docker_host_1 opt]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS hmhqo34e46m1 webapp_d replicated 6/6 tomcat_app:8.5.40 *:8080->8080/tcp [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker service ps webapp_d ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS e2eynnrned2j webapp_d.1 tomcat_app:8.5.40 docker_host_1 Running Running 2 minutes ago wnrm2ndqjk7r webapp_d.2 tomcat_app:8.5.40 docker_host_1 Running Running 2 minutes ago tuuq6q1tlcib \_ webapp_d.2 tomcat_app:8.5.40 docker_host_0 Shutdown Running 16 minutes ago nd8qg74l4t7b \_ webapp_d.2 tomcat_app:8.5.40 docker_host_2 Shutdown Shutdown 16 minutes ago xazm6xhtji5d webapp_d.3 tomcat_app:8.5.40 docker_host_1 Running Running 2 minutes ago e2ef0oc66sqh \_ webapp_d.3 tomcat_app:8.5.40 docker_host_0 Shutdown Running 44 minutes ago oervwdwtj9ei webapp_d.4 tomcat_app:8.5.40 docker_host_1 Running Running 2 minutes ago 67mfqjvqgi7b \_ webapp_d.4 tomcat_app:8.5.40 docker_host_0 Shutdown Running 25 minutes ago qrdqrzm2f6si webapp_d.5 tomcat_app:8.5.40 docker_host_1 Running Running 2 minutes ago mejk0zee8ovy webapp_d.6 tomcat_app:8.5.40 docker_host_1 Running Running 2 minutes ago [root@docker_host_1 opt]#

    将管理节点docker_host_2中的docker守护进程停止:

[root@docker_host_2 opt]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr docker_host_0 Down Active Unreachable 18.09.6 upn0vc4vx47224gxaxn6hwec9 docker_host_1 Ready Active Reachable 18.09.6 jekdpdzmwcxrdfsxaudzbdp2z * docker_host_2 Ready Drain Leader 18.09.6 [root@docker_host_2 opt]# [root@docker_host_2 opt]# systemctl stop docker [root@docker_host_2 opt]#

    群集功能不可用,但仍可访问运行中的容器:

[root@docker_host_1 opt]# docker node ls Error response from daemon: rpc error: code = DeadlineExceeded desc = context deadline exceeded [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker service ls Error response from daemon: rpc error: code = Unknown desc = The swarm does not have a leader. It's possible that too few managers are online. Make sure more than half of the managers are online. [root@docker_host_1 opt]# docker service ps webapp_g Error response from daemon: rpc error: code = Unknown desc = The swarm does not have a leader. It's possible that too few managers are online. Make sure more than half of the managers are online. [root@docker_host_1 opt]# docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES da48a25cf5b2 tomcat_app:8.5.40 "/bin/sh -c 'bin/cat…" 13 minutes ago Up 13 minutes 8080/tcp webapp_d.4.oervwdwtj9eixi9ye225bfaqu 2cfc8b941397 tomcat_app:8.5.40 "/bin/sh -c 'bin/cat…" 13 minutes ago Up 13 minutes 8080/tcp webapp_d.2.wnrm2ndqjk7r6couisn3jhuuv c419aa6ac995 tomcat_app:8.5.40 "/bin/sh -c 'bin/cat…" 13 minutes ago Up 13 minutes 8080/tcp webapp_d.3.xazm6xhtji5dir6xed8gdmmim 577267e59128 tomcat_app:8.5.40 "/bin/sh -c 'bin/cat…" 37 minutes ago Up 37 minutes 8080/tcp webapp_d.6.mejk0zee8ovyiukv2yxh88n4s bfa09130f72f tomcat_app:8.5.40 "/bin/sh -c 'bin/cat…" 37 minutes ago Up 37 minutes 8080/tcp webapp_d.5.qrdqrzm2f6siee5pz7a84p6gi 9c9455285a21 tomcat_app:8.5.40 "/bin/sh -c 'bin/cat…" About an hour ago Up About an hour 8080/tcp webapp_d.1.e2eynnrned2j9732uhf1v0dhi [root@docker_host_1 opt]# [root@docker_host_1 opt]# ss -atn | grep 8080 LISTEN 0 128 :::8080 :::* [root@docker_host_1 opt]# [root@docker_host_1 opt]# curl -I -o /dev/null -s -w %{http_code} 192.168.9.169:8080 200

2. 重建群集。

    在docker_host_1节点上手动强制重建群集,并移除失效的docker_host_0与docker_host_2节点:

[root@docker_host_1 opt]# docker swarm init --force-new-cluster Swarm initialized: current node (upn0vc4vx47224gxaxn6hwec9) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-4nsmenxl72484akypkevpirfse35u2ouxusbgemzzkuz0otgyv-434u94ack6bd9gwgxbvf2dqiw 192.168.9.169:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 5h6m2fspnhtg0lr0x6d481qdr docker_host_0 Down Active 18.09.6 upn0vc4vx47224gxaxn6hwec9 * docker_host_1 Ready Active Leader 18.09.6 jekdpdzmwcxrdfsxaudzbdp2z docker_host_2 Unknown Drain 18.09.6 [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker node rm docker_host_0 docker_host_0 [root@docker_host_1 opt]# docker node rm docker_host_2 docker_host_2 [root@docker_host_1 opt]#

    由于docker_host_1节点的/var/lib/docker/swarm/目录保存了群集状态数据,因此执行重建后,群集ID与先前一致(odbfcfeayjogvdn34m3nruq2f),表明并未创建新的群集。

[root@docker_host_1 opt]# ll /var/lib/docker/swarm/ total 8 drwxr-xr-x 2 root root 75 May 24 05:10 certificates -rw------- 1 root root 193 May 24 07:24 docker-state.json drwx------ 4 root root 55 May 24 05:10 raft -rw------- 1 root root 69 May 24 07:24 state.json drwxr-xr-x 2 root root 22 May 24 05:10 worker [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker info -f '{{.Swarm.Cluster.ID}}' odbfcfeayjogvdn34m3nruq2f [root@docker_host_1 opt]# [root@docker_host_1 opt]# docker swarm join-token manager To add a manager to this swarm, run the following command: docker swarm join --token SWMTKN-1-4nsmenxl72484akypkevpirfse35u2ouxusbgemzzkuz0otgyv-cav7ypxfv6hzuyz5hq7jvn87l 192.168.9.169:2377 [root@docker_host_1 opt]#

    故障节点docker_host_0与docker_host_2强制脱离群集后,以管理角色重新加入:

[root@docker_host_0 opt]# systemctl start docker [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker swarm leave -f Node left the swarm. [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker swarm join --token SWMTKN-1-4nsmenxl72484akypkevpirfse35u2ouxusbgemzzkuz0otgyv-cav7ypxfv6hzuyz5hq7jvn87l 192.168.9.169:2377 This node joined a swarm as a manager. [root@docker_host_0 opt]# [root@docker_host_0 opt]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION i6jberxzc51hprbtgh94e1nzw * docker_host_0 Ready Active Reachable 18.09.6 upn0vc4vx47224gxaxn6hwec9 docker_host_1 Ready Active Leader 18.09.6 [root@docker_host_0 opt]#
[root@docker_host_2 opt]# systemctl start docker [root@docker_host_2 opt]# [root@docker_host_2 opt]# docker swarm leave -f Node left the swarm. [root@docker_host_2 opt]# [root@docker_host_2 opt]# docker swarm join --token SWMTKN-1-4nsmenxl72484akypkevpirfse35u2ouxusbgemzzkuz0otgyv-cav7ypxfv6hzuyz5hq7jvn87l 192.168.9.169:2377 This node joined a swarm as a manager. [root@docker_host_2 opt]# [root@docker_host_2 opt]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION i6jberxzc51hprbtgh94e1nzw docker_host_0 Ready Active Reachable 18.09.6 upn0vc4vx47224gxaxn6hwec9 docker_host_1 Ready Active Leader 18.09.6 sp544qzpe3ghr4ox6gvdv3ylo * docker_host_2 Ready Active Reachable 18.09.6 [root@docker_host_2 opt]#

    群集恢复后,所有任务全部运行在docker_host_1节点:

[root@docker_host_2 opt]# docker service ps -f 'desired-state=running' webapp_d ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS m9qad5jldkmf webapp_d.1 tomcat_app:8.5.40 docker_host_1 Running Running 22 minutes ago 43ycztehfjft webapp_d.2 tomcat_app:8.5.40 docker_host_1 Running Running 22 minutes ago eu49cks7twj1 webapp_d.3 tomcat_app:8.5.40 docker_host_1 Running Running 22 minutes ago pagn85s95a4l webapp_d.4 tomcat_app:8.5.40 docker_host_1 Running Running 22 minutes ago mep9zebz50be webapp_d.5 tomcat_app:8.5.40 docker_host_1 Running Running 22 minutes ago q8cetbu1lgpa webapp_d.6 tomcat_app:8.5.40 docker_host_1 Running Running 22 minutes ago [root@docker_host_2 opt]#

docker service update --force命令用于强制对群集任务进行负载均衡,该操作包括任务的停止与重新分配。

[root@docker_host_2 opt]# docker service update --force webapp_d webapp_d overall progress: 6 out of 6 tasks 1/6: running 2/6: running 3/6: running 4/6: running 5/6: running 6/6: running verify: Service converged [root@docker_host_2 opt]# [root@docker_host_2 opt]# docker service ps -f 'desired-state=running' webapp_d ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS pezzriea1ql3 webapp_d.1 tomcat_app:8.5.40 docker_host_0 Running Running 35 seconds ago miehr525l161 webapp_d.2 tomcat_app:8.5.40 docker_host_2 Running Running 22 seconds ago ivo43js9eolh webapp_d.3 tomcat_app:8.5.40 docker_host_1 Running Running 13 seconds ago ool0tu1tyke3 webapp_d.4 tomcat_app:8.5.40 docker_host_1 Running Running 18 seconds ago unysta4y6woe webapp_d.5 tomcat_app:8.5.40 docker_host_0 Running Running 26 seconds ago j63gtlovl0k9 webapp_d.6 tomcat_app:8.5.40 docker_host_2 Running Running 31 seconds ago [root@docker_host_2 opt]#

参考

https://docs.docker.com/engine/reference/commandline/dockerd/
https://docs.docker.com/engine/swarm/
https://docs.docker.com/engine/swarm/admin_guide/
https://docs.docker.com/engine/api/v1.39/
https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html

 

原文链接:https://my.oschina.net/superwjc/blog/3053478
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章