Docker三剑客——Docekr Swarm

目录

 一、概述

二、Swarm 的核心概念

1. Node(节点)

2. Service(服务)

3. Task(任务)

三、Swarm 服务的运行部分

1. 工作节点

2. 服务、任务和容器

3. 任务和调度

4. 副本服务和全局服务

四、Swarm 的调度策略

1. Spread

2. Binpack

3. Random

五、创建Swarm集群过程

六、Docker Swarm常用管理命令

1. docker swarm 集群管理命令

2. docker node 集群节点管理命令

3. docker service 集群服务管理命令

七、Swarm 集群的部署

1. 部署环境准备

2. 下载Swarm镜像

3. 创建 Swarm 并初始化

4. 查看当前的信息

5. 将node1和node2加入集群

6. 查看集群节点状态

7. Swarm集群的web管理

 八、Docker Swarm部署服务实战

1. 创建网络

2. 创建服务

 3. 在线动态扩容服务

4. 节点故障处理


官方文档地址:How nodes work | Docker Swarm

 

 一、概述

        Docker SwarmDocker Compose都是 Docker 容器的编排技术。两者的区别在于:Docker Compose 是一个能在单台服务器主机创建多个容器的工具,而Docker Swarm 则可以在多台服务器主机上创建容器集群。

        Swarm 是基于 Docker 平台实现的集群技术,可以通过几条简单的指令快速的创建一个Docker集群,接着在集群的共享网络上部署应用,最终实现分布式的服务。

        Swarm 也是目前 Docker 官方唯一指定的容器集群管理工具,其主要作用是把若干台Docker 主机抽象为一个整体,并且通过一个入口统一管理这些Docker主机上的各种Docker资源。

        Swarm Kubernetes 比较类似,但是更加轻便,功能也相对少一点。Swarm 集群提供给用户管理集群内所有容器的操作接口与使用Docker主机基本相同。

二、Swarm 的核心概念

1. Node(节点)

        Node 是一个已加入 Docker Swarm 集群中的容器示例。 

2. Service(服务)

        Service主要在工作节点上执行任务,创建服务时,需要指定容器的镜像。

3. Task(任务)

        Task 是在容器中执行的命令。

三、Swarm 服务的运行部分

        Swarm 服务的工作及运行包括以下4部分:

1. 工作节点

        工作节点是运行服务的主机或服务器

2. 服务、任务和容器

        当服务部署到集群时,管理者将服务定义为服务所需的状态,然后将服务调试为一个或多个副本任务,这些任务在集群的节点上时独立运行的。

        容器是一个独立的进程。在Swarm模型中,每个任务调用一个容器。任务类似于插槽,调度器将容器放入插槽中。一旦容器运行,调度器就认为此任务处于运行状态。如果容器的健康监测出现问题,则任务也将终止。

3. 任务和调度

        任务是集群内调度的原子单位。当创建或更新服务所需的服务状态时,协调者通过调度任务来实现这些所需的状态。

        任务是一个单向机制,通过分配、准备、运行等状态单独运行。如果任务失败,协调者将删除任务以及容器,然后更新服务所需的状态重新创建一个新的任务来替代它。

4. 副本服务和全局服务

        副本服务与全局服务是服务部署的两种类型。

        对于副本服务,指定要运行的相同任务的数量,每个副本都具有相同的内容。

        全局服务是在每个节点上运行一个任务的服务,不需要预先指定任务数量。   

四、Swarm 的调度策略

        Swarm 在 scheduler 节点(leader节点)运行容器时,会根据指定的策略来计算最适合运行容器的节点,目前支持的策略有 Spread,Binpack,Random。

1. Spread

        在同等条件下,Spread 策略会选择运行容器最少的那个节点来运行新的容器。使用Spread 策略会使得容器均衡的分布在集群中的各个节点上运行,一旦一个节点挂掉了,只会损失少部分的容器。

2. Binpack

        Binpack策略可以最大化的避免容器碎片化,就是说 Binpack 策略尽可能地把还未使用的节点留给需要更大空间的容器运行,把容器运行在一个节点上面。

3. Random

        Random 策略时随机选择一个节点来运行容器,一般用作调试。

五、创建Swarm集群过程

        一个Swarm集群的创建需要经历以下三个过程:

(1)发现Docker集群中的各个节点,收集节点状态和角色信息,并监视节点状态的变化。

(2)初始化内部调度(scheduler)模块。

(3)创建并启动API监听服务模块。

        一旦创建好这个集群,就可以用“docker service” 命令批量对集群内的容器进行操作。在启动容器后,Docker会根据当前每个Swarm节点的负载进行判断,在负载最优的节点上运行这个任务,用“docker service ls” “docker service ps + taskId” 可以看到任务运行在哪个节点上。

六、Docker Swarm常用管理命令

1. docker swarm 集群管理命令

参数说明
init初始化集群
join

将某个节点加入集群

join-token管理加入令牌
leave

从集群中将某个节点删除,强制删除参数为 --force

update更新集群
unlock解锁集群

2. docker node 集群节点管理命令

参数说明
demote将集群中一个或多个节点降级
inspect显示集群中一个或多个节点的详细信息
ls列出集群中所有节点
promote将集群中一个或多个节点提升为管理节点
rm从集群中删除停止的节点,强制删除 --force
ps列出集群中一个或多个节点上运行的任务
update更新节点

3. docker service 集群服务管理命令

参数说明
create创建一个新的服务
inspect列出一个或多个服务的详细信息
ps列出一个或多个服务中的任务信息
ls列出所有服务
rm删除一个或多个服务
scale扩展一个或多个服务
update更新服务

七、Swarm 集群的部署

1. 部署环境准备

准备三台服务器,服务器规划如下表:

服务器角色服务器IP备注
Swarm 集群管理节点192.168.65.130主机名:manager
Swarm 集群节点192.168.65.129主机名:node1
Swarm 集群节点192.168.65.128主机名:node2

修改服务器主机名,配置hosts文件:

[root@manager ~]# cat >>/etc/hosts<<EOF
> 192.168.65.130 manager
> 192.168.65.129 node1
> 192.168.65.128 node2
> EOF
[root@manager ~]# tail -3 /etc/hosts
192.168.65.130 manager
192.168.65.129 node1
192.168.65.128 node2

测试能否ping通node1和node2节点:

[root@manager ~]# ping node1
PING node1 (192.168.65.129) 56(84) bytes of data.
64 bytes from node1 (192.168.65.129): icmp_seq=1 ttl=64 time=1.11 ms
64 bytes from node1 (192.168.65.129): icmp_seq=2 ttl=64 time=1.58 ms
64 bytes from node1 (192.168.65.129): icmp_seq=3 ttl=64 time=0.466 ms
^C
--- node1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 0.466/1.056/1.587/0.460 ms
[root@manager ~]# ping node2
PING node2 (192.168.65.128) 56(84) bytes of data.
64 bytes from node2 (192.168.65.128): icmp_seq=1 ttl=64 time=0.942 ms
64 bytes from node2 (192.168.65.128): icmp_seq=2 ttl=64 time=0.512 ms
64 bytes from node2 (192.168.65.128): icmp_seq=3 ttl=64 time=0.577 ms
^C
--- node2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.512/0.677/0.942/0.189 ms

node1和node2节点的 hosts 配置和上面一致。

2. 下载Swarm镜像

所有节点都需要下载Swarm镜像:

[root@manager ~]# docker pull swarm

[root@manager ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
swarm        latest    1a5eb59a410f   2 years ago   12.7MB

3. 创建 Swarm 并初始化

        执行如下命令,将manager节点加入集群中,同时会产生一个唯一的 token 值,其他节点加入集群的时候需要用到这个token。

--advertise-addr 表示Swarm集群中其他节点使用后面的IP地址与管理节点通信。

下面的输出中也提示了其他节点加入集群的命令:

docker swarm join --token SWMTKN-1-2woh1eb077rtf1q7qp3komnit9gzk7hey7xpdvkeqqy7fmvfxa-3azlbbg466c5ltbxn8fn4z1o3 192.168.65.130:2377
[root@manager ~]# docker swarm init --advertise-addr 192.168.65.130
Swarm initialized: current node (vnesir8jo7gbxihtxfs3kh8di) is now a manager.

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

    docker swarm join --token SWMTKN-1-2woh1eb077rtf1q7qp3komnit9gzk7hey7xpdvkeqqy7fmvfxa-3azlbbg466c5ltbxn8fn4z1o3 192.168.65.130:2377

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

4. 查看当前的信息

[root@manager ~]# docker info
Client:
 Context:    default
 Debug Mode: false
 Plugins:
  app: Docker App (Docker Inc., v0.9.1-beta3)
  buildx: Docker Buildx (Docker Inc., v0.9.1-docker)
  scan: Docker Scan (Docker Inc., v0.23.0)

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 1
 Server Version: 20.10.22
 Storage Driver: overlay2
  Backing Filesystem: xfs
  Supports d_type: true
  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 logentries splunk syslog
 Swarm: active
  NodeID: vnesir8jo7gbxihtxfs3kh8di
  Is Manager: true
  ClusterID: fn4adm9k7a7knt79zsx0de7eb
  Managers: 1
  Nodes: 1
  Default Address Pool: 10.0.0.0/8  
  SubnetSize: 24
  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.65.130
  Manager Addresses:
   192.168.65.130:2377
 Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 9ba4b250366a5ddde94bb7c9d1def331423aa323
 runc version: v1.1.4-0-g5fd4c4d
 init version: de40ad0
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 3.10.0-1160.el7.x86_64
 Operating System: CentOS Linux 7 (Core)
 OSType: linux
 Architecture: x86_64
 CPUs: 2
 Total Memory: 1.777GiB
 Name: manager
 ID: NZU5:JH77:546X:VTNX:BSXT:UITP:MYHY:6NZ7:YH6Q:PYU2:BBQX:FEHC
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

查看当前集群所有节点: 目前只有管理节点

[root@manager ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
vnesir8jo7gbxihtxfs3kh8di *   manager    Ready     Active         Leader           20.10.22

5. 将node1和node2加入集群

[root@node1 ~]# docker swarm join --token SWMTKN-1-2woh1eb077rtf1q7qp3komnit9gzk7hey7xpdvkeqqy7fmvfxa-3azlbbg466c5ltbxn8fn4z1o3 192.168.65.130:2377
This node joined a swarm as a worker.
[root@node2 ~]# docker swarm join --token SWMTKN-1-2woh1eb077rtf1q7qp3komnit9gzk7hey7xpdvkeqqy7fmvfxa-3azlbbg466c5ltbxn8fn4z1o3 192.168.65.130:2377
This node joined a swarm as a worker.

6. 查看集群节点状态

Swarm集群中node的AVAILABLITY状态有ActiveDrain

其中:Active状态的节点可以接受管理节点的任务指派,Drain状态的节点会结束任务,但不会接受管理节点的任务指派,节点处于下线状态。

[root@manager ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
vnesir8jo7gbxihtxfs3kh8di *   manager    Ready     Active         Leader           20.10.22
lq0vgrgtwzlzybpxcfxi03y1n     node1      Ready     Active                          20.10.22
r48mnegbxml056jkk0k9c0ng8     node2      Ready     Active                          20.10.22

切换node2的状态:

切换为 Drain

[root@manager ~]# docker node update --availability drain node2
node2

[root@manager ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
vnesir8jo7gbxihtxfs3kh8di *   manager    Ready     Active         Leader           20.10.22
lq0vgrgtwzlzybpxcfxi03y1n     node1      Ready     Active                          20.10.22
r48mnegbxml056jkk0k9c0ng8     node2      Ready     Drain                           20.10.22

切换回 Active 

[root@manager ~]# docker node update --availability active node2
node2
[root@manager ~]# docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
vnesir8jo7gbxihtxfs3kh8di *   manager    Ready     Active         Leader           20.10.22
lq0vgrgtwzlzybpxcfxi03y1n     node1      Ready     Active                          20.10.22
r48mnegbxml056jkk0k9c0ng8     node2      Ready     Active                          20.10.22

在manager节点上查看状态信息:

[root@manager ~]# docker node inspect self
[
    {
        "ID": "vnesir8jo7gbxihtxfs3kh8di",
        "Version": {
            "Index": 9
        },
        "CreatedAt": "2023-01-09T15:33:39.776148204Z",
        "UpdatedAt": "2023-01-09T15:33:40.292319277Z",
        "Spec": {
            "Labels": {},
            "Role": "manager",
            "Availability": "active"
        },
        "Description": {
            "Hostname": "manager",
            "Platform": {
                "Architecture": "x86_64",
                "OS": "linux"
            },
            "Resources": {
                "NanoCPUs": 2000000000,
                "MemoryBytes": 1907744768
            },
            "Engine": {
                "EngineVersion": "20.10.22",
                "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-----\nMIIBazCCARCgAwIBAgIURK49dyMZAJlkF/+KhZ2ZRwk6hHcwCgYIKoZIzj0EAwIw\nEzERMA8GA1UEAxMIc3dhcm0tY2EwHhcNMjMwMTA5MTUyOTAwWhcNNDMwMTA0MTUy\nOTAwWjATMREwDwYDVQQDEwhzd2FybS1jYTBZMBMGByqGSM49AgEGCCqGSM49AwEH\nA0IABI8ig6isgQODWUgSsSSKj2hpK1Ig1V8anqhu7IySfSeZIvNqa5MqNp54pT4z\nwgXuULB66mh6N3JlzJ9tpVN/WmyjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB\nAf8EBTADAQH/MB0GA1UdDgQWBBRKK/w5BkNfYY1tDMhNz8od06a+FTAKBggqhkjO\nPQQDAgNJADBGAiEA/VX4ilaDtBobsqitqJZWQfIQFB8D1ky+gkFSsOTkhJUCIQCR\nu5k9T23i2CgboMdA3Ll9TxrOgF4B+qRgmp3auhXFTw==\n-----END CERTIFICATE-----\n",
                "CertIssuerSubject": "MBMxETAPBgNVBAMTCHN3YXJtLWNh",
                "CertIssuerPublicKey": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjyKDqKyBA4NZSBKxJIqPaGkrUiDVXxqeqG7sjJJ9J5ki82prkyo2nnilPjPCBe5QsHrqaHo3cmXMn22lU39abA=="
            }
        },
        "Status": {
            "State": "ready",
            "Addr": "192.168.65.130"
        },
        "ManagerStatus": {
            "Leader": true,
            "Reachability": "reachable",
            "Addr": "192.168.65.130:2377"
        }
    }
]

7. Swarm集群的web管理

部署Web管理(使用portainer):

portainer优缺点:

优点:

(1)支持容器管理和镜像管理

(2)部署配置简单,属于轻量级

(3)基于Docker API,安全性高,支持TLS证书认证

(4)支持权限分配

(5)支持集群

缺点:

(1)功能较弱

(2)容器管理不便

[root@manager ~]# docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer

Web管理登录:

访问8088端口,需要先创建用户:

点击Swarm菜单,可以看到Swarm集群的状态信息:

 

 八、Docker Swarm部署服务实战

1. 创建网络

部署服务前,先创建几个用于集群内不同主机之间容器通信的网络。

[root@manager ~]# docker network create -d overlay dockernet
19hcx39gaenoermz90zrrsu6v
[root@manager ~]# docker network ls
NETWORK ID     NAME              DRIVER    SCOPE
b5f197fd4cf0   bridge            bridge    local
be209a4c60a6   docker_gwbridge   bridge    local
19hcx39gaeno   dockernet         overlay   swarm
34f3db72e609   host              host      local
i6ljilnnt163   ingress           overlay   swarm
21bc223f3cd7   none              null      local

2. 创建服务

创建Nginx服务:

--replicas 指定副本数量

[root@manager ~]# docker service create --replicas 1 --network dockernet --name nginx-cluster -p 80:80 nginx
obrqkh0eewqfnvq5h10ymeuj8
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged 

列出所有服务:

[root@manager ~]# docker service ls
ID             NAME            MODE         REPLICAS   IMAGE          PORTS
obrqkh0eewqf   nginx-cluster   replicated   1/1        nginx:latest   *:80->80/tcp

列出nginx-cluster服务中的任务信息:

[root@manager ~]# docker service ps nginx-cluster
ID             NAME              IMAGE          NODE      DESIRED STATE   CURRENT STATE           ERROR     PORTS
xaqvwxeu81i4   nginx-cluster.1   nginx:latest   node1     Running         Running 2 minutes ago 

可以看到在node1上运行,在node1节点查看容器:

[root@node1 ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS          PORTS     NAMES
64b58014656d   nginx:latest   "/docker-entrypoint.…"   8 minutes ago        Up 7 minutes    80/tcp    nginx-cluster.1.xaqvwxeu81i4c1wj6ht1jsgcm

 3. 在线动态扩容服务

[root@manager ~]# docker service scale nginx-cluster=5
nginx-cluster scaled to 5
overall progress: 5 out of 5 tasks 
1/5: running   [==================================================>] 
2/5: running   [==================================================>] 
3/5: running   [==================================================>] 
4/5: running   [==================================================>] 
5/5: running   [==================================================>] 
verify: Service converged 

列出nginx-cluster服务中的任务信息:

可以看到服务动态扩容至5个,即5个容器运行着相同的服务,node1上运行着两个,node2上运行着两个。

[root@manager ~]# docker service ps nginx-cluster
ID             NAME              IMAGE          NODE      DESIRED STATE   CURRENT STATE                ERROR     PORTS
xaqvwxeu81i4   nginx-cluster.1   nginx:latest   node1     Running         Running 9 minutes ago                  
gs7rv8phomso   nginx-cluster.2   nginx:latest   node2     Running         Running about a minute ago             
ziru1c6u7v4b   nginx-cluster.3   nginx:latest   node1     Running         Running 3 minutes ago                  
9zxjl51qs0cd   nginx-cluster.4   nginx:latest   manager   Running         Running about a minute ago             
a2kg9dk0309r   nginx-cluster.5   nginx:latest   node2     Running         Running about a minute ago  

4. 节点故障处理

        如果集群中的节点发生故障,会从Swarm集群中被剔除,然后利用自身的负载均衡及调度功能,将服务调度到其他节点上。

停止node1的其中一个容器:

[root@node1 ~]# docker stop 64b58014656d
64b58014656d

列出nginx-cluster服务中的任务信息:

可以看到在 manager 节点重启了一个容器,来代替刚才挂掉的那个

[root@manager ~]# docker service ps nginx-cluster
ID             NAME                  IMAGE          NODE      DESIRED STATE   CURRENT STATE             ERROR     PORTS
rmca33t8f9k3   nginx-cluster.1       nginx:latest   manager   Running         Running 48 seconds ago              
xaqvwxeu81i4    \_ nginx-cluster.1   nginx:latest   node1     Shutdown        Complete 55 seconds ago             
gs7rv8phomso   nginx-cluster.2       nginx:latest   node2     Running         Running 7 minutes ago               
ziru1c6u7v4b   nginx-cluster.3       nginx:latest   node1     Running         Running 9 minutes ago               
9zxjl51qs0cd   nginx-cluster.4       nginx:latest   manager   Running         Running 7 minutes ago               
a2kg9dk0309r   nginx-cluster.5       nginx:latest   node2     Running         Running 7 minutes ago 

如果需要删除节点上所有容器和任务,可以执行:

[root@manager ~]# docker rm nginx-cluster

以上就是关于Docker Swarm 的介绍。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小印z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值