docker 数据管理
Docker 内部管理数据主要有两种方式:
- 数据卷:Data Volumes 容器内数据直接映射到本地主机环境
- 数据卷容器:Data Volume Containers 使用特定容器维护数据卷
数据卷
当我们在使用docker容器的时候,会产生一系列的数据文件,这些数据文件在我们删除docker容器时是
会消失的,但是其中产生的部分内容我们是希望能够把它给保存起来另作用途的,Docker将应用与运行环境打包成容器发布,我们希望在运行过程钟产生的部分数据是可以持久化的的,而且容器之间我们希望能够实现数据共享。
通俗地来说,docker容器数据卷可以看成使我们生活中常用的u盘,它存在于一个或多个的容器中,由docker挂载到容器,但不属于联合文件系统,Docker不会在容器删除时删除其挂载的数据卷。
- 数据卷可以在容器之间共享和重用
- 对数据卷的修改会立马生效
- 对数据卷的更新,不会影响镜像
- 数据卷默认会一直存在,即使容器被删除
数据卷挂载支持三种方式,tmpfs、volume、mount
tmpfs 非数据持久化方式。将数据卷挂载到宿主机内存中。建议只用于测试使用。
mount 将宿主机的目录挂载到容器里,操作权限在宿主机。
volume 将宿主机的目录与容器目录做绑定映射,操作权限在容器。
因docker官方强烈推荐使用volume,所以下面只叙述volume的用法
注意:数据卷的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的数据卷。
mount示例:
使用 -v
标记也可以指定挂载一个本地主机的目录到容器中去,不存在的目录会自动创建。
docker run ... -v 宿主机目录(文件):容器内目录(文件) ... # 宿主名目录(文件)的路径为绝对路径
宿主机内本来没有的文件,在容器内部创建后宿主机可以搜索到,重启容器或者宿主机是不会消失。
一旦删除容器,容器层数据将会删除,宿主机内数据也会删除。
[root@vms10 ~]# find / -name aaaa
[root@vms10 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
567dd209b8c6 nginx "/docker-entrypoint.…" 58 seconds ago Up 57 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp web
[root@vms10 ~]# docker exec -it web bash
root@567dd209b8c6:/# touch aaaa
root@567dd209b8c6:/# exit
exit
[root@vms10 ~]# find / -name aaaa
/var/lib/docker/overlay2/0a1738208d13307fba4a11a26f389b8cb4817b27edb89b06b9a992c52c99f430/diff/aaaa
/var/lib/docker/overlay2/0a1738208d13307fba4a11a26f389b8cb4817b27edb89b06b9a992c52c99f430/merged/aaaa
[root@vms10 ~]# docker restart web
web
[root@vms10 ~]# find / -name aaaa
/var/lib/docker/overlay2/0a1738208d13307fba4a11a26f389b8cb4817b27edb89b06b9a992c52c99f430/diff/aaaa
/var/lib/docker/overlay2/0a1738208d13307fba4a11a26f389b8cb4817b27edb89b06b9a992c52c99f430/merged/aaaa
[root@vms10 ~]# docker rm -f web
web
[root@vms10 ~]# find / -name aaaa
[root@vms10 ~]#
-v
指定挂载一个宿主机的目录到容器中去,容器内部写数据会映射到宿主机中,删除容器后宿主机数据还在。
1、如果只指定一个目录那么这个目录是容器内的目录,此目录不存在会自动生成,并且不指定宿主机中路径会自动映射挂载到其中宿主机的一个目录。
[root@vms10 ~]# docker run -itd --name=web --restart=always -v /data nginx
# 查看宿主机中挂在路径
[root@vms10 ~]# docker inspect web
"Mounts": [
{
"Type": "volume",
"Name": "51bdef00681072466505d3f96dfe3acc70f4b13025c96003e5f079418f6942d3",
"Source ": "/var/lib/docker/volumes/51bdef00681072466505d3f96dfe3acc70f4b13025c96003e5f079418f6942d3/_data",
"Destination": "/data",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
# Destination 容器内的目录
# Source 宿主机内的目录
此时间从容器内创建数据在宿主机可以看到,在宿主机创建数据后在容器内也可以看到。
[root@vms10 ~]# ls /var/lib/docker/volumes/51bdef00681072466505d3f96dfe3acc70f4b13025c96003e5f079418f6942d3/_data
[root@vms10 ~]# docker exec -it web bash
root@74a770517427:/# ls /data/
root@74a770517427:/# touch /data/aaaa
root@74a770517427:/# ls /data/
aaaa
root@74a770517427:/# exit
exit
[root@vms10 ~]# ls /var/lib/docker/volumes/51bdef00681072466505d3f96dfe3acc70f4b13025c96003e5f079418f6942d3/_data
aaaa
[root@vms10 ~]# touch /var/lib/docker/volumes/51bdef00681072466505d3f96dfe3acc70f4b13025c96003e5f079418f6942d3/_data/bbbb
[root@vms10 ~]# docker exec -it web bash
root@74a770517427:/# ls /data/
aaaa bbbb
删除容器后,宿主机数据还存在
[root@vms10 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
74a770517427 nginx "/docker-entrypoint.…" 7 minutes ago Up 7 minutes 80/tcp web
[root@vms10 ~]# docker rm -f web
web
[root@vms10 ~]# ls /var/lib/docker/volumes/51bdef00681072466505d3f96dfe3acc70f4b13025c96003e5f079418f6942d3/_data
aaaa bbbb
[root@vms10 ~]#
再次指定容器内/data 重新创建容器,内部/data数据将不存在,因为宿主机对应的路径变化了,所以不要光指定一个目录路径
2、指定宿主机与容器内两个路径,不存在的目录会自动创建
[root@vms10 ~]# ls /xx
ls: 无法访问/xx: 没有那个文件或目录
[root@vms10 ~]# docker run -itd --name=web --restart=always -v /xx:/data nginx
cbccbb5e12fcd4120033f0b3f409f6666aff3daa580f49388b6d8d7212c1cc59
[root@vms10 ~]# ls /xx
[root@vms10 ~]# docker inspect web
"Mounts": [
{
"Type": "bind",
"Source": "/xx",
"Destination": "/data",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
创建文件测试都是存在的
[root@vms10 ~]# ls /xx
[root@vms10 ~]# docker exec -it web bash
root@cbccbb5e12fc:/# ls /data/
root@cbccbb5e12fc:/# touch /data/aaaa
root@cbccbb5e12fc:/# ls /data/
aaaa
root@cbccbb5e12fc:/# exit
exit
[root@vms10 ~]# ls /xx
aaaa
[root@vms10 ~]# touch /xx/bbbb
[root@vms10 ~]# docker exec -it web bash
root@cbccbb5e12fc:/# ls /data/
aaaa bbbb
root@cbccbb5e12fc:/#
删除容器后,在重新创建指定之前目录进入后数据还是存在的。
[root@vms10 ~]# docker rm -f web
web
[root@vms10 ~]# docker run -itd --name=web --restart=always -v /xx:/data nginx
ffb0678eb1902fbb63c619aebe78ad2294132bd52f88620e8e18cdee9f3502b0
[root@vms10 ~]# docker exec -it web bash
root@ffb0678eb190:/# ls /data/
aaaa bbbb
root@ffb0678eb190:/#
默认执行的命令后是隐藏了权限的设置,正常的话是
[root@vms10 ~]# docker run -itd —name=web —restart=always -v /xx:/data:rw nginx
不写的话默认就是rw读写权限。也可以设置只读权限
[root@vms10 ~]# docker run -itd —name=web —restart=always -v /xx:/data:ro nginx
那么启动容器后进入到容器内部则是只读操作/data目录
volume 示例
通过创建docker volumes ,docker会把数据存放在默认配置的路径。
[root@vms10 ~]# docker volume list # 查看volume列表
DRIVER VOLUME NAME
local 631f3a65bc09729fa0a98ff47d4daa54f9dd9ed02c77365e004ee75cb6626138
local 742e3f8289754c663670740f67feeb5abfcaff61dc22f023d2beda3b7677d6b6
[root@vms10 ~]# docker volume create v1 # 创建volume
v1
[root@vms10 ~]# docker volume list
DRIVER VOLUME NAME
local 631f3a65bc09729fa0a98ff47d4daa54f9dd9ed02c77365e004ee75cb6626138
local 742e3f8289754c663670740f67feeb5abfcaff61dc22f023d2beda3b7677d6b6
local v1
[root@vms10 ~]# docker volume inspect v1 # 查看volume详细信息
[
{
"CreatedAt": "2022-03-03T03:38:30+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/v1/_data",
"Name": "v1",
"Options": {},
"Scope": "local"
}
]
# Mountpoint 宿主机目录
可以直接指定上述volume进行启动容器
[root@vms10 ~]# docker volume inspect v1
[
{
"CreatedAt": "2022-03-03T03:38:30+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/v1/_data",
"Name": "v1",
"Options": {},
"Scope": "local"
}
]
[root@vms10 ~]# ls /var/lib/docker/volumes/v1/_data
[root@vms10 ~]# docker run -itd --name=web --restart=always -v v1:/data nginx
41b3b7d6ba4859232df1695522575bd685c8ec899280e9cf56b9c1382007ceed
[root@vms10 ~]# docker exec -it web bash
root@41b3b7d6ba48:/# ls /data/
root@41b3b7d6ba48:/# touch /data/aaaa
root@41b3b7d6ba48:/# ls /data/
aaaa
root@41b3b7d6ba48:/# exit
exit
[root@vms10 ~]# ls /var/lib/docker/volumes/v1/_data
aaaa
[root@vms10 ~]# touch /var/lib/docker/volumes/v1/_data/bbbb
[root@vms10 ~]# docker exec -it web bash
root@41b3b7d6ba48:/# ls /data/
aaaa bbbb
root@41b3b7d6ba48:/#
如果忘记了容器内部挂载的目录是/data ,那么做这个数据卷意义何在?