Docker学习笔记分享之容器数据管理:

前沿导入:

在默认情况下,容器内创建的所有文件都存储在可写容器层上。这样做的问题有:

**1.**当该容器不再存在时,数据将不会持久保存,如果另一个进程需要它,则可能很难从容器中取出数据。

**2.**容器的可写层与运行容器的主机紧密耦合,不能轻易地将数据移动到其他地方。

**3.**写入容器的可写层需要存储驱动程序来管理文件系统,性能比直接写入主机要低。

Docker 为容器提供了两个选项来将文件存储在主机中,以便即使容器停止后文件也可以持久存储,分为数据卷数据卷容器

1.数据卷 : 容器内数据直接映射到本地主机环境

2.数据卷容器 : 使用特定容器维护数据卷,也成为bind mounts**(绑定挂载)

如果在 Linux 上运行 Docker,则还可以使用 tmpfs 挂载。如果在 Windows 上运行 Docker,则还可以使用命名管道。
在这里插入图片描述

volume , bindtmpfs 三者的相同点和区别:

相同之处

  • 无论选择使用哪种类型去使用,数据在容器内看起来都是相同的。它被视为容器文件系统中的目录或单个文件。

不同之处:

  • 卷(volume)存储在由 Docker 管理的主机文件系统中(/var/lib/docker/volumes/),非Docker进程不应该修改这部分文件系统。卷是在Docker 中保留数据的最佳方式。
  • 绑定挂载(bind mount) 也就是把主机的本地目录挂载到容器中某个挂载点,可以存储在主机系统的任何位置。他们甚至可能是重要的系统文件或目录。Docker主机或Docker容器上的非Docker进程可以随时修改它们。
  • 3.tmpfs挂载(tmpfs mount)仅存储在主机系统的内存中,而不会写入主机系统的文件系统。
1.数据管理命令

使用 docker volume 命令,语法如下:

[root@localhost _data]# docker volume --help
Usage:  docker volume COMMAND

Manage volumes

Commands:
  create      Create a volume		# 创建一个数据卷
  inspect     Display detailed information on one or more volumes	#查看数据卷详细信息
  ls          List volumes		# 列出所有数据卷
  prune       Remove unused local volumes	# 删除悬空数据卷
  rm          Remove one or more volumes	# 删除数据卷

Run 'docker volume COMMAND --help' for more information on a command.
2.数据卷操作

学习案例:通过 MySQL 的数据挂载来演示如何使用数据卷;

首先创建一个数据卷 :myvlo;

#创建数据卷
[root@localhost ~]# docker  volume create myvol
myvol
#验证数据卷是否创建成功
[root@localhost ~]# docker volume ls
DRIVER    VOLUME NAME
local     57d4eea585871cf861a549eafd7fc213b09e7151ebc431f297f74200482e9e04
local     357c2bba60db4d6097ebf5a30b17120b08d434f20c35f64952b3582ba66e24d4
local     myvol

查看卷的详细信息,然后使用数据卷;

[root@localhost ~]# docker volume inspect myvol
[
    {
        "CreatedAt": "2026-01-27T19:06:40+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/data/docker/volumes/myvol/_data",
        "Name": "myvol",
        "Options": null,
        "Scope": "local"
    }
]
#使用数据卷,创建了一个名为nginx的容器
[root@localhost ~]#  docker run --name nginx -d -p 80:80 -v myvol:/usr/share/nginx/html nginx:1.28.1 
a52b4b3bdb6a98855b28f0dbd3f613a4c06887c38007b7ec163ed556bb833821
[root@localhost ~]# docker inspect nginx
...
        "Mounts": [
            {
                "Type": "volume",
                "Name": "myvol",
                "Source": "/data/docker/volumes/myvol/_data",
                "Destination": "/usr/share/nginx/html",
                "Driver": "local",
                "Mode": "z",
                "RW": true,
                "Propagation": ""
            }
        ],
...

进行数据验证;

# 1. 修改 /data/docker/volumes/myvol/_data/index.html 文件
[root@localhost ~]# cd /data/docker/volumes/myvol/_data
[root@localhost _data]# ls
50x.html  index.html
[root@localhost _data]# echo 1111 > index.html
[root@localhost _data]# cat index.html
1111
#进入容器,查看文件内容
[root@localhost _data]# docker exec -it nginx bash
root@a52b4b3bdb6a:/# cd /usr/share/nginx/html/
root@a52b4b3bdb6a:/usr/share/nginx/html# ls
50x.html  index.html
root@a52b4b3bdb6a:/usr/share/nginx/html# cat index.html 
1111
# 3. 在容器内部修改index.html文件
root@a52b4b3bdb6a:/usr/share/nginx/html# echo 2222 > index.html 
root@a52b4b3bdb6a:/usr/share/nginx/html# cat index.html
2222
# 4. 在宿主机中的目录查看文件内容
root@a52b4b3bdb6a:/usr/share/nginx/html#exit
exit
[root@localhost _data]# ls
50x.html  index.html
[root@localhost _data]# cat index.html 
2222

从上面的操作可以发现:我们已经把容器内部的数据共享到宿主机上了。

然后进行删除容器的操作;

[root@localhost ~]# docker stop nginx && docker rm nginx
nginx
nginx

重新创建一个新的容器,并将其挂载到之前的数据卷上,然后访问这个容器;

[root@localhost ~]# docker run --name nginx -d -p 80:80 -v myvol:/usr/share/nginx/html nginx:1.28.1 
af0a60b5bda2bad91e9ec9c0aaf576fc8991948fc78dc524e576b8f759b3eb0d
[root@localhost ~]# curl localhost
2222
[root@localhost ~]# 

可以发现:数据我们的数据卷没有删除,那么别的容器挂载到这个卷后,依然可以使用之前的数据。

如果要想删除数据卷,我们需要关闭关联的容器,然后才去删除数据卷;

[root@localhost ~]# docker stop nginx && docker rm nginx
nginx
nginx
[root@localhost ~]# docker volume rm myvol
myvol
3.数据卷容器操作

在宿主机上创建目录,并通过这个目录来作为卷创建一个容器;

[root@localhost ~]# mkdir /data/nginx
[root@localhost ~]# docker create -v /data/nginx:/data --name voldata nginx:1.28.1 
a5f9d79b58bb1909132da09d13df56c63743567c6c1ca0ad4ff40deb1d8a02d3
[root@localhost ~]# docker inspect voldata
......
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/data/nginx",
                "Destination": "/data",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
......

挂载数据卷,使用语法:--volume-from 卷容器名

[root@localhost ~]# docker run --name n1 --volumes-from voldata --rm -d nginx:1.28.1
57d838278668ce2871ae2146ed4d065b30b977e1b9dbd42cb2429935e7a0f999
[root@localhost ~]# docker run --name n2 --volumes-from voldata --rm -d nginx:1.28.1 
512c4a01e3efc9e4b7fe9c43443f5972b373eda165522809144b864619b13821

验证数据共享;

# 1. 进入n1容器
[root@localhost ~]# docker exec -it n1 bash
root@57d838278668:/# ls
bin   data  docker-entrypoint.d   etc	lib    media  opt   root  sbin	sys  usr
boot  dev   docker-entrypoint.sh  home	lib64  mnt    proc  run   srv	tmp  var
root@57d838278668:/# cd data/
root@57d838278668:/data# ls
root@57d838278668:/data# echo haha > n1.txt
root@57d838278668:/data# cat n1.txt
haha
# 2 进入n2容器
[root@localhost ~]# docker exec -it n2 bash
root@512c4a01e3ef:/# cd data/
root@512c4a01e3ef:/data# ls
n1.txt
root@512c4a01e3ef:/data# cat n1.txt 
haha
# 3. 在宿主机中查看
root@512c4a01e3ef:~# exit
exit
[root@localhost ~]# cd /data/nginx/
[root@localhost nginx]# ls
n1.txt
[root@localhost nginx]# 
# 4. 在宿主机上修改
[root@localhost nginx]# echo 22222 >> n1.txt 
[root@localhost nginx]# cat n1.txt 
haha
22222
# 5. 在n1 和 n2 中查看
root@57d838278668:/data# cat n1.txt 
haha
22222
root@512c4a01e3ef:/data# cat n1.txt 
haha
22222
4.两者结合运用

我们在工作中,通过使用的两者结合的方式

在宿主机上创建目录,创建容器,并挂载目录;

[root@localhost /]# mkdir /sj
[root@localhost ~]# docker run --name nginx -d -v /sj:/usr/share/nginx/html -p 80:80 nginx:1.28.1
764bd70bcac4d6466c1aa74ad529a335f4349587f9db49763f801b865e8029cc
[root@localhost /]# docker inspect nginx
.....
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/sj",
                "Destination": "/usr/share/nginx/html",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
..... 

查看挂载目录,进入容器内部并创建index.html;

[root@localhost /]# ls /sj
[root@localhost /]# 
[root@localhost volumes]# docker exec -it nginx bash
root@764bd70bcac4:/# cd /usr/share/nginx/html/
root@764bd70bcac4:/usr/share/nginx/html# ls
root@764bd70bcac4:/usr/share/nginx/html# 
[root@localhost ~]# echo welcome to nginx > /sj/index.html
[root@localhost ~]# cat /sj/index.html 
welcome to nginx

在容器中确认,并进行访问测试;

[root@localhost ~]#  docker exec -it nginx bash
root@764bd70bcac4:/#  cd /usr/share/nginx/html
root@764bd70bcac4:/usr/share/nginx/html# ls
index.html
root@764bd70bcac4:/usr/share/nginx/html# cat index.html
welcome to nginx
#访问测试
[root@localhost sj]# curl localhost
welcome to nginx
总结
类型 存储位置 特点 适用场景
数据卷 /var/lib/docker/volumes/ Docker 管理,非 Docker 进程不建议修改,隔离性好、易管理,是最佳实践 通用数据持久化(如 Nginx 网页、MySQL 数据)
绑定挂载 主机任意目录 可挂载主机任意路径,主机 / 容器进程均可修改,灵活性高但隔离性弱 需主机与容器共享特定目录(如配置文件)
tmpfs 挂载 主机内存 仅存内存不写磁盘,性能极高但数据不持久 临时缓存、敏感数据临时存储

本次学习通过 Nginx 容器挂载实操,完整掌握了数据卷和绑定挂载的创建、挂载、验证、删除全流程,理解了 Docker 数据管理的底层逻辑,为后续数据库、中间件等容器化部署的持久化配置奠定了基础。

更多推荐