目录
[1.2绑定挂载(bind mount)](#1.2绑定挂载(bind mount))
[1.3数据卷(Docker Volume)](#1.3数据卷(Docker Volume))
[1.4卷插件(Volume Plugins)](#1.4卷插件(Volume Plugins))
一.Docker数据卷
1.1简单介绍
1.概述 :`Docker` 数据卷(`Volume`)是用于将数据从容器持久化到宿主机中的一种机制。存储卷可以在容器之间共享和重用,即使容器被删除,卷中的数据仍然会保留。
设计数据卷的目的就是让数据的持久化完全独立于容器的生命周期。数据卷是经过特殊设计的目录。可以对数据卷里的内容直接进行修改。数据卷的变化不会影响镜像的更新。数据卷会一直存在,即使挂载数据卷的容器已经被删除。
2.三种存储方式:
2.1 Volume :一般存储在/var/lib/docker/volumes目录下,该目录由 Docker Engine进程管理,不允许其他进程修改。
2.2 bind mount :直接挂载到主机任意文件系统的目录或者文件,方法最简单。它类似于主机和容器共享存储目录,主机中的所有进程都可以修改该目录下的文件,不太安全。
2.3 tmpfs :挂载存储到主机的内存当中,不会写入主机的磁盘当中。适合存储临时数据,提高容器性能。

3.绑定挂载与数据卷的区别:
|---------------------|-------------------|----------------------------|
| | bind mount | docker manager volume |
| volume位置 | 可任意指定 | /var/log/docker/volume/容器名 |
| mount point存在文件 | 隐藏并替换为volume | 原有数据替换到volume |
| 是否支持单个文件挂载 | 支持 | 不支持,只支持目录 |
| 权限控制 | 默认读写权限,可选只读 | 均为读写权限 |
| 移植性 | 移植性弱,与host path绑定 | 移植性强,数据都存在统一位置 |
4.权限选项(可选):
- ro:只读(容器内无法修改挂载的文件/ 目录)
- rw:读写(默认,容器内可修改)
1.2绑定挂载(bind mount)
1.2.1简单介绍
1.概述:docker bind mount(绑定挂载)是 Docker 中一种将宿主机的文件或目录直接挂载到容器内部的机制,使容器与宿主机共享指定的文件或目录,实现数据的实时同步。
2.注意 : bind mount会将本机上的文件强制覆盖到容器当中,如果容器的挂载点中存在文件,会被主机文件替换掉,即使主机目录下什么也没有。
1.2.2基本用法
说明:执行docker 命令时,使用-v参数,将本机的文件或目录映射到容器的内部目录或文件当中
bash
-v 本机目录或文件:容器内部目录或文件
示例:将本机的/opt/website文件挂载到nginx容器的/var/lib/www/html文件中
1.挂载空目录,出现客户端请求失败问题(403)
bash
mkdir -p /opt/website
docker run -d --name web1 -v /opt/website:/var/lib/www/html -p 80:80 nginx
curl localhost


2.本机下添加index.html文件
说明:由此可以得出,docker 的挂载文件支持实时读取,不需要重启生效
bash
echo hello > /opt/website/index.html
curl localhost

清理容器:
bash
docker rm -f web1

1.3数据卷(Docker Volume)
1.3.1简单介绍
1.概述 :在 Docker 中,Managed Volume(管理卷)是指由 Docker 引擎自动创建、管理和维护的数据卷(Volume),无需用户指定宿主机的具体路径,是 Docker 推荐的持久化数据方式之一。
它与 bind mount(绑定挂载)的核心区别在于:管理卷的存储路径完全由 Docker 控制,用户无需关心数据在宿主机的具体位置,只需通过卷名操作即可。
2.核心特性:
1.Docker 全权管理:卷的创建、存储路径(默认位于/var/lib/docker/volumes/<卷名>/_data)、权限设置等均由 Docker 引擎自动处理,用户无需手动干预。
2. 数据持久化:容器被删除后,管理卷不会被自动删除,数据依然保留(需手动删除卷)。
3. 跨容器共享:多个容器可通过卷名挂载同一个管理卷,实现数据共享。
4. 与宿主机隔离:用户无需了解宿主机的文件系统结构,避免因路径错误导致的挂载问题。
5. 支持多种驱动:除了默认的本地存储驱动,还可通过第三方驱动(如 local-persist、云存储驱动)将卷存储到外部存储(如 NFS、S 3)。
3.注意 : Docker Volume会自动读取本机上的文件覆盖到容器当中,**如果容器的挂载点中存在文件且主机的挂载点下什么也没有,则会将容器下的文件复制到主机的挂载点上。**如果主机的挂载点上存在文件,容器挂载点的文件依旧会被主机挂载点上的文件所覆盖。
1.3.2基本操作
1.创建volume数据卷
bash
docker volume create vol1 #创建名为vol1的数据卷
docker volume inspect vol1 #查看数据卷信息

2.使用新建的vol1挂载nginx镜像文件访问web1
说明: 新建的vol1下不存在任何文件,在主机和容器挂载时,容器将自身挂载点的文件,复制到了主机的挂载点上。
bash
docker run -d -p 80:80 --name web1 -v vol1:/var/lib/www/html
curl localhost

3.查看主机挂载目录下的文件
bash
cd /var/lib/docker/volumes/vol1/_data #进入数据存储目录
ll

4.验证挂载点的权限
说明:我将本机下的/data1目录挂载到容器中,权限为rw(默认);将本机下的/data2目录挂载到容器中,权限为ro。
bash
docker run -it --rm -v /data1:/data1 -v /data2:/data2:ro centos:7
容器内部操作:
bash
ls
cd /data1
touch file1 #在/data1目录下,创建一个测试文件file1
ls #查看结果
cd /data2
touch file2 #报错,提示该目录为只读目录

本机查看文件
bash
cd /data1
ls #查看结果
cd /data2
ls


5.清理数据卷
bash
docker volume prune #该动作只会清理没有被使用的数据卷

6.数据卷自动挂载
说明:如果创建时不指定主机的挂载点,docker会默认自动创建一个数据卷,用来存储容器内部的挂载数据
java
docker run -d --name web1 -v /var/lib/www/html -p 80:80 nginx
docker volume ls
curl localhost


7.存储挂载信息
说明: 将数据卷的挂载信息封装到一个容器中,通过调用这个容器,即可将挂载配置应用到新容器上。通过这种方法,实现快速重复挂载。
bash
docker create -v /tmp/data1:/data1:rw -v /tmp/data2:/data2:ro -v /etc/passwd:/mnt/passwd:ro --name datavol busybox #封装挂载信息
docker run -it --rm -volumes datavol centos:7 #调用封装的datavol挂载信息容器创建新容器

1.4卷插件(Volume Plugins)
说明 :docker卷默认使用的是Local类型的区别,只能存在宿主机。跨主机的volume,需要第三方驱动。官方只提供卷插件的API,开发者需要根据需求,定制卷驱动插件。
官方文档链接:
https://docs.docker.com/engine/extend/legacy_plugins/#volume-plugins
http://volume pluginsDocker volume plugins | Docker Docs
https://docs.docker.com/engine/extend/plugins_volume/#volume-plugin-protocol
1.4.1简单介绍
1.概述 :Docker Plugin 是以Web Service的服务运行在每一台Docker Host上的,通过HTTP协议传输 RPC风格的JSON数据完成通信。
容器本身适合无状态服务,但数据库、日志、文件存储等需要持久化数据,卷插件就是让容器引擎不用关心底层存储细节,只调用统一接口。
2.作用:把创建、挂载、卸载、删除数据卷这些操作封装起来,对上提供统一接口,对下调用具体存储。
当客户端与Daemon交互,使用插件创建数据卷时,Daemon会在后端找到插件对应的socket文件,建立连接并发起相应的API请求,最终结合Daemon自身的处理完成客户端的请求。
3.工作流程:
1. 用户创建插件容器
**2.**Docker 调用插件容器,插件去存储系统创建卷
**3.**用户启动新容器并挂载插件容器
**4.**Docker 再次调用插件,把卷挂载到宿主机某个目录
**5.**Docker 把这个目录 bind mount 到新容器里
4.框架图如下:

1.4.2convoy卷插件
1.概述 :Convoy 是一款由 Rancher 团队开发的 Docker 卷插件(Volume Plugin),主要用****于扩展 Docker 的存储能力,支持将外部存储(如本地磁盘、NFS、AWS EBS、Ceph等)作为 Docker 数据卷(Volume)使用,尤其适合在集群环境中实现数据卷的跨主机共享和持久化。
2.核心功能与特性
2.1多后端存储支持
●支持多种存储类型作为卷的底层存储,满足不同场景需求:、
●本地存储:直接使用宿主机磁盘目录(类似 Docker 原生数据卷,但提供更灵活的管理)。
●网络存储:NFS(网络文件系统)、GlusterFS、Ceph RBD 等,适合跨主机共享数据。
●云存储:AWS EBS、Google Persistent Disk 等,适配云环境部署。
2.2跨主卷共享
说明 :在 Docker Swarm 或 Kubernetes 等集群环境中,通过 Convoy 管理的卷可以被不同****主机上的容器挂载和访问,解决了 Docker 原生数据卷(local 驱动)仅能单机使用的限制。
2.3卷快照与恢复
说明 :支持对卷创建快照(Snapshot),并能通过快照恢复数据,方便数据备份和版本管理。
创建容器快照:
bash
convoy snapshot create myvolume-snap1 myvolume #创建快照
恢复容器快照:
bash
convoy snapshot restore myvolume-restored myvolume-snap1 #恢复快照
1.4.3项目:结合nfs使用数据卷
说明:将数据卷放到nfs共享目录下,多个主机可以通过该目录,访问数据卷的信息,实现多个主机的信息共享
项目描述:将docker1上的数据卷共享给docker2
|---------------|--------------|----------|
| IP地址 | 主机名 | 挂载点 |
| 192.168.7.161 | docker1(服务端) | /mnt/nfs |
| 192.168.7.162 | docker2(客户端) | /mnt/nfs |

1.两个主机上配置nfs共享目录
1.1两个主机安装nfs软件
bash
yum install -y nfs-utils
systemctl start nfs
systemctl enable nfs #如果想要实现开机挂载,需要开启开机自启
1.2在docker1上修改 /etc/exports 文件,将目录共享给docker2
bash
vim /etc/exports #修改文件
exportfs -rv #使文件生效
添加以下内容:
bash
/mnt/nfs *(rw,sync,no_root_squash) #将目录/mnt/nfs暴露给所有外机,赋予读写权限,同步写入,保留客户端的root用户权限
/mnt/nfs: 共享目录
*: 共享给所有主机
rw: 读写权限
sync: 同步写入,写入后,返回给主机一个确认信号
no_root_squash: 客户端root用户进入共享目录,保留客户端的root权限
1.3docker2挂载docker1的共享目录
bash
mount docker1:/mnt/nfs /mnt/nfs
2.两个主机安装convoy插件
2.1官网下载convoy,并解压
bash
wget https://github.com/rancher/convoy/releases/download/v0.5.2/convoy.tar.gz
tar -xzf convoy.tar.gz
2.2将程序文件复制到/usr/local目录下
bash
cp convoy convoy-pdata_tools /usr/local/bin
2.3启动convoy插件
bash
mkdir -p /etc/docker/plugins/ #创建插件目录
echo "unix:///var/run/convoy/convoy.sock" >/etc/docker/plugins/convoy.spec #向 Docker 注册 Convoy 卷插件
convoy daemon --drivers vfs --driver-opts vfs.path=/mnt/nfs & #后台启动convoy插件


3.实现数据卷共享
3.1任选一个主机创建数据卷
bash
convoy create vl1 #创建vl1数据卷
convoy inspect vl1 #查看vl1信息


3.2使用共享数据卷运行容器,查看数据是否共享
说明:将vl1数据卷挂载到/data上,vl1中的数据可以被docker1和docker2上的容器同时访问
docker1上:创建数据docker1
bash
docker run -it --name vm1 -v vl1:/data --volume-driver=convoy busybox


docker2上:查看数据docker1
bash
docker run -it --name vm1 -v vl1:/data --volume-driver=convoy busybox

