<一>数据存储方式
<1> bind mount
启动容器时,通过-v参数在host主机上指定一个对应的挂点目录,如下:
docker run -d --name my_httpd -v /my_http_dir:/usr/lib/http_dir httpd
如上容器运行后,将my_http_dir&/usr/lib/http_dir 两个目录点挂在一起.
注:当容器被删除时,host的目录仍旧存在的,数据可以被持久化,再次启动一个容器,仍旧指定对应的目录.
<2> docker managed volume
例:启动容器时,直接不指定mount point
docker run -it --name vvv_three -v /usr/lib/htdoc busybox
如上命令直接指定一个容器目录,并没有指定mount point,此时容器会默认在/var/lib/docker/volumes目录下生成一个随机的目录『 不同的操作系统可能差异 』
通过如下命令查看当前容器挂在点信息:
docker inspect 容器id (通过docker ps -a|grep container_name查询,或者直接查找)
查看挂在源信息:
[root@#] docker inspect e3s434333darde
....
"Mounts": [
{
"Type": "volume",
"Name": "82be27ec4cd694fc4a57d129f6ac14e4a1c6a0f9528aef05ecc3737c0b02dd59",
"Source": "/var/lib/docker/volumes/82be27ec4cd694fc4a57d129f6ac14e4a1c6a0f9528aef05ecc3737c0b02dd59/_data",
"Destination": "/usr/lib/htdoc",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
...
查看创建的卷信息:
[root@#] docker volume inspect 82be27ec4cd694fc4a57d129f6ac14e4a1c6a0f9528aef05ecc3737c0b02dd59
[
{
"CreatedAt": "2022-09-20T21:36:59+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/82be27ec4cd694fc4a57d129f6ac14e4a1c6a0f9528aef05ecc3737c0b02dd59/_data",
"Name": "82be27ec4cd694fc4a57d129f6ac14e4a1c6a0f9528aef05ecc3737c0b02dd59",
"Options": null,
"Scope": "local"
}
]
总结:
a> 容器启动时,直接告诉 docker 我需要一个 volume 存放数据,帮我 mount 到目录 /abc
b> docker 在 /var/lib/docker/volumes 中生成一个随机目录作为 mount 源,用于存放数据
c> 如果 /abc 已经存在,则将数据复制到 mount 源 (数据复制到随机生成的mount源)
d> 将 volume mount 到 /abc
e> 如果想将一个容器挂在多个mount源,只需要使用多个-v指定即可
***[如上,1,2两种方式,的数据都可以持久化存储数据,并且两者都最终的数据都是存储在host主机上]
<二>docker 数据共享
<1> data volume - bind 相同挂在点数据共享(目录or文件,容器可以读写volume,并且volume数据会永久保存,即便在没有容器情况)该方法可以达到容器跟容器,容器跟host之间的数据共享.
例如: 相同挂在点 /vvvv_data目录点
docker run -it --name vvv_1 -v /vvvv_data:/var/lib/vvv busybox
docker run -it --name vvv_2 -v /vvvv_data:/var/lib/vvv busybox
如上两个容器,都挂在/vvvv_data目录下,那么两个容器之前的共享目录,任何一个改变,另外一个都会同步改变,(当然可以操作host对应的挂在目录,两个容器都会同步修改)
(
使用-v时,也可以指定对应的权限,例如指定只读, ro:只读属性
docker run -it --name vvv_only_read /vvvv_data:/var/lib/vvv:ro busybox
如果改变文件,直接报错如下:
[/#] echo "study" >> /var/lib/vvv/vvv.log
sh: can't create /var/lib/vvv/vvv.log: Read-only file system
[/#]
)
不足:因为所有的容器都要挂在host上的目录,所以限制了迁移性,当迁移时,如果其他host没有对应的文件目录,直接操作失败。
<2> volumes container数据共享
a.创建一个容器,并且指定对应的挂载点(无需启动容器,但数据仍旧在host上存储),新启动容器通过--volumes-from 指定共享数据的容器,如下:
docker create --name vc_data -v /file:/usr/lib/file -v /tool:/usr/lib/tool busybox
first:
docker run -it --name first --volumes-from vc_data busybox
second:
docker run -it --name second --volumes-from vc_data busybox
可通过docker inspect 容器名 查看对应的数据存储信息,如下,只关注Mounts信息
"Mounts": [
{
"Type": "bind",
"Source": "/data/htdocs",
"Destination": "/usr/local/htdocs",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
<3> 使用第三容器实现容器之间的共享数据(该种方法,不用再host主机上存储数据)
还是第三容器的方式,但是容器存储的的点不在时host主机目录。通过自定义镜像,再创建一个一个容器作为数据存储点
其他容器运行时,同等上述<2>中的--volumes-from 指定容器即可。该方式可移值性比较好,并非常实用于一些静态数据,比如web静态文件,以及应用配置。
示例:
Dockerfile:
FROM busybox
ADD doc /usr/lib/docs
VOLUME /usr/lib/docs
[root@#] docker build -t vc_vol .
[root@#] docker push registry.net:port/username/vc_vol
[root@#] docker create --name vc_vol_data vc_vol
[root@#] docker run -it --name con_one --volumes-from vc_vol_date busybox
[root@#] docker run -it --name con_two --volumes-from vc_vol_data busybox
如上启动两个容器,从而实现数据共享,将数据存储写入到对应的vc_vol_data中.可以直接在某个容器中修改对应的数据内容,再另一个容器中也会看到对应数据的修改。
(该种方式不足之处,不适用于需改修改的情景)
<三>存储管理卷
docker managed volume
备份:
本地仓库的创建,实质上最重存储的镜像还是存储在host主机上的,具体的目录,就是创建仓库时通过-v参数指定的路径.
注:定时备份该目录即可。
恢复:
如果当前的数据坏了,直接讲备份的数据拷贝到-v指定的目录即可恢复。
迁移:
在仓库如果有更新,想使用最新的仓库,只需要通过下操作即可:
1.docker stop 当前registry容器
2.重新启动容器并将挂在点(mount)设置为原来的volume位置。例如:
docker run -d -p 5000:5000 -v /selfregistry:/var/lib/registry registry:latest
3.通过如上两步操作,即可将原来的数据迁移至最新的仓库
删除:
当容器要销毁时,对应的volume数据也不需要了,可以一并进行销毁. 操作如下:
docker rm containerId -v [-v参数,销毁容器时,连同相关的volume一并销毁] 如果不带-v参数,则仅仅销毁的是容器,对应的volume并不会被销毁.那么造成孤儿volume,就像linux进程的孤儿进程一样(linux进程会被init进程最终管理,但是volume并不会被任何容器管理)
所以需要开发者管理,具体操作如下:
docker volume rm 孤儿volume的目录名
可批量删除:
docker volume rm $(docker volume ls -q)