Docker 容器数据 持久化(系统学习Docker05)
写在前面
本来是可以将数据存储在 容器内部 的。但是存在容器内部,一旦容器被删除掉或者容器毁坏(我亲身经历的痛,当时我们的大数据平台就是运行在docker容器内,有次停电后,不管怎样容器都起不来。以前的同事也没有将数据映射到外面 。搞得最后我们重新导的数据,痛的领悟啊~~)。
再就是如果不将数据映射出来 ,比如要想使用容器内部的web日志,也是比较难搞,反正不就是其它容器/服务不是很方便。
大体上来说,一般只要使用Docker都会将 重要的数据 进行持久化。
本文有任何问题,欢迎留言指正~
Docker 持久化存储技术
默认仅在Container Layer(层) 保存的文件数据,删除容器就没有了
Data Volume(卷):数据卷,数据挂载相关,外挂一个存储
这个外挂的存储 ,即:Volume 有三种类型:
Volume 卷的三种类型:
Volume
Docker 自己管理的 Data Volume ,由docker后台自动创建,我们不要去 手动 更改映射出来的文件内容。挂载点 存于主机文件系统中的某个区域docker area(linux 一般是存储在 /var/lib/docker/volumes/ 目录下)。这种持久化方式是很推荐的*****。
Bind Mounting
将当前主机目录 与 指定的容器内部目录进行绑定 --> 实现数据共享我们在开发的时候比较推荐这种方式,实现数据共享
Docker的 数据共享 技术 能极大提高开发人员的开发效率
配合chrome插件super auto refresh plus,边写代码,边看运行结果。相当舒服~。
tmpfs mount(Linux中):存于内存中(注意,并不是持久化到磁盘)。在容器的生命周期中,它能被容器用来存放非持久化的状态或敏感信息
上图 卷的三种类型,后文主要根据代码来讲解这几种类型
Volume 相关的常用命令:
列出所有卷:docker volume ls
删除某个卷:docker volume rm 卷名
删除所有未使用的卷:docker volume prune # 慎用
创建:docker volume create
查看某个卷的元信息:docker volume inspect 卷名
容器数据 持久化 实操
类型一:Volume
如果没有显式创建卷,一个卷会在最开始 挂载<VOLUME["/var/lib/mysql"] > 时被创建。当容器停止时,卷仍然存在。多个容器可以通过read-write或read-only的方式使用同一个卷。只有在显式删除时,卷才会被删除。
查看官方mysql Dockerfile 中定义的持久化存储方式: https://github.com/docker-library/mysql/blob/6952c5d5a9889311157362c528d65dc2e37ff660/5.7/Dockerfile 发现是通过 VOLUME["/var/lib/mysql"] 这样的方式将数据持久化到本地的 意思是指,需要将容器内部/var/lib/mysql 目录下的数据 映射出去 不指定其实是不会将数据映射出来的。 映射出来的位置是在/var/lib/docker/volumes/ ,他会自己在该目录下生成一个volume ID 实际的数据就是保存在其中的。 代码验证上面这段话: docker volume ls docker run -d --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.7 [ ~]# docker ps cef34ac36e63 mysql:5.7 "docker-entrypoint.s…" 16 seconds ago Up 15 seconds 3306/tcp, 33060/tcp mysql1 [ ~]# docker exec -it mysql1 bash mysql -u root create database test1; quit exit 回到本地主机: docker volume ls docker volume inspect [volume ID] 详细信息中可以看见挂载点 cd 进去,可以看见实际的数据库文件是真实存在的。 /var/lib/docker/volumes/1b7400bf5cca58f06957e865ab7c072b4cd5961c56d536357fb69575985ecbac/_data [ _data]# ls auto.cnf client-cert.pem ibdata1 ibtmp1 private_key.pem server-key.pem ca-key.pem client-key.pem ib_logfile0 mysql public_key.pem sys ca.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem test1 [ _data]# 其实这个时候你把容器停止,删除容器。数据库的文件还是会在本地保留的 # 强制删除运行中的容器 docker rm -f mysql1 # 删除volume docker volume rm VOLUME NAME 【升级1】 上面的方式有一个不好的地方就是:由于没有指定映射的对应目录,自动为我们生成了一个很长的Volume ID, 这个其实是不太好管理的。最好的方式是,我们自己指定名称。 具体如下: 通过-v 指定映射 docker run -d -v mysql:/var/lib/mysql --name mysql2 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.7 [ ~]# docker volume ls DRIVER VOLUME NAME local mysql [ ~]# 发现是我们自己指定的名称mysql 【升级2】 上面的还有一个不好的一点 就是不太方便移植映射出来, 我们如果可以将映射出来的目录指定到 Dockerfile 同一级目录下就更好了, 要想实现这个 可以通过编写 docker-compose.yml 文件,在文件中定义volume
volume这种方式可以很好的将数据持久化的本地文件系统中,【推荐】
类型二:Bind Mounting
将当前目录外部 与 指定的容器内部目录进行绑定 --> 实现数据共享
案例中 实现容器内部 /usr/share/nginx/html 与 本机主机 /root/docker-nginx
两个目录下的文件共享
案例:
[ ~]# mkdir docker-nginx [ ~]# cd docker-nginx/ [ docker-nginx]# vim Dockerfile FROM nginx:latest WORKDIR /usr/share/nginx/html COPY index.html index.html [ docker-nginx]# docker build -t liuge36docker/my-nginx . Sending build context to Docker daemon 3.072kB Step 1/3 : FROM nginx:latest ---> 2073e0bcb60e Step 2/3 : WORKDIR /usr/share/nginx/html ---> Running in 8bdefed78445 Removing intermediate container 8bdefed78445 ---> 747647be78f1 Step 3/3 : COPY index.html index.html ---> b6a5afe9dcf8 Successfully built b6a5afe9dcf8 Successfully tagged liuge36docker/my-nginx:latest [ docker-nginx]# # 创建容器 将当前目录与 指定的容器内部目录进行绑定 [ docker-nginx]# docker rm -f web web [ docker-nginx]# docker run -d -v $(pwd):/usr/share/nginx/html -p 8777:80 --name web liuge36docker/my-nginx 4822d9626b36c2b539527a9ba8d9cdebfaee19762b02f957559e4f2ae6e2d281 [ docker-nginx]# docker exec -it web /bin/bash :/usr/share/nginx/html# ls Dockerfile index.html :/usr/share/nginx/html# touch hello.txt :/usr/share/nginx/html# exit exit [ docker-nginx]# ls Dockerfile hello.txt index.html [ docker-nginx]# echo "1111" >> hello.txt [ docker-nginx]# docker exec -it web /bin/bash :/usr/share/nginx/html# cat hello.txt 1111 :/usr/share/nginx/html#
后面我可能会根据 SpringBoot 单独写一篇文章 ,看看到底这个代码共享 该怎么去做。
本文比较基础,后面我再写一下关于 容错、 备份、恢复、迁移数据卷 相关的东西。
尽情期待~
有什么问题,欢迎留言讨论~~
更多文章:系统学习Docker 不迷路:https://blog.csdn.net/liuge36/category_7651616.html