概述

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:2377To 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: activeNodeID: cos4ftcikaykcit9m15kqmvlhIs Manager: trueClusterID: odbfcfeayjogvdn34m3nruq2fManagers: 3Nodes: 3Default Address Pool: 10.0.0.0/8SubnetSize: 24Orchestration:Task History Retention Limit: 5Raft:Snapshot Interval: 10000Number of Old Snapshots to Retain: 0Heartbeat Tick: 1Election Tick: 10Dispatcher:Heartbeat Period: 5 secondsCA Configuration:Expiry Duration: 3 monthsForce Rotate: 0Autolock Managers: falseRoot Rotation In Progress: falseNode Address: 192.168.9.169Manager Addresses:192.168.9.168:2377192.168.9.169:2377192.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.xmlpattern="%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:2377To 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

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

  1. Linux安装Docker CE

    系统:CentOS Linux release 7.2 (Core) 3.10.0-693.11.6.el7.x86_64 SELinux:关闭 参考链接:https://docs.docker.co ...

  2. linux安装教程 ce,docker CE安装教程

    docker CE安装教程 2018-11-09 10:28 | coding云 | 31451次阅读 | 本文开发环境为Ubuntu 16.04 LTS 64位系统,通过apt的docker官方源安 ...

  3. docker显示linux桌面,怎样在桌面上安装 Docker CE?

    按照这些简单的步骤在你的 Linux.Mac 或 Windows 桌面上安装 Docker CE. 在上一篇文章中,我们学习了容器世界的一些基本术语.当我们运行命令并在后续文章中使用其中一些术语时,这 ...

  4. Docker入门之 - 如何安装Docker CE

    本文将介绍如何在Ubantu.CentOS.Windows.Mac上安装Docker Docker 提供了两个版本:社区版 (CE) 和企业版 (EE). Docker 社区版 (CE) 是开发人员和 ...

  5. 一、安装Docker CE

    卸载旧版本 较旧版本的Docker被称为docker或docker-engine.如果已安装这些,需要卸载以及相关的依赖项. $ sudo yum remove docker \docker-clie ...

  6. docker学习-1CentOS安装Docker CE

    1 moby.docker-ce与docker-ee docker原是一个开源项目,主要由docker公司维护,2017年年初,docker公司将原先的docker项目改名为moby,并创建了dock ...

  7. Docker CE 安装

    一.YUM安装 1.卸载旧版本docker # yum remove docker \docker-common \docker-selinux \docker-engine 2.安装docker C ...

  8. 【自学Docker容器二 ● Linux下Dokcer环境安装 】

    Docker自学系列 第一篇 [自学Docker容器一 ● 基础知识 ] 第二篇 [自学Docker容器二 ● Linux下Dokcer环境安装 ] 第三篇 [自学Docker容器三 ● Docker ...

  9. linux安装mysql四种方式

    一.前言 linux下安装mysql大概有四种安装方式,分别为仓库安装.本地安装.容器安装.以及源码安装.这几种方式分别对应着不同的工作环境,因此掌握这四种安装mysql方式便会极大的提高我们的工作效 ...

最新文章

  1. Request Connection: Remote Server @ 192.229.145.200:80
  2. 30分钟内让你明白正则表达式是什么,并对它有一些基本的了解(二)
  3. 在 Asp.NET MVC 中使用 SignalR 实现推送功能
  4. 减小Delphi的Exe文件大小
  5. php 扩展 mysql_PHP链接MySQL的常用扩展函数
  6. python3新式类_python新式类和旧式类区别
  7. 【转】Linux ln(link) 命令详解
  8. Android 学习 笔记_03. SQLite的使用
  9. Asp.net高效导出excel篇之Aspose导出excel
  10. SQL数据库引擎服务SQL Server启动参数概述
  11. 基于Volley框架的图片渐变显示alpha动画
  12. 多核Cache一致性 伪共享 atomic的实现和cache相关的部分
  13. 黑客攻防技巧:2分钟入侵网站全程实录
  14. 华为手机wifi不显示连接到服务器,华为手机中无法连接WIFI处理方法
  15. 关于阿里云主机万网虚拟主机建立多个网站教程,很实用!
  16. 【tokio】watch
  17. Java时间片轮转(简单模拟实现,适合初学者)
  18. 关于使用cin的返回值终止循环输入
  19. iOS 10 相机相册闪退适配
  20. 四层高速dsp开发板制作7——绘制等长线

热门文章

  1. 人事考试在线报名系统新突破,一键触达“智慧考试”
  2. Workflow,要不要了解一下
  3. 计算两幅图之间的旋转角
  4. 近期风靡互联网的Deep Dream人工智能图像识别软件
  5. Java数据对象(JDO)的应用
  6. 致远项目管理SPM系统之变更管理概述
  7. linux的常用命令行
  8. tomcat配置SSL报错解决:java.lang.IllegalArgumentException: Invalid character (CR or LF) found in method nam
  9. Gatling:HTTP Checks
  10. SpringApplication.run(MyApplication.class, args)运行流程源码分析