


容器默认的数据读写操作在容器的存储层,当容器被删除时其上的数据将会丢失。所以我们应该尽量保证容器存储层不发生写操作,不然我们存储的数据很容易随着容器的删除而丢失,为了实现数据的持久化存储我们需要选择一种方案来保存数据。目前实现该方案的主要有Volumes 、 Bind mounts 、 tmpfs mounts,下面我们主要介绍Volumes与Bind mounts
volumes数据卷:
docker管理宿主机文件系统的一部分,通常存储在(/var/lib/docker/volumes)中,提供很多有用的特性:
1:数据卷可以在容器之间共享和重用,多个容器共享Volumes更安全
2:对数据卷的修改会立马生效
3:对数据卷的更新,不会影响镜像
4:数据卷默认会一直存在,即使容器被删除
5: Volumes更容易备份和移植。
6: 可以通过Docker CLI或API进行管理
7: Volumes可以无区别的工作中Windows和Linux下
8:当容器外的对应目录是空的,volume会先将容器内的内容拷贝到容器外目录,而mount会将外部的目录覆盖容器内部目录,内部的文件会被清空。相当于两种挂载方式处理文件是相反的,一种是把内部的复制到外部,一种是把外部的文件覆盖到内部
9:volume 是docker的宿主机文件系统一部分,只有docker可以进行更改,其他进程不能修改
bind mounts挂载主机目录:
将宿主机上的任意位置的文件或者目录挂在到容器 (—mount type=bind,src=源目录,dst=目标目录)
1:mount方式会将外部的目录覆盖容器内部目录,内部的文件会被清空。不管外部目录有没有文件内部目录的文件都会被清空,如果外部有文件就被外部的文件给复制出来。所以如果是把容器的内部的文件映射出来在外部使用,更推荐使用Volumes方式,但是如果镜像会经常更新,而以前持久化的数据存储在外边,如果使用Volumes方式新打包的镜像启动容器就会覆盖以前的内容,所以需要根据实际情况选择挂载方式。
2:bind mounts 是挂载在宿主机文件系统的任意位置,除了docker所有进程都可以进行修改
3:bind mount可以直接挂载文件,例如挂载nginx容器的配置文件:nginx.conf。
类似于配置文件这种单文件方式不太适合使用volume,可以使用bind mount,但由于config文件中包含一些类似于数据库密码等敏感信息,因此推荐使用tmpfs。
Volume管理
1) 使用命令创建一个Volume。如图6.5所示
docker volume create my-nginx-volume
2) 使用命令查看Volumes。如图6.6所示
docker volume ls
可以使用如下命令查看volume详情,如图6.7所示。
|docker volume inspect my-nginx-volume|
我们可以看到创建的my-nginx-volume 目录保存在/var/lib/docker/volumes/下,以后所有针对该 Volume 的写数据都会保存在目录/var/lib/docker/volumes/my-nginx-volume/_data中。
3) 删除一个指定名称的Volume。如图6.8所示
docker volume rm my-nginx-volume
删除后我们再次查看了一下Volume,可以看到刚刚创建的Volume已经被删除掉了
4) 删除所有未使用的 Volumes
我们可以先创建几个Volume,如图6.9所示。
docker volume create my-volume-test-1
docker volume create my-volume-test-2
docker volume create my-volume-test-3
查看一下刚刚创建的Volume,如图6.10所示。
docker volume ls
使用命令执行删除所有未使用的 Volumes,如图6.11所示。
docker volume prune
删除后我们再次查看了一下Volume,可以看到很多的Volume已经被删除掉了,只剩下两个,而且执行的时候会让你输入一个y或者n进行确定和取消,因为该命令可能会造成一些误删除,所以需要用户的确认。
挂载数据卷到容器目录
1) 运行容器时通过指定—mount 参数来使用 Volume
我们先创建一个Volume,如图6.12所示。
docker volume create my-nginx-volume
然后运行容器的时候通过指定—mount 参数来使用 Volume,如图6.13所示。
docker run -d \
--name=nginxtest \
--mount source=my-nginx-volume,destination=/usr/share/nginx/html \
nginx:latest
source 指定 volume,destination 指定容器内的文件或文件夹。
挂载成功后,容器从 /usr/share/nginx/html 目录下读取或写入数据,实际上都是从宿主机的 my-nginx-volume 数据卷中读取或写入数据。因此 Volumes 或 Bind mounts 也可以看作是容器和宿主机共享文件的一种方式。
运行成功后可以查询一下刚刚启动的容器,如图6.14所示。
2) 运行容器时通过指定 -v参数来使用 Volume
我们先创建一个Volume,如图6.15所示。
docker volume create my-nginx-volume-2
然后运行容器的时候通过指定—v 参数来使用 Volume,如图6.16所示。
docker run -d \
--name=nginxtest-2 \
-v my-nginx-volume-2:/usr/share/nginx/html \
nginx:latest
-v 参数使用冒号分割 source 和 destination,冒号前半部分是 source,后半部分是 destination。
注意如果你挂载的数据卷不存在,Docker 会自动创建它,所以通常不需要手动去创建数据卷
如果容器中的待挂载的目录不是一个空目录,那么该目录下的文件会被复制到数据卷中。Bind mounts模式下,宿主机上的目录总会覆盖容器中的待挂载目录
-v 参数和 —mount 参数总的来说功能几乎一样,唯一的区别是在运行一个 service 时只能够使用—mount 参数来挂载数据卷。
3) 查看一下上面我们使用的数据卷,如图6.17所示
docker volume ls
通过如下命令查看volume详情,可以看volume使用的目录,如图6.18所示。
docker volume inspect my-nginx-volume
可以通过如下进入volume使用的目录查看文件,如图6.19所示。
cd /var/lib/docker/volumes/my-nginx-volume/_data
ls
可以看到有个50x.html与index.html
查看一下index.html的内容,如图6.20所示。
cat index.html
可以看到就是nginx里边的起始页
4) 修改挂载目录内容,测试数据。
重新运行容器,指定一下端口,如图6.21所示。
docker run -d \
--name=nginxtest-3 \
-p 9000:80 \
-v my-nginx-volume-3:/usr/share/nginx/html \
nginx:latest
访问指定映射的9000端口,如图6.22所示。
查看刚刚的挂载卷与对应的目录,如图6.23所示。
进入volume使用的目录查看文件,如图6.24所示。
cd /var/lib/docker/volumes/my-nginx-volume-3/_data
ls
使用vi命令修改index.html文件
vi index.html
把提示语句修改一点即可,如图6.25所示。
然后在访问数据已经变化了,如图6.26所示。证明我们的挂载已经成功了,因为我们并没有进入容器内部修改,而是通过在容器外部修改达到修改内部资源的效果。
bind mounts挂载主机目录
这种挂载比较简单,可以挂载系统盘的任意可用目录,直接挂载就可以。如果挂载的目录不存在也会自动创建。
比如运行nginx的时候挂载目录html出来
docker run -d \
--name=mynginx \
-p 8000:80 \
-v ~/aj/nginx-html:/usr/share/nginx/html \
nginx
又比如挂载.net6项目下面的wwwroot目录下个某个文件
docker run --name=wy_jbland_api \
-p 8003:8003 \
-v ~/fb/wy_jbland_api_volumne_uploads:/app/wwwroot/uploads \
wy_jbland_api:v1
注意:当容器外的对应目录是空的,mount会将外部的目录覆盖容器内部目录,也就是说内部目录的数据也会被清空。如果外部目录有文件,也被复制进去,而且内部原有的文件会被清空。相当于两种挂载方式处理文件是相反的,一种是把内部的复制到外部,一种是把外部的文件复制到内部,可以根据不同的需求选择不同的挂载方式。
mount方式会将外部的目录覆盖容器内部目录,内部的文件会被清空。不管外部目录有没有文件内部目录的文件都会被清空,如果外部有文件就被外部的文件给复制出来。所以如果是把容器的内部的文件映射出来在外部使用,更推荐使用Volumes方式,但是如果镜像会经常更新,而以前持久化的数据存储在外边,如果使用Volumes方式新打包的镜像启动容器就会覆盖以前的内容,所以需要根据实际情况选择挂载方式。
视频地址:
链接: https://pan.baidu.com/s/1Z8PoO9sHIx8pTPlZkTT0hA?pwd=26y6 提取码: 26y6 复制这段内容后打开百度网盘手机App,操作更方便哦
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739。有需要软件开发,或者学习软件技术的朋友可以和我联系~(Q:815170684)