Docker

发布于:2025-07-17 ⋅ 阅读:(18) ⋅ 点赞:(0)

什么是Docker Swarm

DockerSwarm 是什么?

DockerSwarm 是 Docker 的集群管理工具

其主要作用是把若干台 Docker 主体抽象为一个整体 并且通过一个入口统一管理这些Docker 主机上的各种 Docker 资源

DockerSwarm 将一个或多个 Docker 节点组织起来 使得用户能够以集群方式管理它们

组成部分

swarm 集群由管理节点(Manager)和工作节点(Worker)构成。

管理节点:主要负责整个集群的管理工作包括集群配置,服务管理等所有跟集群有关的工作 诸如如监控集群状态 分发任务至工作节点等操作

工作节点:主要负责执行运行服务的任务

在 Docker Swarm 集群中,节点的角色分为 Manager 和 Worker。

Manager 节点不仅负责管理集群(如调度任务、维护集群状态等),也可以运行服务的任务(即容器)。

默认情况下,当你创建一个服务时,Swarm 会根据其调度策略将服务的任务分配到可用的节点上,包括 Manager 节点。

docker swarm 是 Docker 引擎内置的一个功能模块,不需要单独安装,它是随着 Docker Engine 一起发布的。

只要 Docker 已经正确安装并运行,就可以使用 docker swarm 命令来初始化和管理 Swarm 集群。

相关命令说明

[root@localhost data]# docker swarm COMMAND

Usage:  docker swarm COMMAND

Manage Swarm

Commands:
  ca          Display and rotate the root CA
  init        Initialize a swarm
  join        Join a swarm as a node and/or manager
  join-token  Manage join tokens
  leave       Leave the swarm
  unlock      Unlock swarm
  unlock-key  Manage the unlock key
  update      Update the swarm

Run 'docker swarm COMMAND --help' for more information on a command.

命令 说明
docker swarm init 初始化一个 Swarm 集群,将当前节点设为 Manager 节点。
docker swarm join --token <TOKEN> <MANAGER_IP>:2377 将当前节点加入到已有的 Swarm 集群中(作为 Worker 或 Manager)。
docker swarm ca 显示或轮换集群的根 CA 证书(用于安全通信)。
docker swarm join-token worker 显示用于添加 Worker 节点的 token 和命令。
docker swarm join-token manager 显示用于添加 Manager 节点的 token 和命令。
docker swarm leave 当前节点离开 Swarm 集群。
docker swarm unlock 如果集群被加密锁定了,使用该命令解锁。
docker swarm unlock-key 查看或删除集群的解锁密钥。
docker swarm update [OPTIONS] 更新 Swarm 集群配置(如调度策略、默认安全设置等)。

[root@localhost data]# docker swarm init --help

Usage:  docker swarm init [OPTIONS]

Initialize a swarm

Options:
      --advertise-addr string                  Advertised address (format: "<ip|interface>[:port]")
      --autolock                               Enable manager autolocking (requiring an unlock key to start a
                                               stopped manager)
      --availability string                    Availability of the node ("active", "pause", "drain") (default "active")
      --cert-expiry duration                   Validity period for node certificates (ns|us|ms|s|m|h) (default 2160h0m0s)
      --data-path-addr string                  Address or interface to use for data path traffic (format:
                                               "<ip|interface>")
      --data-path-port uint32                  Port number to use for data path traffic (1024 - 49151). If no value
                                               is set or is set to 0, the default port (4789) is used.
      --default-addr-pool ipNetSlice           default address pool in CIDR format (default [])
      --default-addr-pool-mask-length uint32   default address pool subnet mask length (default 24)
      --dispatcher-heartbeat duration          Dispatcher heartbeat period (ns|us|ms|s|m|h) (default 5s)
      --external-ca external-ca                Specifications of one or more certificate signing endpoints
      --force-new-cluster                      Force create a new cluster from current state
      --listen-addr node-addr                  Listen address (format: "<ip|interface>[:port]") (default 0.0.0.0:2377)
      --max-snapshots uint                     Number of additional Raft snapshots to retain
      --snapshot-interval uint                 Number of log entries between Raft snapshots (default 10000)
      --task-history-limit int                 Task history retention limit (default 5)

集群节点规划

为了利用 swarm 模式的容错功能,可以根据组织的高可用性要求实现奇数个节点

当有多个管理中心时,可以从一个管理中心节点的故障中恢复,而无需停机。

  • 三个管理器群可以容忍最多损失一个管理器。
  • 五个管理器群最多可以同时丢失两个管理器节点。

  • 七个管理器群最多可以同时丢失三个管理器节点。

  • 九个管理器群最多可以同时丢失四个管理器节点。

  • Docker 建议一个群最多有七个管理器节点。

添加更多管理器并不意味着可伸缩性或性能的提高 一般来说 情况恰恰相反

主机名 IP地址 docker版本号 角色 备注
manager01 192.168.66.146 26.1.4 管理节点 主管
manager02 192.168.66.152 26.1.4 管理节点 从管
manager03 192.168.66.153 26.1.4 管理节点 从管
worker01 192.168.66.154 26.1.4 工作节点 工作
worker02 192.168.66.155 26.1.4 工作节点 工作

环境准备

  • 1、修改主机名

  • 2、配置IP地址

  • 3、关闭防火墙和SELINUX安全模式

  • 4、配置系统YUM源和Docker镜像源

  • 5、更新系统(yum update -y)

  • 6、安装好docker环境

创建集群

docker swarm init --advertise-addr

--advertise-addr 行为 推荐程度
不指定 Docker 自动选择一个 IP 不推荐(尤其在生产环境)
指定 明确控制节点间通信的 IP 推荐
m1配置信息(manager)

初始化一个新的 Swarm 集群,并将当前节点设置为 Manager 节点。

docker swarm init --advertise-addr 192.168.66.146

Swarm initialized: current node (og3lc3bbg990qc0mkr7mbaoz2) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join --token 
    SWMTKN-1-1wgm41bp9zb04tbzvv6p7q21ke5bbkp2a4p71o6o666si24ssf-ch84gl3dpmxavtx479zkglt59 192.168.66.146:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

Swarm 集群创建成功,获取用于添加新 Manager 的命令

docker swarm join-token manager

To add a manager to this swarm, run the following command:

docker swarm join --token 
    SWMTKN-1-1wgm41bp9zb04tbzvv6p7q21ke5bbkp2a4p71o6o666si24ssf-bug5lagqesuzehgbnuha66ktk 192.168.66.146:2377

在另一台主机上执行上面这条命令,可以成功加入集群,并作为新的 Manager

操作 命令 是否添加新节点 用途
初始化集群 docker swarm init 创建一个新的 Swarm 集群
获取 Manager 加入命令 docker swarm join-token manager 生成供其他主机使用的命令
执行 join 命令(在其他主机) docker swarm join --token xxx IP:2377 把该主机加入集群并设为 Manager
m2配置信息(manager)

# 添加至集群中成为管理节点
[root@docker-m2 ~]# docker swarm join --token SWMTKN-1-2m0zoq7mc98hsecvt3jrshltywt42w8jtlx7zifa84n8gm6hog-das8vljcfnlzv7gwjbrcg84er 192.168.66.146:2377
This node joined a swarm as a manager.

m3配置信息(manager)

# 添加至集群中成为管理节点
[root@docker-m3 ~]# docker swarm join --token SWMTKN-1-2m0zoq7mc98hsecvt3jrshltywt42w8jtlx7zifa84n8gm6hog-das8vljcfnlzv7gwjbrcg84er 192.168.66.146:2377
This node joined a swarm as a manager.

n1配置信息(worker)

# 添加至集群中成为工作节点
[root@docker-n1 ~]# docker swarm join --token SWMTKN-1-2m0zoq7mc98hsecvt3jrshltywt42w8jtlx7zifa84n8gm6hog-73vr18usjr5mz23td976369xb 192.168.66.146:2377
This node joined a swarm as a worker.

n2配置信息(worker)

# 添加至集群中成为工作节点
[root@docker-n2 ~]# docker swarm join --token SWMTKN-1-2m0zoq7mc98hsecvt3jrshltywt42w8jtlx7zifa84n8gm6hog-73vr18usjr5mz23td976369xb 192.168.66.146:2377
This node joined a swarm as a worker.

检查配置情况

查看集群节点状态信息

发现docker-m1是主管理节点,docker-m2、docker-03是备用管理节点;

两个工作节点docker-n1、docker-n2也正常添加至集群中来。

[root@docker-m1 ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
409i7chz9723h64qph463her5 *   m1         Ready     Active         Leader           26.1.4
vq7gdmivvizdnm17rya29e395     m2         Ready     Active         Reachable        26.1.4
hqgphq68rvrp3sh3dmy7j3ytv     m3         Ready     Active         Reachable        26.1.4
pq4w82fq0wn7rbi24ybzinayq     s1         Ready     Active                          26.1.4
kwlfsipeln7u0sstejmr8s8wm     s2         Ready     Active                          26.1.4

查看整个Docker系统的信息 发现docker swarm集群已经创建完成。 共有五台节点,其中三台为管理节点。

[root@docker-m1 ~]# docker info
Client: Docker Engine - Community
 Version:    26.1.4
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.14.1
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.27.1
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 2
  Running: 0
  Paused: 0
  Stopped: 2
 Images: 6
 Server Version: 26.1.4
 Storage Driver: overlay2
  Backing Filesystem: xfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 Swarm: active
  NodeID: 409i7chz9723h64qph463her5
  Is Manager: true
  ClusterID: tpezv4gb4895pm0xyivmez2ng
  Managers: 3
  Nodes: 5
  Data Path Port: 4789
  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.66.146
  Manager Addresses:
   192.168.66.146:2377
   192.168.66.152:2377
   192.168.66.153:2377
 Runtimes: runc io.containerd.runc.v2
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: d2d58213f83a351ca8f528a95fbd145f5654e957
 runc version: v1.1.12-0-g51d5e94
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
 Kernel Version: 3.10.0-1160.71.1.el7.x86_64
 Operating System: CentOS Linux 7 (Core)
 OSType: linux
 Architecture: x86_64
 CPUs: 2
 Total Memory: 972.3MiB
 Name: m1
 ID: bb7b1d09-3c39-4cec-8e91-b3d249c92aa8
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Registry Mirrors:
  https://docker.m.daocloud.io/
 Live Restore Enabled: false

查询集群网络信息 查看到集群中各个节点的IP地址

[root@docker-m1 ~]# docker network ls
NETWORK ID     NAME              DRIVER    SCOPE
7544bf512308   bridge            bridge    local
575614844e29   docker_gwbridge   bridge    local
c50925c91744   host              host      local
utmwp4dtmdwe   ingress           overlay   swarm
b9f09410831a   net1              bridge    local
a6bdb177b438   net2              bridge    local
3eac8d80c11d   none              null      local

[root@docker-m1 ~]# docker network inspect ingress
[
    {
        "Name": "ingress",
        "Id": "utmwp4dtmdwe4t0rtb44l1pdt",
        "Created": "2025-06-06T11:25:55.280963109+08:00",
        "Scope": "swarm",
        "Driver": "overlay",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "10.0.0.0/24",
                    "Gateway": "10.0.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": true,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "ingress-sbox": {
                "Name": "ingress-endpoint",
                "EndpointID": "6ffbebbd8103e689e070e9d7b131d4217b8cc72424d77c60662dadec80be887c",
                "MacAddress": "02:42:0a:00:00:02",
                "IPv4Address": "10.0.0.2/24",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.driver.overlay.vxlanid_list": "4096"
        },
        "Labels": {},
        "Peers": [
            {
                "Name": "07527edc7cf2",
                "IP": "192.168.66.146"
            },
            {
                "Name": "51e9b4f53752",
                "IP": "192.168.66.152"
            },
            {
                "Name": "19682ed354a6",
                "IP": "192.168.66.153"
            },
            {
                "Name": "3161d8159fff",
                "IP": "192.168.66.154"
            },
            {
                "Name": "8b58eb7829cd",
                "IP": "192.168.66.155"
            }
        ]
    }
]

角色变化

将Manager降级为Worker

以docker-m3为例,将docker-m3管理节点由manager角色变成worker角色

# 查看帮助命令
[root@docker-m1 ~]# docker node update -h
Flag shorthand -h has been deprecated, please use --help

Usage:  docker node update [OPTIONS] NODE

Update a node

Options:
      --availability string   Availability of the node ("active"|"pause"|"drain")
      --label-add list        Add or update a node label (key=value)
      --label-rm list         Remove a node label if exists
      --role string           Role of the node ("worker"|"manager")

# 执行如下命令,将docker-m3管理节点由manager角色变成worker角色。
[root@docker-m1 ~]# docker node ls
ID                            HOSTNAME    STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
34cug51p9dw83u2np594z6ej4 *   docker-m1   Ready     Active         Leader           26.1.4
hwmwdk78u3rx0wwxged87xnun     docker-m2   Ready     Active         Reachable        26.1.4
4q34guc6hp2a5ok0g1zkjojyh     docker-m3   Ready     Active         Reachable        26.1.4
4om9sg56sg09t9whelbrkh8qn     docker-n1   Ready     Active                          26.1.4
xooolkg0g9epddfqqiicywshe     docker-n2   Ready     Active                          26.1.4

[root@docker-m1 ~]# docker node update --role worker docker-m3
docker-m3

[root@docker-m1 ~]# docker node ls
ID                            HOSTNAME    STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
34cug51p9dw83u2np594z6ej4 *   docker-m1   Ready     Active         Leader           26.1.4
hwmwdk78u3rx0wwxged87xnun     docker-m2   Ready     Active         Reachable        26.1.4
4q34guc6hp2a5ok0g1zkjojyh     docker-m3   Ready     Active                          26.1.4
4om9sg56sg09t9whelbrkh8qn     docker-n1   Ready     Active                          26.1.4
xooolkg0g9epddfqqiicywshe     docker-n2   Ready     Active                          26.1.4

# 更改之后,查看docker-m3节点详细信息情况
# 发现已经由管理节点变成工作节点
[root@docker-m1 ~]# docker node inspect m3
[
    {
        "ID": "4q34guc6hp2a5ok0g1zkjojyh",
        "Version": {
            "Index": 39
        },
        "CreatedAt": "2022-05-03T10:59:07.69499678Z",
        "UpdatedAt": "2022-05-03T11:27:02.178601504Z",
        "Spec": {
            "Labels": {},
            "Role": "worker",
            "Availability": "active"
        },
        "Description": {
            "Hostname": "docker-m3",
            "Platform": {
                "Architecture": "x86_64",
                "OS": "linux"
            },
            "Resources": {
                "NanoCPUs": 1000000000,
                "MemoryBytes": 2076499968
            },
            "Engine": {
                "EngineVersion": "26.1.4",
                "Plugins": [
                    {
                        "Type": "Log",
                        "Name": "awslogs"
                    },
                    {
                        "Type": "Log",
                        "Name": "fluentd"
                    },
                    {
                        "Type": "Log",
                        "Name": "gcplogs"
                    },
                    {
                        "Type": "Log",
                        "Name": "gelf"
                    },
                    {
                        "Type": "Log",
                        "Name": "journald"
                    },
                    {
                        "Type": "Log",
                        "Name": "json-file"
                    },
                    {
                        "Type": "Log",
                        "Name": "local"
                    },
                    {
                        "Type": "Log",
                        "Name": "logentries"
                    },
                    {
                        "Type": "Log",
                        "Name": "splunk"
                    },
                    {
                        "Type": "Log",
                        "Name": "syslog"
                    },
                    {
                        "Type": "Network",
                        "Name": "bridge"
                    },
                    {
                        "Type": "Network",
                        "Name": "host"
                    },
                    {
                        "Type": "Network",
                        "Name": "ipvlan"
                    },
                    {
                        "Type": "Network",
                        "Name": "macvlan"
                    },
                    {
                        "Type": "Network",
                        "Name": "null"
                    },
                    {
                        "Type": "Network",
                        "Name": "overlay"
                    },
                    {
                        "Type": "Volume",
                        "Name": "local"
                    }
                ]
            },
            "TLSInfo": {
                "TrustRoot": "-----BEGIN CERTIFICATE-----\nMIIBaTCCARCgAwIBAgIUYUzIe4mqhjKYxuilbhVByLwzzeMwCgYIKoZIzj0EAwIw\nEzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMjIwNTAzMTA0NzAwWhcNNDIwNDI4MTA0\nNzAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABK8XzVHRM50TgsAxrgXg18ti69dkedf9LsaHm2I2ub9kKzkLsnTV+bIHGOHK\n0/Twi/B9OCFSsozUGDP7qR3/rRmjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB\nAf8EBTADAQH/MB0GA1UdDgQWBBQ3iXSq5FKnODK2Qqic39A0bg9qjjAKBggqhkjO\nPQQDAgNHADBEAiASv1HdziErIzBJtsVMxfp8zAv0EJ5/eVeIldYdUIVNTQIgXUc3\nakty/iBy5/MhFt9JRRMV1xH1x+Dcf35tNWGH52w=\n-----END CERTIFICATE-----\n",
                "CertIssuerSubject": "MBMxETAPBgNVBAMTCHN3YXJtLWNh",
                "CertIssuerPublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAErxfNUdEznROCwDGuBeDXy2Lr12R51/0uxoebYja5v2QrOQuydNX5sgcY4crT9PCL8H04IVKyjNQYM/upHf+tGQ=="
            }
        },
        "Status": {
            "State": "ready",
            "Addr": "192.168.66.153"
        }
    }
]

将Worker晋升为Manager

以docker-n2 为例 将docker-n2管理节点由worker角色变成manager角色

[root@docker-m1 ~]# docker node ls
ID                            HOSTNAME    STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
34cug51p9dw83u2np594z6ej4 *   docker-m1   Ready     Active         Leader           26.1.4
hwmwdk78u3rx0wwxged87xnun     docker-m2   Ready     Active         Reachable        26.1.4
4q34guc6hp2a5ok0g1zkjojyh     docker-m3   Ready     Active                          26.1.4
4om9sg56sg09t9whelbrkh8qn     docker-n1   Ready     Active                          26.1.4
xooolkg0g9epddfqqiicywshe     docker-n2   Ready     Active                          26.1.4
[root@docker-m1 ~]# docker node update --role manager docker-n2
docker-n2
[root@docker-m1 ~]# docker node ls
ID                            HOSTNAME    STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
34cug51p9dw83u2np594z6ej4 *   docker-m1   Ready     Active         Leader           26.1.4
hwmwdk78u3rx0wwxged87xnun     docker-m2   Ready     Active         Reachable        26.1.4
4q34guc6hp2a5ok0g1zkjojyh     docker-m3   Ready     Active                          26.1.4
4om9sg56sg09t9whelbrkh8qn     docker-n1   Ready     Active                          26.1.4
xooolkg0g9epddfqqiicywshe     docker-n2   Ready     Active         Reachable        26.1.4

移除再添加管理节点

将集群中某台管理节点移除集群 重新获取管理节点的令牌 再添加至集群中

# 查看帮助命令
[root@docker-m1 ~]# docker swarm leave --help

Usage:  docker swarm leave [OPTIONS]

Leave the swarm

Options:
  -f, --force   Force this node to leave the swarm, ignoring warnings

在docker-m3节点执行操作 将docker-m3管理节点移除集群

[root@docker-m3 ~]# docker node ls
ID                            HOSTNAME    STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
34cug51p9dw83u2np594z6ej4     docker-m1   Ready     Active         Leader           26.1.4
hwmwdk78u3rx0wwxged87xnun     docker-m2   Ready     Active         Reachable        26.1.4
4q34guc6hp2a5ok0g1zkjojyh *   docker-m3   Ready     Active         Reachable        26.1.4
4om9sg56sg09t9whelbrkh8qn     docker-n1   Ready     Active                          26.1.4
xooolkg0g9epddfqqiicywshe     docker-n2   Ready     Active                          26.1.4

[root@docker-m3 ~]# docker swarm leave -f
Node left the swarm.

在docker-m1管理节点上查看。发现docker-m3管理节点已经关闭

在某个节点上执行 docker swarm leave -f 时,该节点会退出集群,但这个操作并不会自动从其他节点的节点列表中删除它。

也就是说:

  • m3 已经不再是 Swarm 的一部分。

  • 但它曾经是集群的一部分,Swarm 管理节点(Manager)仍保留它的记录。

  • 所以在 docker node ls 中它依然显示,只是状态变成 Down(表示无法通信或已离开)。

如果确认 m3 永远不会再加入集群,并且你想清理这个节点记录,你需要在 Manager 节点上手动删除它:

docker node rm m3

如果执行docker node rm s2

会出现以下错误

Error response from daemon: rpc error: code = FailedPrecondition desc = node kwlfsipeln7u0sstejmr8s8wm is a cluster manager and is a member of the raft cluster. It must be demoted to worker before removal

Docker Swarm 不允许直接删除处于 Manager 角色的节点

先将该 Manager 节点 降级为 Worker,然后再删除

[root@docker-m1 ~]# docker node ls
ID                            HOSTNAME    STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
34cug51p9dw83u2np594z6ej4 *   docker-m1   Ready     Active         Leader           26.1.4
hwmwdk78u3rx0wwxged87xnun     docker-m2   Ready     Active         Reachable        26.1.4
4q34guc6hp2a5ok0g1zkjojyh     docker-m3   Ready     Active         Reachable        26.1.4
4om9sg56sg09t9whelbrkh8qn     docker-n1   Ready     Active                          26.1.4
xooolkg0g9epddfqqiicywshe     docker-n2   Ready     Active                          26.1.4

[root@docker-m1 ~]# docker node ls
ID                            HOSTNAME    STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
34cug51p9dw83u2np594z6ej4 *   docker-m1   Ready     Active         Leader           26.1.4
hwmwdk78u3rx0wwxged87xnun     docker-m2   Ready     Active         Reachable        26.1.4
4q34guc6hp2a5ok0g1zkjojyh     docker-m3   Down      Active         Unreachable      26.1.4
4om9sg56sg09t9whelbrkh8qn     docker-n1   Ready     Active                          26.1.4
xooolkg0g9epddfqqiicywshe     docker-n2   Ready     Active                          26.1.4

重新获取添加管理节点的令牌命令

执行docker swarm join-token manager命令 获取命令

[root@docker-m1 ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-528o8bfk061miheduvuvnnohhpystvxnwiqfqqf04gou6n1wmz-1z6k8msio37as0vaa467glefx 192.168.66.146:2377

[root@docker-m1 ~]#

重新将docker-m3管理节点添加到集群中

[root@docker-m3 ~]# docker swarm join --token SWMTKN-1-528o8bfk061miheduvuvnnohhpystvxnwiqfqqf04gou6n1wmz-1z6k8msio37as0vaa467glefx 192.168.66.146:2377
This node joined a swarm as a manager.
[root@docker-m3 ~]# docker node ls
ID                            HOSTNAME    STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
34cug51p9dw83u2np594z6ej4     docker-m1   Ready     Active         Leader           26.1.4
hwmwdk78u3rx0wwxged87xnun     docker-m2   Ready     Active         Reachable        26.1.4
4q34guc6hp2a5ok0g1zkjojyh     docker-m3   Down      Active         Reachable        26.1.4
jvtiwv8eu45ev4qbm0ausivv2 *   docker-m3   Ready     Active         Reachable        26.1.4
4om9sg56sg09t9whelbrkh8qn     docker-n1   Ready     Active                          26.1.4
xooolkg0g9epddfqqiicywshe     docker-n2   Ready     Active                          26.1.4
[root@docker-m3 ~]#

移除再添加工作节点

将集群中某台工作节点移除集群 重新获取工作节点的令牌 再添加至集群中

在docker-n1 节点执行操作 将docker-n1工作节点移除集群

[root@docker-n1 ~]# docker swarm leave
Node left the swarm.

在docker-m1管理节点上查看。发现docker-n1工作节点已经关闭

[root@docker-m1 ~]# docker node ls
ID                            HOSTNAME    STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
34cug51p9dw83u2np594z6ej4 *   docker-m1   Ready     Active         Leader           26.1.4
hwmwdk78u3rx0wwxged87xnun     docker-m2   Ready     Active         Reachable        26.1.4
4q34guc6hp2a5ok0g1zkjojyh     docker-m3   Down      Active         Reachable        26.1.4
jvtiwv8eu45ev4qbm0ausivv2     docker-m3   Ready     Active         Reachable        26.1.4
4om9sg56sg09t9whelbrkh8qn     docker-n1   Down      Active                          26.1.4
xooolkg0g9epddfqqiicywshe     docker-n2   Ready     Active                          26.1.4

重新获取添加工作节点的令牌命令

执行docker swarm join-token worker命令 获取命令

[root@docker-m1 ~]# docker swarm join-token worker
To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-528o8bfk061miheduvuvnnohhpystvxnwiqfqqf04gou6n1wmz-3ixu6we70ghk69wghfrmo0y6a 192.168.66.146:2377

[root@docker-m1 ~]#

重新将docker-n1工作节点添加到集群中。

[root@docker-n1 ~]# docker swarm join --token SWMTKN-1-528o8bfk061miheduvuvnnohhpystvxnwiqfqqf04gou6n1wmz-3ixu6we70ghk69wghfrmo0y6a 192.168.66.146:2377
This node joined a swarm as a worker.

删除多余的节点

[root@docker-m1 ~]# docker node rm 34emdxnfc139d6kc4ht2xsp4b 4om9sg56sg09t9whelbrkh8qn
34emdxnfc139d6kc4ht2xsp4b
4om9sg56sg09t9whelbrkh8qn
[root@docker-m1 ~]#

部署NGINX应用测试

service命令

  • Service (服务) 是一个抽象概念 表示你希望运行的应用(比如Nginx Redis等) 以及它的期望状态(如副本数 网络 端口等)
  • Task (任务) 是服务在某个节点上的实际运行实例 每个Task对应一个容器(Container)

只有Manager节点才能管理服务(执行这些命令)

服务是Swarm模式下的核心资源之一 适合用于部署高可用,可扩展的分布式应用

# 查看service 帮助命令
[root@docker-m1 ~]# docker service

Usage:  docker service COMMAND

Manage services

Commands:
  create      Create a new service
  inspect     Display detailed information on one or more services
  logs        Fetch the logs of a service or task
  ls          List services
  ps          List the tasks of one or more services
  rm          Remove one or more services
  rollback    Revert changes to a service's configuration
  scale       Scale one or multiple replicated services
  update      Update a service

Run 'docker service COMMAND --help' for more information on a command.

命令 作用描述 常用用途/示例
create 创建一个新的服务(Service),由 Swarm 管理调度 启动一个 Nginx 服务并指定副本数:docker service create --replicas 3 -p 80:80 nginx
inspect 查看一个或多个服务的详细信息 查看服务配置和状态:docker service inspect my_service
logs 获取某个服务或任务的日志 查看服务日志:docker service logs my_service 查看具体任务日志:docker service logs <task_id>
ls 列出当前 Swarm 集群中的所有服务 查看所有运行的服务:docker service ls
ps 显示一个或多个服务的任务(Task)状态 查看服务下所有容器的状态:docker service ps my_service
rm 删除一个或多个服务 删除服务:docker service rm my_service
rollback 回滚服务到上一次配置(例如更新失败后恢复) 回滚服务更新:docker service rollback my_service
scale 调整一个或多个服务的副本数量(Replicas) 扩容服务:docker service scale my_service=5
update 更新服务的配置(如镜像、环境变量、端口等),支持滚动更新 更新服务镜像并设置更新策略:docker service update --image nginx:1.21 --update-parallelism 2 my_service

创建NGINX服务

docker service 服务启动,具有扩缩,滚动更新。

docker service create -p 8888:80 --name my-nginx nginx

  1. Docker 会在集群中启动一个名为my-nginx的服务
  2. 该服务默认以 副本模式(Replicated)运行一个任务(Task)也就是一个nginx容器
  3. 所有连接到Swarm节点(任意节点)的 8888 端口的请求都会被路由到运行着nginx 的容器中
  4. 如果你有多个节点 Swarm 可以根据策列自动调度任务到不同节点上运行

查看NGINX服务

docker service ls

该命令用于列出当前 Docker Swarm 集群中所有的服务(Services)。

[root@docker-m1 ~]# docker service ls
ID             NAME       MODE         REPLICAS   IMAGE          PORTS
nckewzy2gkl1   my-nginx   replicated   1/1        nginx:latest   *:8888->80/tcp

字段 含义
ID 服务的唯一标识符(内部使用,通常不需要手动处理)
NAME 服务的名称(比如你用 --name my-nginx 指定的)
MODE 服务的调度模式: - replicated:副本模式(指定数量的副本) - global:全局模式(每个节点运行一个任务)
REPLICAS 实际运行 / 期望的副本数(例如 3/3 表示所有副本都在正常运行)
IMAGE 使用的镜像名称和标签(如 nginx:latest
PORTS 端口映射信息(比如 *:8888->80/tcp 表示宿主机的 8888 端口映射到容器的 80 端口)
docker service ps my-nginx

必须在 Manager 节点 上执行此命令。

这个命令用于查看指定服务(Service)的所有任务(Tasks)的运行状态。

在 Docker Swarm 中,一个服务(Service)是由多个“任务(Task)”组成的。

每个任务对应一个容器(Container),Swarm 会负责调度这些任务到集群中的不同节点上运行。

字段 含义
ID 任务的唯一 ID
NAME 任务名称,格式通常是 <service-name>.<replica-number>
IMAGE 使用的镜像
NODE 该任务运行在哪个节点上
DESIRED STATE 期望状态(如 Running, Shutdown, Ready
CURRENT STATE 当前实际状态和持续时间
ERROR 如果任务失败,这里显示错误信息
PORTS 端口映射信息(如果配置了)

docker service inspect my-nginx

必须在 Manager 节点上执行此命令

这个命令用于查看名为my-nginx 的服务的详细配置和运行状态信息

它会输出该服务的完整配置信息(比如使用的镜像、副本数、环境变量、端口映射、调度约束等)以及当前的服务状态、任务状态等,是排查问题、了解服务详情的重要工具。

部分 内容说明
ID 服务的唯一 ID
Spec 服务的配置规范(最重要的部分) - 包括镜像、副本数、端口、更新策略、重启策略等
Endpoint 服务暴露的网络信息 - 比如 VIP(虚拟 IP)、端口映射等
UpdateStatus 最近一次服务更新的状态(是否成功)
CreatedAt / UpdatedAt 服务创建时间和最近更新时间

动态扩容

动态扩容,缓解主机被访问的压力。

docker service update

docker service update 的作用是:

在不中断服务的前提下,动态更新 Swarm 服务的配置(如镜像、副本数、端口、资源限制等),支持滚动更新和回滚功能,非常适合用于生产环境中的服务维护与升级。

是实现 滚动更新(rolling update) 的核心命令,适用于持续集成/持续部署(CI/CD)流程中非常有用。

选项 说明 示例
--image 更新服务使用的镜像 --image nginx:1.21
--env-add, --env-rm 添加或删除环境变量 --env-add "ENV1=value1"
--replicas 设置新的副本数 --replicas 5
--update-parallelism 每次同时更新的任务数 --update-parallelism 2
--update-delay 设置两次更新之间的延迟时间 --update-delay 10s
--limit-cpu, --limit-memory 设置资源限制 --limit-cpu 2 --limit-memory 512M
--restart-condition 设置任务重启条件 --restart-condition on-failure
--network-add, --network-rm 添加或移除网络 --network-add my_network
--publish-add, --publish-rm 添加或移除端口映射 --publish-add 8080:80
--rollback 回滚到上一次配置 --rollback

[root@docker-m1 ~]# docker service update --help

Usage:  docker service update [OPTIONS] SERVICE

Update a service

Options:
......
  -q, --quiet                              Suppress progress output
      --read-only                          Mount the container's root filesystem as read only
      --replicas uint                      Number of tasks
      --replicas-max-per-node uint         Maximum number of tasks per node (default 0 = unlimited)
......
 

docker service update \
  --image nginx:1.21 \
  --update-parallelism 2 \
  --update-delay 10s \
  my-nginx
  
将 my-nginx 服务的容器镜像更新为 nginx:1.21
每次更新 2 个任务
每次更新之间间隔 10 秒(确保系统稳定)

创建多个NGINX服务副本

[root@docker-m1 ~]# docker service update --replicas 2 my-nginx
my-nginx
overall progress: 2 out of 2 tasks
1/2: running   [==================================================>]
2/2: running   [==================================================>]
verify: Service converged
[root@docker-m1 ~]#
查看创建的NGINX服务副本

[root@docker-m1 ~]# docker service ls
ID             NAME           MODE         REPLICAS   IMAGE          PORTS
ngoi21hcjan5   my-nginx   replicated   2/2        nginx:latest   *:8888->80/tcp

[root@docker-m1 ~]# docker service ps my-nginx
ID             NAME             IMAGE          NODE        DESIRED STATE   CURRENT STATE            ERROR     PORTS
w5azhbc3xrta   my-nginx.1   nginx:latest   docker-n2   Running         Running 36 minutes ago
rgtjq163z9ch   my-nginx.2   nginx:latest   docker-m1   Running         Running 33 seconds ago

测试访问NGINX服务

http://192.168.66.146:8888/
http://192.168.66.154:8888/

删除对应的服务

docker service rm my-nginx

模拟故障情况

当docker-m1管理主机发生宕机时,查看NGINX服务是否能够正常运行访问。

# 关闭docker-m1节点
[root@docker-m1 ~]# shutdown -h now
Connection to 192.168.66.146 closed by remote host.
Connection to 192.168.66.146 closed.

查看节点状态

[root@docker-m2 ~]# docker node ls
ID                            HOSTNAME    STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
75dxq2qmzr2bv4tkg20gh0syr     docker-m1   Down      Active         Unreachable      26.1.4
l2is4spmgd4b5xmmxwo3jvuf4 *   docker-m2   Ready     Active         Reachable        26.1.4
u89a2ie2buxuc5bsew4a2wrpo     docker-m3   Ready     Active         Leader           26.1.4
aon2nakgk87rds5pque74itw4     docker-n1   Ready     Active                          26.1.4
ljdb9d3xkzjruuxsxrpmuei7s     docker-n2   Ready     Active                          26.1.4
[root@docker-m2 ~]#

查看服务状态

[root@docker-m2 ~]# docker service ls
ID             NAME           MODE         REPLICAS   IMAGE          PORTS
ngoi21hcjan5   my-nginx   replicated   3/2        nginx:latest   *:8888->80/tcp

[root@docker-m2 ~]# docker service ps my-nginx
ID             NAME                 IMAGE          NODE        DESIRED STATE   CURRENT STATE            ERROR     PORTS
w5azhbc3xrta   my-nginx.1       nginx:latest   docker-n2   Running         Running 2 minutes ago
tteb16dnir6u   my-nginx.2       nginx:latest   docker-n1   Running         Running 2 minutes ago
rgtjq163z9ch    \_ my-nginx.2   nginx:latest   docker-m1   Shutdown        Running 17 minutes ago

调度模式

在 Docker Swarm 中,服务的调度模式(--mode)确实分为两种:

replicated:副本模式

  • 定义:你指定一个期望的副本数量(如 3 个任务),Swarm 负责在集群中选择合适的节点来运行这些副本。

  • 用途:适用于大多数场景,比如 Web 服务、数据库连接池等,你希望控制服务的整体规模而不必每个节点都跑一个。

docker service create \
  --name my-web \
  --replicas 3 \
  nginx

这会在集群中启动3个 Nginx 容器 具体分布在哪些节点上由Swarm 自动决定

global:全局模式

  • 定义:每个节点上运行一个任务(容器),不需要指定副本数。

  • 用途:适合需要在每个节点上都部署的服务,例如日志收集器、监控代理、网络插件等。

docker service create \
  --name node-exporter \
  --mode global \
  prom/node-exporter

这会在集群中的每一个节点(Manager 和 Worker)上都启动一个 node-exporter 容器。

模式 含义 是否需要指定副本数 每个节点最多运行几个任务 典型使用场景
replicated 指定总副本数,Swarm 分配部署 0 或 1 Web 服务、API 服务、数据库代理等
global 每个节点自动运行一个任务 1 监控代理、日志采集、节点级守护进程

是否可以运行超过当前机器数量的容器?

当你创建一个服务时,Swarm 会在集群中的节点上为该服务创建多个任务(容器实例),每个任务都有一个全局唯一的任务ID和一个基于服务名称的任务名称格式如 <service-name>.<replica-number>

Swarm 节点 ≠ 任务上限

每台机器(节点)可以运行多个服务任务(容器),只要资源(CPU、内存等)允许。

Docker Swarm 默认会在所有可用节点中智能分配任务,包括重复地在同一个节点上部署多个任务。

全局模式 (global) 下:每个节点只运行一个任务

副本模式 (replicated) 下的任务数量不受限于节点数