11. Docker Swarm(二)

1、前言

上一篇中我们利用Docker Swarm搭建了基础的集群环境。那么今天我们就来验证以下该集群的可用性。上一篇的示例中,我创建了3个实例副本,并且通过访问http://192.168.74.132:8080得到我们的页面。

2、验证高可用

1)我们可以通过以下命令查看当前应用的节点信息:

docker service ps swarm_demo

可以看出在IP为132,133,134上各启动了一个容器来运行。

2)此时,我们将134上的节点容器关掉:

# 查看容器信息,拿到容器ID
docker ps

# 停止该容器
docker stop <容器ID>

3)停止完后,我们再到master节点上查看节点信息:

可以看到134节点上出现运行的容器宕机了,但是由于我们将节点的副本数量设置为3,所以Swarm集群自动的又重新启动了一个容器。通过当前状态可以看到启动的时间。

4)如果我们把134的docker容器整个停止掉:

5)我们再来查看master节点节点信息:

我们会发现3个节点副本中,有2个启动在了132的节点上。

而我们依然可以访问我们的应用:

3、热更新

Docker Swarm实现平滑升级,也就是不停机更新。

1)更新Dockerfile文件,版本号version改为2:

FROM nginx
RUN echo '<h1> My first Swarm demo, version: 2</h1>' > /usr/share/nginx/html/index.html

2)重新编译镜像:

docker build -t pengyaohuang/swarm_nginx_demo:2 .

3)上传Docker Hub:

docker login
docker push pengyaohuang/swarm_nginx_demo:2

4)更新之前Swarm部署的服务:

docker service update --image pengyaohuang/swarm_nginx_demo:2 swarm_demo

5)访问应用:

4、数据持久化

与单机环境一样,Docker Swarm集群中的容器也是无状态的服务。如果在Swarm集群行了MySQL 等有状态的服务,若没有将数据挂载到宿主机中,那么一旦容器被销毁,则意味着据会丢失。

Docker Swarm集群提供了两种方式解决数据持久化问题:

  1. volume模式:默认模式,将工作节点宿主机的目录同步到容器内。
  2. NFS模式:通过网络文件系统实现数据持久化。

4.1、volume挂载

这里的数据卷方式与docker容器下的数据卷完全一样。可以使用以下命令挂载数据卷:

docker service create -p 8080:80 --replicas 3 --name swarm_demo 
    --mount type=volume,src=myvolume,dst=/usr/share/nginx/html/ 
    pengyaohuang/swarm_nginx_demo:1

这里使用--mount进行挂载数据卷。这里将容器/usr/share/nginx/html/目录挂载到宿主机定义的myvolume目录下。

查看数据卷信息,可以使用:

docker volume ls

通过volume模式挂载的数据卷,可以实现容器与宿主机间的数据持久化,但是无法实现群中各个节点的数据共享。

4.2、NFS

为了解决volume无法在各个节点中共享数据的问题,Swarm 集群中更常用的一种方式是,使用NFS(网络文件系统来实现数据的共享与持久化。

NFS(网络文件系统)允许计算机之间通过TCP/IP 网络共享资源。在NFS应用中,NFS客户端可以透明地读写远端NFS 服务器上的文件,就像访问本地文件一样。

系统结构图如下:

其中,NFS可被看成是 NFS 的服务器端,而 Docker 节点(master 节点、node1 节点、node2 节点)则可以被看成是NFS的客户端。因此,整个系统是 Client-Server 结构。

为了方便进行测试,可以将 master 节点作为 NFS Server。但在实际的环境中,一般可以单独搭建一个节点作为NFS Server。

1)安装NFS:

yum install -y nfs-utils
systemctl start nfs

2)master节点中编辑/etc/exports文件:

# 输入以下配置信息
/nfs *(rw,sync,no_root_squash)

参数说明:

  • /nfs:NFS共享目录
  • *:所有网段可以访问主机网段
  • rw:可读写权限
  • sync:数据传输采用同步方式,async表示异步
  • no_root_squash:NFS共享目录属性

3)master节点上创建/nfs目录:

mkdir /nfs
# 重启nfs节点
systemctl restart nfs

4)Node1节点上启动NFS客户端:

systemctl start rpcbind

5)在Node1节点上挂载NFS目录:

# 创建node1节点的目录
mkdir /nfs-node1
# 将master节点的目录/nfs挂载到node1节点的nfs-node1上
mount -t nfs 192.168.74.132:/nfs /nfs-node1

6)测试,node1目录上新建一个文件:

Node1节点上:

master节点上:

可以看到文件已经进行了同步。

7)Swarm集群中创建服务:

docker service create --replicas 3 --name swarm_demo -p 8080:80 
    --mount 'type=volume,src=mynfsvol,dst=/usr/share/nginx/html,volume-driver=local,volume-nocopy=true,volume-opt=type=nfs,volume-opt=device=192.168.74.132:/nfs,"volume-opt=o=addr=192.168.74.132,vers=4,soft,timeo=180,bg,tcp,rw"' 
    pengyaohuang/swarm_nginx_demo:1

参数说明:

  • type=volume:数据存储类型
  • src=mynfsvol:数据卷名称
  • dst=/usr/share/nginx/html:挂载到容器中的目录
  • volume-opt=type=nfs:数据卷的类型
  • volume-opt=device=192.168.74.132:/nfs:挂载的 NFS 目录
  • volume-opt=o=addr=192.168.74.132: NFS 服务器的地址。

即可完成挂载。