Docker-Swarm

发布时间 2023-04-02 11:40:38作者: libing-zhang

Docker-Swarm

一、什么是Docker Swarm?

Swarm是Docker的一个编排工具,在之前我们只是在一台机器来进行docker的管理:

img

  但是有时容器并不一定都在一台主机上,如果是分布式的处于多台主机上,这时就可以借助于Swarm,Swarm是Docker自带的编排工具,只要你安装了Docker就会存在Docker Swarm工具。

img

  Swarm中的模式是有两大类节点,一类是manager节点,另一类是worker节点,manager节点相当于对服务的创建和调度,worker节点主要是运行容器服务,当然manager节点也是可以运行的。

img

manager节点状态、信息的同步根据Raft consensus group的网络进行通信同步的,而worker之间的通信依靠的是Gossip network做到的。

另外一个重要的概念就是service,我们可以在一个manager节点上创建一个服务,但是可以根据这一个服务创建多个容器的任务,这些容器任务运行在不同的节点上。

img

那么如何进行Swarm集群的搭建呢?

  • 在swarm模式下初始化一个Swarm集群,并且将当前主机加入到该集群作为manager节点
  • 加入其它节点到该集群中
  • 部署service到该集群中

二、Docker Swarm集群搭建

(一)创建多节点集群

1、查看Swarm命令

[root@centos-7 ~]# docker swarm --help

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.

可以看到其中有一个 init的命令,这就是初始化一个Swarm,我们再看看这个init的参数:

[root@centos-7 ~]# 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)

可以看到它有很多的参数,其中第一个就是将本机的地址添加进去,让自己成为一个Manager节点,这样其它的节点都可以知道这个节点的存在。

2、创建一个Manager节点

在此之前我们应该先知道自己本机的ip,以便于–advertise-addr string 这个参数使用,查看本机ip:

然后就可以初始化Manager节点:

[root@centos-7 ~]# docker swarm init --advertise-addr=192.168.0.108
Swarm initialized: current node (sz7bfcmk637qhqfvzqhdnk3t2) is now a manager.

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

    docker swarm join --token SWMTKN-1-0zzpk3xqq2ykb5d5jcd6hqeimckhrg5qu82xs7nw2wwnwyjmzg-9tmof9880m9r92vz5rygaa42e 192.168.0.108:2377

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

可以看到已经创建了一个swarm manager节点–advertise-addr参数的值192.168.0.108是自己的ip,相当于将自己加入到swarm中。它也说明了其它worker加入的方式。

3、创建一个worker节点

另外再开启一台虚拟机,将这台机器加入到swarm中成为worker节点:

[root@localhost ~]#  docker swarm join --token SWMTKN-1-0zzpk3xqq2ykb5d5jcd6hqeimckhrg5qu82xs7nw2wwnwyjmzg-9tmof9880m9r92vz5rygaa42e 192.168.0.108:2377
This node joined a swarm as a worker.

可以看到已经成功了。

4、查看节点状态

注意的是查看节点状态只能在manager节点那台机器上查看,普通节点无法执行查看命令:

[root@centos-7 ~]# docker node ls
ID                            HOSTNAME                STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
sz7bfcmk637qhqfvzqhdnk3t2 *   centos-7                Ready               Active              Leader              19.03.5
89tezea9ltn6mqek7b48gtve7     localhost.localdomain   Ready               Active                                  18.09.7

可以看到有两台机器了。

(二)多节点容器创建

上面我们已经将节点创建好了,现在可以在这些节点上创建容器了,那么就需要看看docker service 的帮助信息:

[root@centos-7 ~]# docker service --help

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这个命令,可以这样理解,docker service create 相当于docker run 就是创建容器,只不过在swarm中是不同的表现方式。

1、manager节点上创建容器

[root@centos-7 docker]# docker service create --name nginx-demo nginx
image busybox:latest could not be accessed on a registry to record
its digest. Each node will access busybox:latest independently,
possibly leading to different nodes running different
versions of the image.

edqgwqjka7ceyym9tg4gr9uim
overall progress: 1 out of 1 tasks 
1/1: running   
verify: Service converged 

可以查看是否创建成功:

[root@centos-7 docker]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
edqgwqjka7ce        demo                replicated          1/1                 busybox:latest      

可以具体看这个service的内容:

[root@centos-7 docker]# docker service ps demo
ID                  NAME                IMAGE               NODE                    DESIRED STATE       CURRENT STATE           ERROR    PORTS
lshgq4gfi3cv        demo.1              busybox:latest      localhost.localdomain   Running             Running 2 minutes ago   

2、水平扩展

  • 水平扩展

之前接触或scale,它可以帮助我们创建多个service,这里也是可行的:

[root@centos-7 docker]# docker service scale demo=5
demo 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 

已经有5个demo服务的容器正在运行了。可以先看看serverice:

[root@centos-7 docker]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
edqgwqjka7ce        demo                replicated          5/5                 busybox:latest      

再看看具体的容器数量:

[root@centos-7 docker]# docker service ps demo
ID                  NAME      IMAGE               NODE                    DESIRED STATE       CURRENT STATE       ERROR   PORTS
lshgq4gfi3cv        demo.1   busybox:latest      localhost.localdomain   Running             Running 3 hours ago                       
vvxl3f5p1w40        demo.2   busybox:latest      centos-7                Running             Running 3 hours ago                       
q5imz8pqygbv        demo.3   busybox:latest      centos-7                Running             Running 3 hours ago                       
ih6e2bhzzru2        demo.4   busybox:latest      localhost.localdomain   Running             Running 3 hours ago                       
l32ziu7ygoqw        demo.5   busybox:latest      centos-7                Running             Running 3 hours ago  

可以看到5个容器在不同的节点上,其中有3个容器在manager节点,有两个在worker节点上。

当然,每一个节点都可以自己查看自己目前运行的容器,比如worker节点查看自己运行容器的数量:

[root@centos-7 docker]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS         PORTS        NAMES
fbf77922d24c        busybox:latest      "/bin/sh -c 'while t…"   3 hours ago         Up 3 hours              demo.5.l32ziu7ygoqwapu4rbazqhyej
51e0e953688f        busybox:latest      "/bin/sh -c 'while t…"   3 hours ago         Up 3 hours              demo.3.q5imz8pqygbv5fw1r2wyt84ps
6f2b6d5f670c        busybox:latest      "/bin/sh -c 'while t…"   3 hours ago         Up 3 hours              demo.2.vvxl3f5p1w40oc82wvm2yq01q

只需要通过docker ps命令即可。

  • 修复

scale在swarm中除了水平扩展外,还有一个作用,那就是修复作用,比如将某一个节点中的容器删除掉,那么很快swarm中发觉并进行修复,数量保持原先的样子。

假如现在删除worker中的一个容器:

[root@localhost ~]# docker rm -f a8c8e6a95978
a8c8e6a95978

我们在manager节点中查看容器情况:

[root@centos-7 docker]# docker service ps demo
ID            NAME        IMAGE               NODE               DESIRED STATE   CURRENT STATE       ERROR      PORTS
lshgq4gfi3cv  demo.1     busybox:latest      localhost.localdomain   Running     Running 3 hours ago                                             
vvxl3f5p1w40  demo.2     busybox:latest      centos-7                Running     Running 3 hours ago                                             
q5imz8pqygbv  demo.3     busybox:latest      centos-7                Running    Running 3 hours ago                                             
zkoywf8h19p1  demo.4     busybox:latest      localhost.localdomain   Running   Starting less than a second ago                                 
ih6e2bhzzru2 \_ demo.4  busybox:latest      localhost.localdomain   Shutdown  Failed 23 seconds ago  "task: non-zero exit (137)"   
l32ziu7ygoqw  demo.5     busybox:latest      centos-7                Running    Running 3 hours ago                                             

可以看到红色就是我们删掉的容器,但是后面它又马上补充了一个,保持了整个系统的稳定性。

三、wordpress部署

(一)单容器启动方式

  如何使用Swarm进行部署wordpress呢?wordpress涉及到数据库容器以及wordpress应用容易,那么这两个容器很有可能是不在一台机器的,也就是使用Swarm中两个容器是分配到不同的节点之上的。

  首先,将之前的service进行移除:

[root@centos-7 docker]# docker service rm demo
demo

1、创建overlay网络

需要将这些service部署在一个overlay网络中,所以需要有个overlay网络。所以现在manager节点上创建这个网络:

[root@centos-7 docker]# docker network create -d overlay demo
xcjljjqcw26b2xukuirgpo6au

可以查看:

[root@centos-7 docker]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
xcjljjqcw26b        demo                overlay             swarm

值得注意的是其他节点上现在并没有这个网络,那么其它节点又是怎么连上这个网络的呢?

2、启动数据库服务

[root@centos-7 docker]# docker service create --name mysql --env MYSQL_ROOT_PASSWORD=root --env MYSQL_DATABASE=wordpress --network demo --mount type=volume,source=mysql-data,destination=/var/lib/mysql mysql:5.7.24
eirarnex6suqa4uqzgowncigv
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged 

可以看看这个服务的详情以及位于哪一个节点上:

[root@centos-7 docker]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
eirarnex6suq        mysql               replicated          1/1                 mysql:5.7.24        
[root@centos-7 docker]# docker service ps mysql
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE     ERROR      PORTS
c4a4lggjmvuf        mysql.1             mysql:5.7.24        centos-7            Running             Running about a minute ago   

3、启动wordpress服务

接着在manager节点上启动wordpress服务

[root@centos-7 docker]#  docker service create --name wordpress -p 80:80 --env WORDPRESS_DB-PASSWORD=root \
 --env WORDPRESS_DB_HOST=mysql --network demo \
 --mount type=volume,source=wordpress-config,destination=/var/www/html wordpress

上述中 –mount参数将容器中的配置等一系列的文件映射出来了,是方便修改容器中配置文件,修复数据库连接不上的错误,详情查看:

4、测试

现在可以进行访问本机的80端口进行测试了

img

(二)Docker Stack部署

这种部署方式就是使用docker-compose.yml文件来进行部署应用,而上面那种方式就是每次手动单启容器。

  • 查看docker stack的命令
[root@centos-7 wordpress-stack]# docker stack --help

Usage:    docker stack [OPTIONS] COMMAND

Manage Docker stacks

Options:
      --orchestrator string   Orchestrator to use (swarm|kubernetes|all)

Commands:
  deploy      Deploy a new stack or update an existing stack
  ls          List stacks
  ps          List the tasks in the stack
  rm          Remove one or more stacks
  services    List the services in the stack

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

可以看到docker stack 的命令不是很多,第一个就是部署服务,一个docker-compose.yml就是一个服务,当然这个文件里面可能包含多个service。下面以实例来说明:

  • docker-compose.yml文件
version: '3'

services:

  web:
    image: wordpress
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_PASSWORD: root
    networks:
      - my-network
    depends_on:
      - mysql
    deploy:
      mode: replicated
      replicas: 3      #开启3个web服务
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      update_config:
        parallelism: 1
        delay: 10s

  mysql:
    image: mysql:5.7.24
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: wordpress
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - my-network
    deploy:
      mode: global  #只能有一个mysql的服务
      placement:
        constraints:
          - node.role == manager #服务只能部署在manager节点上

volumes:
  mysql-data:

networks:
  my-network:
    driver: overlay   #注意这里可能服务在不同的主机上,需要使用overlay网络
  • 部署wordpress stack
[root@centos-7 wordpress-stack]# docker stack deploy wordpress --compose-file=docker-compose.yml
Creating network wordpress_my-network
Creating service wordpress_web
Creating service wordpress_mysql
  • 查看stack
[root@centos-7 wordpress-stack]# docker stack ls
NAME                SERVICES            ORCHESTRATOR
wordpress           2                   Swarm
  • 查看stack中的服务
[root@centos-7 wordpress-stack]# docker stack ps wordpress
  • 移除stack
[root@centos-7 wordpress-stack]# docker stack rm wordpress
Removing service wordpress_mysql
Removing service wordpress_web
Removing network wordpress_my-network