在这一讲,我们会学习如何用Docker persist data (翻译为持久化数据?) 。 有时候感觉如果持久化这个翻译没有很好做到本土化,第一次听的人会感觉一头雾水。那解释成学习如何保证Docker 不会丢失数据如何? 😉
为什么我们需要Docker volumes?
依然,我们先抛出一个问题。无论何时,我们创建一个Docker 容器,容器都会包含两层,第一层是image layer (Read-only layer),我们到目前为止还不能对这层进行修改。所有的修改都会发生在第二层,也就是container layer (Writable layer)。当我们删除容器的时候,会发生什么呢? 容器内的所有的资源都会被删除。同样的当我们删除image的时候,所有在image中的数据也会全部丢失。比如我们在一个容器里有一个数据库服务,如果我们删除了容器,那数据库的记录就可能也被全部删除。所以我们能做什么呢?方案如下图所示:
解决方案是,我们不在容器中保存数据,而是把它写入volumes里,volumes位于Docker Host里但container之外,因此删除container和image并不会删除volumes里的数据。
让我们开始实践下
首先我们进入Docker的目录:
cd /var/lib/docker
输入下列命令,查看目录下的文件和子目录:
sudo ls -lrt
如果我们用的操作系统不同或者版本,命令可能会有所差异。
输出如下:
drwx------ 4 root root 4096 Aug 2 00:03 plugins
drwx------ 3 root root 4096 Aug 2 00:03 image
drwx------ 2 root root 4096 Aug 2 00:03 trust
drwxr-x--- 3 root root 4096 Aug 2 00:03 network
drwx------ 2 root root 4096 Aug 2 00:03 swarm
drwx--x--x 4 root root 4096 Aug 2 00:03 buildkit
drwx------ 2 root root 4096 Aug 7 08:27 runtimes
drwx-----x 3 root root 4096 Aug 7 08:27 volumes
drwx------ 2 root root 4096 Aug 7 09:07 tmp
drwx-----x 27 root root 28672 Aug 7 09:50 overlay2
drwx-----x 4 root root 12288 Aug 7 09:50 containers
在输出信息里,我们会找到一个volumes的目录,当我们和容器交换数据的时候,容器都会在这个目录下创建对应的文件。
接下来我们跳转到这个volumes目录里:
cd volumes
当前里面可能已经有一些文件了,但是没有关系。
创建我们自己的卷
执行下列命令
docker volume create data_volume
然后你会现在volumes目录下多出了一个data_volume子目录,我们接着跳转到这个子目录:
cd data_volume
看看里面有什么:
sudo ls -lrt
输出:
drwxr-xr-x 2 root root 4096 Aug 7 11:22 _data
噢,里面还有一个文件夹,接着跳到里面去:
cd _data
然后这应该是个空目录
让我们将容器内的一个目录与volume做一个映射
输入下列命令
docker run -itd -v data_volume:/www ubuntu
该命令会创建一个容器,并且在该容器里创建一个叫做www的目录,该目录会和我们的卷data_volume进行一个映射
让我们通过查看容器列表验证容器已经被创建
docker ps
输出应该类似于下列信息:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0c7ef3b182b8 ubuntu "bash" 2 minutes ago Up 2 minutes cool_kilby
也许我们的COMMAND的值不一样,但没有关系
与容器进行连接
docker exec -it [容器ID] [COMMAND]
如:
docker exec -it 0c bash
在交互模式里
我们查看下是否存在www这个目录
ls -lrt
应该是有的,如果没有,应该是Docker版本更新了,谢谢你回来考古我这篇博文;)
接下里跳转到该目录下
cd www/
创建一个文件
echo "Test Data" > test.txt
验证下www目录下是否多了个test.txt文件:
ls
好的,让我们推出交互模式,输入:
exit
接下来我们要验证volumes可以帮助我们实现持久化
停止我们创建的这个容器
docker stop [容器ID]
删除我们创建的这个容器
docker rm [容器ID]
在我们的volume目录下查看:
请确保你的路径在:
/var/lib/docker/volumes/data_volume/_data
在上述路径下输入下列命令:
ls
输出应该是:
test.txt
我们再运行一次卷映射到容器的命令
docker run -itd -v data_volume:/www ubuntu
查看新创建的容器
docker ps
连接到这个容器
docker exec -it [容器ID] [COMMAND]
你可以在这个容器的www目录下找到我们在上一个容器里创建的test.txt
总结
在这一讲里我们一起学习了如何创建我们自己的卷,然后在创建容器时,将容器的一个文件夹映射到我们的卷里,并验证了volumes用于持久化的有效性。我们这讲的过程实际上在英文语境里被称为volume mount。在下一讲同时也是这个系列的最后一讲里,我们将会讨论bind mount。谢谢跟到这里。