docker swarm集群部署(一)

一、概述

Docker Swarm是Docker官方项目之一,提供docker容器集群服务,是docker官方对容器云生态进行支持的核心方案,通过它,可以将多个docker主机封装成单个大型虚拟机docker主机,快速打造容器云平台
swarm中一台主机就是一个节点,节点分为管理节点和工作节点,管理节点管理swarm集群,一个swarm集群可以有多个管理节点,但是只有一个节点可以成为leader
管理节点内置Raft数据库,存放配置数据,管理节点之间通信是加密的,通过swarm可以一次性通过swarm创建多个容器,不用一个个去创建
03swarm1
manager节点状态、信息的同步根据Raft consensus group的网络进行通信同步的,而worker之间的通信依靠的是Gossip network

二、环境准备

三台ECS服务器,均为2cpu、4g内存

  • 172.19.159.7 manager
  • 172.19.159.8 worker
  • 172.19.159.9 worker

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

三、swarm集群部署

分三步:

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

3.1.集群初始化

1.创建一个manager节点
docker swarm init --advertise-addr=172.19.159.7
输出如下提示

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

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

    docker swarm join --token SWMTKN-1-1hl47x8zhs3g5xb6d8o2lumkpm8e22qpahz43utoaijb68n2cq-2wflswbzqxeb6gu06c2sb53w0 172.19.159.7:2377

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

上面的提示说明了如何将其他节点加入该集群
2.添加worker节点
docker swarm join --token SWMTKN-1-1hl47x8zhs3g5xb6d8o2lumkpm8e22qpahz43utoaijb68n2cq-2wflswbzqxeb6gu06c2sb53w0 172.19.159.7:2377
This node joined a swarm as a worker
3.查看节点
docker node ls

ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
85l1qeexhi44tk31n81j06com *   node-1              Ready               Active              Leader              18.03.1-ce
bk1ivh4wo2ny1e6u82n9sz0t2     node-2              Ready               Active                                  18.03.1-ce
jtqlorda2hy9ue1hci3tm48ax     node-3              Ready               Active                                  18.03.1-ce              Ready               Active                                  18.03.1-ce

4.退出集群
比如将172.19.159.9这个worker节点退出集群
在此节点上执行
docker swarm leave
查看集群节点
docker node ls

ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
85l1qeexhi44tk31n81j06com *   node-1              Ready               Active              Leader              18.03.1-ce
bk1ivh4wo2ny1e6u82n9sz0t2     node-2              Ready               Active                                  18.03.1-ce
jtqlorda2hy9ue1hci3tm48ax     node-3              Down                Active                                  18.03.1-ce

再比如将172.19.159.7这个manager节点退出集群,这个时候分两种情况:

  • 集群上没有其他worker节点
    在此节点上执行
    docker swarm leave
  • 集群上还有其他worker节点
    在此节点上执行
    docker swarm leave --force (worker节点down掉了也属于此种情况)

注意集群初始化的时候只能有一个节点,不论是后面加入的节点是worker还是manager,比如现在将172.19.159.7这个节点初始化了成为一个manager节点,现在只需要到172.19.159.8执行加入集群的相关命令即可

5.集群上部署应用
部署2个nginx副本
manager上执行
docker service create --name my-web --publish published=8080,target=80 --replicas 2 nginx
查看
docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
b5m2cw7aytnn        my-web              replicated          2/2                 nginx:latest        *:8080->80/tcp

另外两个worker上
docker ps查看启动的容器

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
0cb091b66be4        nginx:latest        "nginx -g 'daemon of…"   19 minutes ago      Up 19 minutes       80/tcp              my-web.1.p8lria15vu18i7te42jb93m7r

更改两个nginx应用的站点内容,访问任何一个节点加上发部端口即可访问nginx容器内的服务,而且自动实现负载均衡,具体点说就是当我们访问节点加端口8080,service会通过ingress网格路由将请求分发至两个nginx容器

下面在部署一个service
docker service create --name test1 alpine ping www.baidu.com
docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
b5m2cw7aytnn        my-web              replicated          2/2                 nginx:latest        *:8080->80/tcp
2f19xkbbitki        test1               replicated          1/1                 alpine:latest     

6.集群网络
部署好应用后我们最关心的应该就是各个应用之间是如何通信的,先来看一下管理节点上存在着哪些网络
docker network ls

NETWORK ID          NAME                DRIVER              SCOPE
65629ae783f4        bridge              bridge              local
89ae12fb2946        docker_gwbridge     bridge              local
5f6f18c1a815        host                host                local
mc6sa17bsn7v        ingress             overlay             swarm
fc6214c23454        none                null                local
5a4301ea8b75        vmbridge            bridge              local

overlay网络驱动程序会创建多个Docker守护主机之间的分布式网络。该网络位于(覆盖)特定于主机的网络之上,允许连接到它的容器(包括群集服务容器)安全地进行通信

现在做个测试,进到test1服务下的应用去访问my-web服务下的nginx应用
docker exec -it test1.1.y3keifol2nargx1ealfq65x9h bash

/ # ping my-web
ping: bad address 'my-web'
/ # wget 172.19.159.7:8080
Connecting to 172.19.159.7:8080 (172.19.159.7:8080)
saving to 'index.html'
index.html           100% |********************************|     5  0:00:00 ETA
'index.html' saved

从上面的两次访问发现无法通过服务名来访问,只能通过集群的路由网络来访问,如果需要用服务名称来访问,这就需要自定义overlay网络
docker network create -d overlay my-overlay
删掉基于默认网络ingress创建的服务
docker service create --network my-overlay -p 8080:80 --name nginx nginx
docker service create --network my-overlay --name alpine alpine ping www.baidu.com
docker service ls

ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
lu64wdu42qky        alpine              replicated          1/1                 alpine:latest       
crbzopjh0emn        nginx               replicated          1/1                 nginx:latest        *:8080->80/tcp

进alpine容器
docker exec -it alpine.1.quumzg6fgrkkbqy6e0d1679ni sh
ping nginx可以通