swarm是docker自家推出的一个docker集群,相对于kubernetes适合大型企业的大型业务场景,swarm对于小型企业的小型应用场景还是比较简单的,同时对于学习kubernetes集群也有帮助和参考。

前期准备

这里的演示使用almalinux作为底层的操作系统,在虚拟机环境中进行演示。需要准备四台服务器作为本次集群的演示环境,服务器需要提前安装好docker服务且配置好仓库源,四台服务器的配置以及IP设置如下:

序号 主机名 配置 IP地址
1 docker-mgr1 CPU:2CORE;内存:2G;硬盘:60G 192.168.42.61
2 docker-mgr2 CPU:2CORE;内存:2G;硬盘:60G 192.168.42.62
3 docker-worker1 CPU:2CORE;内存:2G;硬盘:60G 192.168.42.71
4 docker-worker2 CPU:2CORE;内存:2G;硬盘:60G 192.168.42.72

集群的数量根据您的实际需求而定,可以不用和我的演示数量一致,需要有最少一个管理节点和两个工作节点即可组成最小的swarm集群。

因为是演示集群的部署,虚拟机的配置不用很高。根据自己的情况配置运行不会很卡顿就可以。使用虚拟机的话,可以先部署完一台服务器并配置完成,其余的三台使用克隆的方式复制出来即可,复制完成后记得重新生产虚拟机的网卡MAC地址。

以上服务器提前把防火墙都关闭了。以免集群间不能通讯。

初始化集群

在已经安装好 Docker 的主机上,也就是上面列表中的docker-mgr1(192.168.42.61)执行命令docker swarm init来初始化集群:

[root@docker-mgr1 ~]# docker swarm init --advertise-addr=192.168.42.61
Swarm initialized: current node (j5w3ramf37t1xxwnhellr9rtf) is now a manager.

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

    docker swarm join --token SWMTKN-1-585i7zpaidxfhiavtd2q5cxn316tzw16fpyqyiccn0wjscood0-4tjojsw81mwdywgg6mci3gurb 192.168.42.61:2377

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

管理节点和工作节点的加入token是不一样的上面的命令中只给出了工作节点的加入命令的完整格式,包括必须的集群token。如果需要加入的是管理节点的话,它也给出了获取集群token的命令docker swarm join-token manager。

如果你的 Docker 主机有多个网卡,拥有多个 IP,必须使用 --advertise-addr 指定 IP。

执行 docker swarm init 命令的节点自动成为管理节点且leader。

增加管理节点

执行docker swarm join-token manager获取管理节点加入集群的token和完整命令。

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

    docker swarm join --token SWMTKN-1-585i7zpaidxfhiavtd2q5cxn316tzw16fpyqyiccn0wjscood0-8or6g8vtm4s9rp4yxq64mq0aw 192.168.42.61:2377

获取到token和完整的加入集群的命令后,在docker-mgr2(192.168.42.62)执行命令加入集群的命令:

[root@docker-mgr2 ~]# docker swarm join --token SWMTKN-1-585i7zpaidxfhiavtd2q5cxn316tzw16fpyqyiccn0wjscood0-8or6g8vtm4s9rp4yxq64mq0aw 192.168.42.61:2377
This node joined a swarm as a manager.

执行结果有输出This node joined a swarm as a manager.这表示节点已经加入到集群中了。

通过下面命令docker node ls来查看集群的信息。

[root@docker-mgr1 ~]# docker node ls
ID                            HOSTNAME      STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
j5w3ramf37t1xxwnhellr9rtf *   docker-mgr1   Ready     Active         Leader           27.2.0
ignivgt0cvwftziij0qdswikm     docker-mgr2   Ready     Active         Reachable        27.2.0

从上面的运行结果中,我们可以看到,集群有两个节点,且两个都是活动的状态。

添加管理节点的token只有24小时的时效,过期会失效,失效之后如果需要添加新的工作节点,需要重新执行docker swarm join-token manager获取最新的token。

增加工作节点

上面我们初始化了一个 Swarm 集群,并添加了额外的一个管理节点,现在集群已经拥有了两个管理节点,下面我们继续把剩下的两个有Docker服务的主机(192.168.42.71、192.168.42.72)也分别执行加入集群的命令,创建工作节点并加入到集群中。token和命令在初始化集群时已经有输出。我们直接拿来用就可以。

工作节点1(192.168.42.71)上面执行:

[root@docker-worker1 ~]# docker swarm join --token SWMTKN-1-585i7zpaidxfhiavtd2q5cxn316tzw16fpyqyiccn0wjscood0-4tjojsw81mwdywgg6mci3gurb 192.168.42.61:2377
This node joined a swarm as a worker.

工作节点2(192.168.42.72)上面执行:

[root@docker-worker2 ~]# docker swarm join --token SWMTKN-1-585i7zpaidxfhiavtd2q5cxn316tzw16fpyqyiccn0wjscood0-4tjojsw81mwdywgg6mci3gurb 192.168.42.61:2377
This node joined a swarm as a worker.

有看见输出This node joined a swarm as a worker.即表示节点加入到集群的操作是成功的。

再次在管理节点上使用docker node ls命令来查看集群的信息。

[root@docker-mgr1 ~]# docker node ls
ID                            HOSTNAME         STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
j5w3ramf37t1xxwnhellr9rtf *   docker-mgr1      Ready     Active         Leader           27.2.0
ignivgt0cvwftziij0qdswikm     docker-mgr2      Ready     Active         Reachable        27.2.0
wbf2i1imojh30rxlcx4445z06     docker-worker1   Ready     Active                          27.2.0
be8d8iilz790l958ohu93dagv     docker-worker2   Ready     Active                          27.2.0

可以看到,现在咱们的集群已经有四个节点了。

添加工作节点的token只有24小时的时效,过期会失效,失效之后如果需要添加新的工作节点,需要重新执行docker swarm join-token worker获取最新的token。

查看集群信息

经过上面的一轮部署命令下来,现在我们已经拥有了一个小型的 Swarm 集群,它包含两个管理节点和两个工作节点。两个管理节点一个是leader,也就是主的管理节点,

在管理节点使用 docker node ls 查看集群。

[root@docker-mgr1 ~]# docker node ls
ID                            HOSTNAME         STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
j5w3ramf37t1xxwnhellr9rtf *   docker-mgr1      Ready     Active         Leader           27.2.0
ignivgt0cvwftziij0qdswikm     docker-mgr2      Ready     Active         Reachable        27.2.0
wbf2i1imojh30rxlcx4445z06     docker-worker1   Ready     Active                          27.2.0
be8d8iilz790l958ohu93dagv     docker-worker2   Ready     Active                          27.2.0

另外,如果想单独查看某个指定的节点的信息,可以使用docker node inspect <node_name>,这里的node_name就是docker node ls输出中的HOSTNAME列中的节点主机名。

[root@docker-mgr1 ~]# docker node inspect docker-worker1
[
    {
        "ID": "wbf2i1imojh30rxlcx4445z06",
        "Version": {
            "Index": 27
        },
        "CreatedAt": "2024-08-31T04:11:48.747424777Z",
        "UpdatedAt": "2024-08-31T04:11:48.802225055Z",
        "Spec": {
            "Labels": {},
            "Role": "worker",
            "Availability": "active"
        },
        "Description": {
            "Hostname": "docker-worker1",
            "Platform": {
                "Architecture": "x86_64",
                "OS": "linux"
            },
            "Resources": {
                "NanoCPUs": 2000000000,
                "MemoryBytes": 1828098048
            },
            "Engine": {
                "EngineVersion": "27.2.0",
                "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": "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-----\nMIIBazCCARCgAwIBAgIUV6M1Nwz+JmSaSqvPvlmgKnnL0IgwCgYIKoZIzj0EAwIw\nEzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMjQwODMxMDM1MTAwWhcNNDQwODI2MDM1\nMTAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABNvpa1ohaGvr2VVSfSbElot4ESWMh26IEJIrC3xg41vN4UDtbG6nueVeVyHR\naAvrWuoVTNvDIQ6X8vkUUHgwoFajQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB\nAf8EBTADAQH/MB0GA1UdDgQWBBRqp2KX5aX94q2ZAiw3Vj8nQl/hsjAKBggqhkjO\nPQQDAgNJADBGAiEAuuQwziPDuM6YCu1S7QqxGngOp/wAy+BoOz/or0Eit4UCIQCJ\nXESn3iTlG/Cryb0gBjj2oL8okb3MXST2qWkpppeptA==\n-----END CERTIFICATE-----\n",
                "CertIssuerSubject": "MBMxETAPBgNVBAMTCHN3YXJtLWNh",
                "CertIssuerPublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2+lrWiFoa+vZVVJ9JsSWi3gRJYyHbogQkisLfGDjW83hQO1sbqe55V5XIdFoC+ta6hVM28MhDpfy+RRQeDCgVg=="
            }
        },
        "Status": {
            "State": "ready",
            "Addr": "192.168.42.71"
        }
    }
]

和上面的查看集群信息命令一样,都必须是在管理节点上执行,工作节点没有权限执行。

在节点上查看自己的节点信息可以使用docker info查看,这个命令也会显示出swarm的信息而且任意节点都可以查看。

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

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 27.2.0
 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: systemd
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 Swarm: active
  NodeID: be8d8iilz790l958ohu93dagv
  Is Manager: false
  Node Address: 192.168.42.72
  Manager Addresses:
   192.168.42.61:2377
   192.168.42.62:2377
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 472731909fa34bd7bc9c087e4c27943f9835f111
 runc version: v1.1.13-0-g58aa920
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version: 5.14.0-427.13.1.el9_4.x86_64
 Operating System: AlmaLinux 9.4 (Seafoam Ocelot)
 OSType: linux
 Architecture: x86_64
 CPUs: 2
 Total Memory: 1.703GiB
 Name: docker-worker2
 ID: 27f9b028-fde8-429d-b5c9-333d2225de6c
 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