【Docker 系列】docker 学习 五,容器数据卷

什么是容器数据卷 思考一个问题,我们为什么要使用 Docker?
主要是为了可以将应用和环境进行打包成镜像,一键部署。
再思考一个问题,容器之间是相互隔离的,如果我们在容器中部署类似 mysql 这样的组件,如果把该容器删除掉,那么 mysql 的数据也会被删掉了,数据丢失了,咱们删库跑路真刺激
事实上,我们可不能让这么有风险的事情存在,因此有了卷技术
卷技术是容器之间可以共享数据的技术,Docker 容器中产生数据,将数据同步到本地
例如咱们将 Docker mysql 容器中的 /usr/mysql 目录挂载到宿主机的/home/mysql 目录
【Docker 系列】docker 学习 五,容器数据卷
文章图片

使用卷技术,我们就可以让数据得以持久化
实际上操作起来就是挂载目录,将 Docker 容器里面的目录,挂载到宿主机上的某个目录,这就可以将数据持久化和同步了, Docker 容器间的数据共享仍然是这样做的
咱们如何使用数据卷? 启动容器的时候,直接使用 -v命令就可以进行数据卷的挂载

docker run -it -v 宿主机目录:容器目录 镜像名

我们来尝试启动一个 nginx,并将宿主机的 /home/test 目录和 nginx 的 /home 目录挂载起来
#docker run -d -v /home/test:/home nginx

此时我们在宿主机的 /home/test 目录下建一个 test.txt 并且写入一些字符串,再查看容器的 /home 目录 是否有 test.txt
# 宿主机 root@iZuf66y3tuzn4wp3h02t7pZ:/home/test# echo xiaomotong >> test.txt# 容器 root@c8405d03a9a1:/home# ls test.txtroot@c8405d03a9a1:/home# cat test.txt xiaomotong

我们在容器的/home 目录下创建一个test2.txt 文件,同样写入一些字符串,再查看 宿主机的 /home/test 目录是否有 test2.txt
# 容器 root@c8405d03a9a1:/home# echo xiaozhu >> test2.txt# 宿主机 root@iZuf66y3tuzn4wp3h02t7pZ:/home/test# ls test2.txttest.txtroot@iZuf66y3tuzn4wp3h02t7pZ:/home/test# cat test2.txt xiaozhu

查看上述效果,果然是挂载 ok,数据确实同步了,哪怕是我们把 docker 容器删除掉,数据也不会丢失
【【Docker 系列】docker 学习 五,容器数据卷】docker inspect 容器ID ,查看一下我们创建的容器的挂载情况
# docker ps CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES c8405d03a9a1nginx"/docker-entrypoint.…"9 minutes agoUp 9 minutes80/tcpnginx2# docker inspect c8405d03a9a1[ ... "Mounts": [ { "Type": "bind", "Source": "/home/test", "Destination": "/home", "Mode": "", "RW": true, "Propagation": "rprivate" } ], ... ]

使用容器数据卷的便利之处:
以后我们只需要修改宿主机里面的目录和文件,即可和容器中的指定目录保持同步
mysql 实战一波
咱们再来一个实战,我们一起来看看数据卷如何使用
下载 5.7 版本的 mysql docker 镜像,也可以下载其他版本,这个没有关系
# docker pull mysql:5.7 5.7: Pulling from library/mysql# 5.7版本 33847f680f63: Already exists# 本层级已经之前已经下载过了 5cb67864e624: Pull complete 1a2b594783f5: Pull complete b30e406dd925: Pull complete 48901e306e4c: Pull complete 603d2b7147fd: Pull complete 802aa684c1c4: Pull complete 5b5a19178915: Pull complete f9ce7411c6e4: Pull complete f51f6977d9b2: Pull complete aeb6b16ce012: Pull complete Digest: sha256:be70d18aedc37927293e7947c8de41ae6490ecd4c79df1db40d1b5b5af7d9596 Status: Downloaded newer image for mysql:5.7 docker.io/library/mysql:5.7# 真实的mysql 镜像地址

启动镜像,直接使用 -v 来挂载目录
使用方式
docker run -it -v 主机目录:容器的目录

开始启动镜像
咱们可以参考 dockerhub 上的文档
【Docker 系列】docker 学习 五,容器数据卷
文章图片

【Docker 系列】docker 学习 五,容器数据卷
文章图片

# docker run-d -p 8888:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql1 mysql:5.7 23c31b285804cd95130e36ad40d3c07239fe744845ca464b9c80e42c84848bfb# 解释一下上述命令 -d 后台运行 -p 宿主机端口:容器端口端口映射 -v 宿主机目录:容器目录挂载卷 -e 设置环境变量 --name 设置启动容器的名字

咱们可以通过window 的 workbench 来远程连接一下 mysql
我的是云服务器,因此输入云服务器的地址,端口填入 8888 端口
默认用户名是 root , 密码是 123456
【Docker 系列】docker 学习 五,容器数据卷
文章图片

测试连接 ok ,我们可以来进入数据库
【Docker 系列】docker 学习 五,容器数据卷
文章图片

咱们在 workbench 中新建一个数据库
看看这个数据库是否会在我们的宿主机上面有同步
【Docker 系列】docker 学习 五,容器数据卷
文章图片

查看我们挂载宿主机的目录 /home/mysql/data
root@iZuf66y3tuzn4wp3h02t7pZ:/home/mysql/data#ls auto.cnfca.pemclient-key.pemibdata1ib_logfile1mysqlprivate_key.pemserver-cert.pemsys ca-key.pemclient-cert.pemib_buffer_poolib_logfile0ibtmp1performance_schemapublic_key.pemserver-key.pemtest

【Docker 系列】docker 学习 五,容器数据卷
文章图片

果然是有的,再次 nice,这就达到了数据持久化的效果,这就是咱们从认识数据卷到使用数据卷的一个简单流程,咱们可以慢慢的深入下去
具名挂载和匿名挂载 以启动一个 nginx 为例子:
具名挂载:
# docker run -d--name nginx3 -v JM:/etc/nginx:rw nginx

匿名挂载:
# docker run -d--name nginx3 -v /etc/nginx:rw nginx

上述的 rw也可以写成ro
  • rw
可读可写
  • ro
只读,只能宿主机才能写
查看数据挂载卷
root@iZuf66y3tuzn4wp3h02t7pZ:/home/mysql# docker volume ls DRIVERVOLUME NAME localJM# 具名挂载 ,下面的为匿名挂载 localbd2b9ea00eb7d95bb69bdd39a63769ce906a0bb17fae2e29b726f9b92cbcb008 locald67ba49109dfd654173b8d05f8602b99751066483a357c654b63ba46ec72d5c0

查看挂载具体目录
l# docker volume inspect JM [ { "CreatedAt": "2021-08-04T23:48:05+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/JM/_data", "Name": "JM", "Options": null, "Scope": "local" } ]

查看该目录下的挂载文件,是否是和 nginx 容器中的 /etc/nginx目录下内容一致
root@iZuf66y3tuzn4wp3h02t7pZ:/var/lib/docker/volumes/JM/_data# ll total 36 drwxr-xr-x 3 root root 4096 Aug4 23:48 ./ drwx-----x 3 root root 4096 Aug4 23:48 ../ drwxr-xr-x 2 root root 4096 Aug4 23:48 conf.d/ -rw-r--r-- 1 root root 1007 Jul6 22:59 fastcgi_params -rw-r--r-- 1 root root 5290 Jul6 22:59 mime.types lrwxrwxrwx 1 root root22 Jul6 23:11 modules -> /usr/lib/nginx/modules -rw-r--r-- 1 root root648 Jul6 23:11 nginx.conf -rw-r--r-- 1 root root636 Jul6 22:59 scgi_params -rw-r--r-- 1 root root664 Jul6 22:59 uwsgi_params

果然一毛一样,nice
再来看看 docker 默认的挂载目录 /var/lib/docker/volumes,我们可以看到每一个匿名挂载,和具名挂载的目录和数据都存放于此
root@iZuf66y3tuzn4wp3h02t7pZ:/var/lib/docker/volumes# ll total 44 drwx-----x5 root root4096 Aug4 23:48 ./ drwx--x--x 13 root root4096 Aug3 22:58 ../ brw-------1 root root 252, 1 Aug3 22:58 backingFsBlockDev drwx-----x3 root root4096 Aug1 21:36 bd2b9ea00eb7d95bb69bdd39a63769ce906a0bb17fae2e29b726f9b92cbcb008/ drwx-----x3 root root4096 Aug3 23:32 d67ba49109dfd654173b8d05f8602b99751066483a357c654b63ba46ec72d5c0/ drwx-----x3 root root4096 Aug4 23:48 JM/ -rw-------1 root root32768 Aug4 23:48 metadata.db

我们来小结一下
  • 指定挂载
-v 宿主机的绝对路径:容器路径
  • 具名挂载
-v 卷名:容器路径
  • 匿名挂载
-v 容器路径
参考资料:
docker docs
欢迎点赞,关注,收藏 朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力
【Docker 系列】docker 学习 五,容器数据卷
文章图片

好了,本次就到这里
技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。
我是小魔童哪吒,欢迎点赞关注收藏,下次见~

    推荐阅读