目录
1.2.3 Docker提供三种方式将数据从宿主机挂载到容器
一、Docker数据持久化概述
1.1联合文件系统
了解联合文件系统后,我们知道,镜像是只读的,类似共享文件形式让多个容器使用。如果要在容器里修改文件,即镜像里的文件,那该如何修改?
为了解决这个问题,docker 引入了 写时复制(copy-on-write),需要修改文件操作时,会先从镜像里把要写的文件复制到自己的文件系统中进行修改。
默认情况下,Docker容器内部新创建文件或者修改文件,结果会保存在容器的可读写层中,因此:
(1)当container消失时,与container一体的可读写层也一并消失,数据并未持久化。当一个container需要其它container中可读写层的数据时,读取操作非常困难。
(2)container可读写层与宿主机的文件系统紧密结合,很难进行迁移。
(3)写入数据到container可读写层需要storage driver,与直接在宿主机文件系统中读写数据相比效率要低。
1.2容器的数据卷
1.2.1 什么是数据卷
数据卷是经过特殊设计的目录,可以绕过联合文件系统(UFS),为一个或者多个容器提供访问,数据卷设计的目的,在于数据的永久存储,它完全独立于容器的生存周期,因此,docker 不会在容器删除时删除其挂载的数据卷,也不会存在类似的垃圾收集机制,对容器引用的数据卷进行处理,同一个数据卷可以只支持多个容器的访问。
1.2.2 数据卷特点
- 数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,这些数据会被拷贝到新初始化的数据卷中
- 数据卷可以在容器之间共享和重用
- 可以对数据卷里的内容直接进行修改
- 数据卷的变化不会影像镜像的更新
- 卷会一直存在,即使挂载数据卷的容器已经被删除
1.2.3 Docker提供三种方式将数据从宿主机挂载到容器
- Volumes: Docker 管理宿主机文件系统的一部分(/var/lib/docker/volumes)。保存数据的最佳方式。
- Bind mounts: 将宿主机的任意位置的文件或者目录挂载到容器中。
- tmpfs:挂载存储在主机系统的内存中,而不会写入主机的文件系统。如果不希望将数据持久存储在任何位置,可以使用tmps,同时避免写入容器可写层提高性能。
二、 Docker持久化方案
2.1 查看volume 基本命令使用方法
2.2 volume持久化方案
2.2.1volume简介
volume是Docker官方推荐的持久化方案,默认情况下,volume的存储空间来自于宿主机文件系统中的某个目录,如/var/lib/docker/volumes/,docker系统外的程序无权限修改其中的数据。
一个volume可以同时供多个container使用,如果没有container使用volume,其不会自动删除,用户需运行docker volume prune明确删除。
如果用户显式创建volume,则需要给其指定一个名称;如果是隐式创建volume,Docker会自动为其分配一个在宿主机范围内唯一的名字。
2.2.2.volume特点
docker volume create -v 创建 volume 时,宿主机目录路径必须以/或~/开头,否则 Docker 会将其当成volume 而不是bind mount。
如果容器中的目录不存在,docker会自动创建目录;如果容器中的目录已有内容,docker会使用宿主机上目录的内容覆盖容器目录的内容。
2.2.3 挂载指定volume
### 管理卷
docker volume create nginx-vol # docker volume ls
docker volume inspect nginx-vol
## 用卷创建一个容器
docker run -d --name=nginx-test -v nginx-vol:/usr/share/nginx/html nginx
## 清理
docker stop nginx-test # docker rm nginx-test
docker volume rm nginx-vol
## 注意:如果没有指定卷,自动创建。
创建数据卷,启动容器使用 nginx-vol 这个数据卷
[root@offline-client docker]# docker volume create nginx-vol
nginx-vol
[root@offline-client docker]# docker volume inspect nginx-vol
[
{
"CreatedAt": "2022-05-15T12:10:52+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/nginx-vol/_data",
"Name": "nginx-vol",
"Options": {},
"Scope": "local"
}
]
[root@offline-client ~]# docker run -d --name=nginx-test -v nginx-vol:/usr/share/nginx/html nginx:1.17Unable to find image 'nginx:1.17' locally
[root@offline-client ~]# curl 172.17.0.2
hello world
创建容器并挂载数据卷
2.2.4 volume使用场景
通过使用第三方提供的volume driver,用户可以将数据持久到远程主机或者云存储中。
(1)多个容器间共享数据。
(2)宿主机不保证存在固定目录结构。
(3)持久化数据到远程主机或者云存储而非本地。
(4)需要备份、迁移、合并数据时。停止container,将volume整体复制,用于备份、迁移、合并等
2.3 Bind Mounts持久化方案
bind mount持久化方式将宿主机中的文件、目录挂载到容器上,相应文件、目录可以被宿主机读写,也可以被容器读写。
bind mount持久化方式可以将数据存储在宿主机器任何地方,但会依赖宿主机的目录结构,因此不能通过docker CLI直接管理,并且非Docker进程和Docker进程都可以修改。
2.3.1 bind mount特点
(1)性能最好
(2)Docker容器与宿主机耦合过于紧密,移植性较差。
2.3.2 bind mount使用场景
(1)container共享宿主机配置文件,如docker将宿主机文件/etc/resov.conf文件bind mount到容器上,两者会使用相同的DNS服务器。
(2)开发环境中build容器化。开发过程中将build过程container化,将宿主机上源代码目录bind mount到build container中。修改代码后,运行build container的build命令,build container则将build结果写入另一个bind mount的目录中。
(3)监控服务container化。读取宿主机固定文件中的数据实现监控。
2.3.3 常用命令
#用卷创建一个容器:
docker run -d --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx
docker run -d --name=nginx-test -v /app/wwwroot:/usr/share/nginx/html nginx
# 验证绑定:
docker inspect nginx-test
# 清理:
docker stop nginx-test
docker rm nginx-test
启动 nginx-test容器,挂载/app/wwwroot到/usr/share/nginx/html
[root@offline-client ~]# docker run -d --name=nginx-test --mount type=bind,src=/app/wwwroot,dst=/usr/share/nginx/html nginx
13e5652a1b889d61021b9b726579646a00531fa2773068b1b7066ff60eff11f5
[root@offline-client ~]#
[root@offline-client ~]#
[root@offline-client ~]#
[root@offline-client ~]# ll /app/wwwroot/
total 0
[root@offline-client ~]# echo hello world > /app/wwwroot/index.html
[root@offline-client ~]# curl 172.17.0.2
hello world
将 根路径下wwwNginx路径mount到/usr/share/nginx/html,并输入 内容 ,然后访问
2.3.4 bind mount注意事项
(1)-v 宿主机目录路径必须以/或~/开头,否则docker会将其当成是volume 而不是bind mount。
(2)如果宿主机上的目录不存在,docker会自动创建目录(多级的绝对路径好像不行)。
(3)如果容器中的目录不存在,docker会自动创建目录。
(4)如果容器中目录已有内容,那么docker会使用宿主机上目录的内容覆盖容器目录的内容。
2.4 tmpfs mount持久化方案
2.4.1 tmpfs mount
tmpfs mount只在Linux主机内存中持久化,是临时性的。当容器停止,tmpfs mount会被移除,通常用于临时存放敏感文件。
tmpfs mounts 可选选项
Option |
Description |
tmpfs-size |
挂载的tmpfs的字节数,默认不受限制 |
tmpfs-mode |
tmpfs的文件模式,例如700或1700.默认值为1777,这意味着任何用户都有写入权限 |
使用--tmpfs参数无法指定任何其他的可选项,并且不能用于Swarm Service(集群节点服务)。
docker run -d -it --name tmptest --tmpfs /test busybox
2.4.2 tmpfs mount特点
(1)只能在Linux主机内存中,不会持久化到磁盘。
(2)不支持多容器间共享。
2.4.3 tmpfs mount使用场景
Docker可将用户名与密码等敏感数据保存在某个数据库中,当启动需要访问这些敏感数据的container或者service时,docker会在宿主机上创建一个tmpfs,然后将敏感数据从数据库读出写到tmpfs中,再将tmpfs mount到container中,安样能保证数据安全。当容器停止运行时,则相应的tmpfs也从系统中删除。
参考原文链接:Hello Docker(七)——Docker数据持久化_docker持久化目录_天山老妖的博客-CSDN博客