Docker 容器数据:持久化
Docker 容器数据:持久化
每当从镜像创建容器时,它都会创建一个新容器,除了镜像数据之外没有任何数据
- 意味着如果在提交更改之前删除容器,我们将丢失数据
- Docker 应该存在一种将数据的文件系统与容器的文件系统分开的技术
- 每当创建容器时,也会创建一个文件系统【这是默认的 Linux 文件系统】
- 尽管 Docker 共享操作系统的内核,但文件系统之间存在分离,不然 Docker 就失去了环境隔离的意义
在 Docker 中我们可以创建卷,并且可以挂载到容器的文件系统中
挂载
让我们来看一个简单的挂载:使用主机文件系统并使用带有运行命令的 -v
标志将其挂载到容器上
-
语法
docker run -it -v <local-path>:<container-path>[:<flag>] <image>
- flag 是可选的,比如使用
ro
标志可以实现只读效果
- flag 是可选的,比如使用
-
我们使用镜像
python:3.6
#### 先在本地主机中创建一个用于挂载的目录,提示 pwd 可以显示当前路径,添加目录使用 mkdir #### learn@debian10:~$ pwd /home/learn learn@debian10:~$ mkdir test learn@debian10:~$ ls apt-sources.sh learn.code-workspace packages.microsoft.gpg test work #### 创建挂载本地主机文件系统的容器 #### # 本地主机的 /home/learn/test 目录挂载到 容器的 /root/work 目录 docker run -it -v /home/learn/test:/root/work python:3.6 #### 结果:我们创建挂载的容器,并进入容器 python 的交互模式 #### Python 3.6.15 (default, Dec 21 2021, 12:03:22) [GCC 10.2.1 20210110] on linux Type "help", "copyright", "credits" or "license" for more information. >>> # 判断容器中是否有 /root/work 目录 >>> import os >>> os.path.isdir(r'/root/work') True # 在 /root/work 目录,创建一个 test.txt 文件,写入 'test volume\n' 并退出容器 >>> with open(r'/root/work/test.txt', 'w', encoding='utf-8') as f: ... f.write('test volume\n') ... 11 >>> exit()
我们已经退出容器,容器也停止
# 查看 /home/learn/test 目录变化 learn@debian10:~$ ls /home/learn/test test.txt learn@debian10:~$ cat /home/learn/test/test.txt test volume
- 在容器中
/root/work
目录创建的 test.txt 以及其中数据被持久化在/home/learn/test
- 通过这种方式可以使容器中的数据得到保存,并且
/home/learn/test
挂载到不同容器中可以实现不同容器的数据共享 - 毕竟 Docker 是对应用级的虚拟化,如果没有共享数据的方法,会导致大量重复数据,至于通信那是另一回事【通过端口映射可以实现不一定是挂载】,所有重复数据是主要问题【通过这种共享解决】
- 挂载有一些限制,并且依赖于主机的文件系统,如果那个目录被删除,你能猜到后果 😏
Volumes
接下来我们聊一聊 Volumes,上面我们知道主机文件系统绑定挂载存在的限制
- Volumes 卷是 Docker 空间中创建的,这提供了对 Docker CLI 的更多控制
- Docker Volumes 功能很明确:主要用于在不同容器内共享数据,而不是与主机和容器共享数据
- 它的相关操作主要是通过 docker 的
volume
子命令
创建 volume 语法 docker volume create [<volume-name>]
其中卷名称是可选的,如果未指定会随机生成一个唯一 ID,最好指定方便记忆【指明含义,否则别起】
- 在创建 Docker 卷后通过
docker volume inspect <volume-name>
可以查看卷的信息
learn@debian10:~$ docker volume create test-volume test-volume learn@debian10:~$ docker volume inspect test-volume [ { "CreatedAt": "2023-04-05T15:35:45+08:00", "Driver": "local", "Labels": null, "Mountpoint": "/var/lib/docker/volumes/test-volume/_data", "Name": "test-volume", "Options": null, "Scope": "local" } ]
使用 test-volume
卷运行容器,语法:docker run -it -v <volume-name>:<container-path>[:<flag>] <image>
- 创造一个负责数据写入的容器:将 test-volume 卷挂载到 /root/w 目录
learn@debian10:~$ docker run -it --name "write-container" -v test-volume:/root/w python:3.6 Python 3.6.15 (default, Dec 21 2021, 12:03:22) [GCC 10.2.1 20210110] on linux Type "help", "copyright", "credits" or "license" for more information. >>> with open(r'/root/w/test.txt', 'w', encoding='utf-8') as f: ... f.write('test volume') ... 11 >>> exit()
- 创造一个负责只读的容器:将 test-volume 卷挂载到 /root/r 目录
# 这里判断方法比较粗浅,建议可以尝试读取 /root/r/test.txt learn@debian10:~$ docker run -it --name "read-container" -v test-volume:/root/r:ro python:3.6 Python 3.6.15 (default, Dec 21 2021, 12:03:22) [GCC 10.2.1 20210110] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import os >>> os.path.exists(r'/root/r/test.txt') True >>> exit()
- 说明一下:
--name
项目是为容器命名,属于可选
对卷的管理:
docker volume ls
查看所有卷docker volume rm <volume-name>
删除卷
其实最重要的命令是 docker volume --help
😋
实际上还有种挂载形式 tmpfs
- 这种方式具有临时性,因为保留在主机内存中,具体内容不大懂,推荐官方 https://docs.docker.com/storage/tmpfs/
- 主要是应用于临时存储主机或容器可写层中的敏感文件,而且这种方法是不支持共享以及只有 Linux 上可以用
想了解更深,希望有知道的提点一下
mount 选项
这个选项基本统合了上面三种方式,而且这种方式在阅读上更严谨
-
简单语法是
docker --mount 'type=[volume|bind|tmpfs], [src=<local-path|volume-name>] target=<container-path>', [volume-opt=<key=value>], [readonly|ro], ...
-
type 挂载类型在 volume、bind、tmpfs 中选
-
src 路径或卷【type=tmpfs 可以不指定】
-
target 挂载在容器中的路径
-
volume-opt 选项列表功能比较复杂,可选的
-
readonly 或 ro 可读属性,可选
-
...
表示的是其他属性,建议去官网查看,或者使用 help
使用 docker inspect <container-name|container-id>
可以查看容器挂载内容,这个只是简单说明,毕竟不熟悉在后面学习再细化
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了