容器数据卷
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过UnionFS,提供一些用于持续存储或共享数据。
将应用和环境打包成一个镜像,数据也在容器里面,如果我们把容器删除了,数据就没了。
容器之间有一个数据共享技术,Docker容器中产生的数据,同步到本地。这就是卷技术,目录的挂载,将我们容器内的目录,挂在到Linux上。
修改Docker容器里面的数据,本地数据跟着变化,修改本地数据,Docker容器里面的数据也跟着变化。删除了Docker后,本地数据没有被删除。
特性:卷设计的目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。
特点:
- 数据卷可以在容器之间共享或重用数据
- 卷中的更改可以直接实施生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
运行一个带有容器卷功能的容器实例:
docker run -it [--privileged=true] -v 宿主机绝对路径目录:容器内目录[:rw|ro] 镜像名或者镜像ID
可以使用docker inspect
查看容器绑定的数据卷。
权限:
rw
:读写 ,默认就是这个ro
:只读。如果宿主机写入内容,可以同步给容器内,容器内可以读取,不能改变。
Docker挂载主机目录,可能会出现报错:cannot open directory .: Perission denied
。
解决方案:在命令中加入参数 --privileged=true
。
CentOS7安全模块比之前系统版本加强,不安全的会先禁止,目录挂载的情况被默认为不安全的行为,在SELinux里面挂载目录被禁止掉了。如果要开启,一般使用 --privileged=true
,扩大容器的权限解决挂载没有权限的问题。也即使用该参数,容器内的root才拥有真正的root权限,否则容器内的root只是外部的一个普通用户权限。
#运行centos容器,宿主机目录/home/ceshi,容器类目录/home,两个目录映射关系
[root@izj6cev682kqg86i4ogj8rz ~]# docker run -it -v /home/ceshi:/home centos /bin/bash
[root@b402cda0c8f6 /]# cd /home
#在容器里面创建了一个test.java文件,我通过Xftp在linux的/home/ceshi目录里面发现了同步创建的文件
[root@b402cda0c8f6 home]# touch test.java
[root@b402cda0c8f6 home]# ls
test.java
#我在linux目录里面创建的文件,同步到了容器里面
[root@b402cda0c8f6 home]# ls
abc.txt test.java
#最后我删除了centos容器,linux宿主机目录下的文件还在
[root@b402cda0c8f6 home]# exit
exit
[root@izj6cev682kqg86i4ogj8rz ~]# docker rm b402cda0c8f6
b402cda0c8f6
容器卷的继承
通过--volumes-from 容器名或者ID
可以实现容器之间的挂载继承。
是拷贝机制,abc三个容器,a挂载的本地路径,b挂载a,c挂载b,a被删除了,bc数据还在
# 启动一个容器
docker run -it --privileged=true /tmp/test:/tmp/docker --name c1 centos /bin/bash
# 使用 --volumes-from 继承 u1的容器卷映射配置
docker run -it --privileged=true --volumes-from c1 --name c2 centos
具名和匿名挂载
挂载目录路径的时候,在-v后面只写了一个容器内的路径,没有指定宿主机的路径,这就是匿名挂载。
可以通过docker volume
来查看卷的情况
可以看到输出的卷的名字1f581adcdd4df8749da0971bfa19071a08635fc843ee7e2569843b509c74e315
就是匿名挂载的nginx的卷名
[root@izj6cev682kqg86i4ogj8rz ~]# docker run -d -p 3344:80 --name nginx03 -v /ect/nginx nginx
88e927ef258502d1596c72f43666640d203911490152128a6d3a6b26bea11d31
[root@izj6cev682kqg86i4ogj8rz ~]# docker volume ls
DRIVER VOLUME NAME
local 1f581adcdd4df8749da0971bfa19071a08635fc843ee7e2569843b509c74e315
[root@izj6cev682kqg86i4ogj8rz ~]#
当我们在-v后面指定了 名字:容器内路径
,这就是具名挂载
[root@izj6cev682kqg86i4ogj8rz ~]# docker run -d -P --name nginx04 -v nginx04test:/ect/nginx nginx
2457ed3d810b17ad1628de2ffe7a675e9b5652b672a6fb28b6a468f91aabf30e
[root@izj6cev682kqg86i4ogj8rz ~]# docker volume ls
DRIVER VOLUME NAME
local 1f581adcdd4df8749da0971bfa19071a08635fc843ee7e2569843b509c74e315
local nginx04test
通过docker volume inspect 卷名
可以查看对应的卷挂载的目录。
在/var/lib/docker
目录下,所有的docker相关的东西默认都在这个目录下。
匿名和具名挂载的卷都在/var/lib/docker/volumes
目录下。
[root@izj6cev682kqg86i4ogj8rz ~]# docker volume inspect nginx04test
[
{
"CreatedAt": "2022-06-01T14:44:02+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/nginx04test/_data",
"Name": "nginx04test",
"Options": null,
"Scope": "local"
}
]
[root@izj6cev682kqg86i4ogj8rz ~]# cd /var/lib/docker
[root@izj6cev682kqg86i4ogj8rz docker]# ls
buildkit containers image network overlay2 plugins runtimes swarm tmp trust volumes
[root@izj6cev682kqg86i4ogj8rz docker]# cd /var/lib/docker/volumes
[root@izj6cev682kqg86i4ogj8rz volumes]# ls
1f581adcdd4df8749da0971bfa19071a08635fc843ee7e2569843b509c74e315 backingFsBlockDev metadata.db nginx04test
[root@izj6cev682kqg86i4ogj8rz volumes]#
具名,匿名,指定路径挂载区分
:::success
-v 容器内路径
:匿名挂载-v 卷名:容器内路径
:具名挂载-v /宿主机的绝对路径:容器内路径
:指定路径挂载 :::