简介
容器的持久存储有多个解决方案,本文针对的是运行在容器里的应用的持久存储。除了Docker自带的Volumes解决方案外,还有开源的解决方案(Flocker,Torus),也有商用的解决方案(Portworx)。本文提供了一个Docker Volumes和NFS结合起来的解决方案,并且介绍了具体的实施步骤。
这个方案的体系架构是Docker,NFS Mount和数据库相结合的综合产物。NFS和数据库可以运行在不同的服务器上。数据库不只是单机数据库,也可以是集群数据库。本文的实例是运行在一台8个内核16GB内存的Linux主机上的。其在主机上的容器如下:
Linux上的Docker NFS挂载
NFS(网络文件系统)是一个允许用户远程存储文件的协议,广泛应用于Linux操作系统中。NFS同时也是远程进行持久存储的一种方式。这里利用NFS和Docker的Volumes结合起来解决Docker容器的持久存储问题。
NFS不一定要安装在主机裸机上,也可以运行在容器里。Docker Hub上有了一个相当不错的NFS Docker镜像,可以把容器里的一个路径展示给主机,以便在主机的文件系统上形成一个挂载(mount):
https://hub.docker.com/r/mnagy/nfs-server/
本例使用如下命令启动NFS服务器容器:
- docker run -d --net=bridge --privileged --name nfs-server mnagy/nfs-server /exports/portworx
这里面“/exports/portworx” 是主机可以挂载的容器里的路径。
主机是利用如下的命令把容器里的路径“/exports/portworx”在主机上形成NFS挂载的:
- sudo mount 10.255.0.1:/exports/portworx /mnt2
NFS服务器的IP地址可以通过Docker命令来找到:
- docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' nfs-server
- 10.255.0.1
Redis在NFS挂载上的持久存储
谈到持久存储就需要持久存储的工具。数据库是很好的持久存储的工具。数据库类的应用有很多种,这里采用被广泛认可的Redis键值存储应用。
下面的链接是一个很好的Redis Docker镜像,我们可以用来快速运行一个容器来存储持久数据:
- https://hub.docker.com/_/redis/
当我们启动了Redis的持久存储功能,数据就会保存在Redis的一个叫Data的卷里。然后我们可以把Redis的这个卷映射到主机的/mnt2路径,这样就可以和NFS挂载机制联系起来:
- docker run --name redis-server-wma -v /mnt2:/data -d redis redis-server --appendonly yes
向Redis发送数据
为了完整的展示一个实例,我们要向Redis发送大量模拟数据。我们想看到的是数据最终落到NFS服务器上。我们将利用Shell脚码来向Redis发送数据。
首先,我们运行一个交互模式的Redis客户端容器:
- docker run --name redis-client --link redis-server-wma:redis -it alpine
然后, 我们运行如下的命令来发送数据:
- for i in `seq 10000000`; do redis-cli -h redis -p 6379 SET users:app "{id: '$i', name: 'name$i', address: 'address$i' }" ; done
之后我们可以登陆nfs-server:
- docker exec -it nfs-server /bin/bash
我们可以看到NFS服务器的export 路径填满了数据,并且数据不断增涨:
- [root@02040860a13d /]# ls -alh /exports/portworx/
- total 19M
- drwxrwxrwx 2 999 27 4.0K Nov 6 21:58 .
- drwxr-xr-x 3 root root 4.0K Nov 6 10:41 ..
- -rw-r--r-- 1 999 input 19M Nov 6 22:17 appendonly.aof
这就验证了Docker Volumes和NFS相结合的解决方案是有效的。