容器数据卷

卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过UnionFS,提供一些用于持续存储或共享数据。

将应用和环境打包成一个镜像,数据也在容器里面,如果我们把容器删除了,数据就没了。
容器之间有一个数据共享技术,Docker容器中产生的数据,同步到本地。这就是卷技术,目录的挂载,将我们容器内的目录,挂在到Linux上。
修改Docker容器里面的数据,本地数据跟着变化,修改本地数据,Docker容器里面的数据也跟着变化。删除了Docker后,本地数据没有被删除。

特性:卷设计的目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。
特点:

  • 数据卷可以在容器之间共享或重用数据
  • 卷中的更改可以直接实施生效
  • 数据卷中的更改不会包含在镜像的更新中
  • 数据卷的生命周期一直持续到没有容器使用它为止

运行一个带有容器卷功能的容器实例:

  1. docker run -it [--privileged=true] -v 宿主机绝对路径目录:容器内目录[:rw|ro] 镜像名或者镜像ID

可以使用docker inspect查看容器绑定的数据卷。
image.png
权限:

  • rw:读写 ,默认就是这个
  • ro:只读。如果宿主机写入内容,可以同步给容器内,容器内可以读取,不能改变。

Docker挂载主机目录,可能会出现报错:cannot open directory .: Perission denied
解决方案:在命令中加入参数 --privileged=true
CentOS7安全模块比之前系统版本加强,不安全的会先禁止,目录挂载的情况被默认为不安全的行为,在SELinux里面挂载目录被禁止掉了。如果要开启,一般使用 --privileged=true,扩大容器的权限解决挂载没有权限的问题。也即使用该参数,容器内的root才拥有真正的root权限,否则容器内的root只是外部的一个普通用户权限。

  1. #运行centos容器,宿主机目录/home/ceshi,容器类目录/home,两个目录映射关系
  2. [root@izj6cev682kqg86i4ogj8rz ~]# docker run -it -v /home/ceshi:/home centos /bin/bash
  3. [root@b402cda0c8f6 /]# cd /home
  4. #在容器里面创建了一个test.java文件,我通过Xftp在linux的/home/ceshi目录里面发现了同步创建的文件
  5. [root@b402cda0c8f6 home]# touch test.java
  6. [root@b402cda0c8f6 home]# ls
  7. test.java
  8. #我在linux目录里面创建的文件,同步到了容器里面
  9. [root@b402cda0c8f6 home]# ls
  10. abc.txt test.java
  11. #最后我删除了centos容器,linux宿主机目录下的文件还在
  12. [root@b402cda0c8f6 home]# exit
  13. exit
  14. [root@izj6cev682kqg86i4ogj8rz ~]# docker rm b402cda0c8f6
  15. b402cda0c8f6

容器卷的继承

通过--volumes-from 容器名或者ID可以实现容器之间的挂载继承。
是拷贝机制,abc三个容器,a挂载的本地路径,b挂载a,c挂载b,a被删除了,bc数据还在

  1. # 启动一个容器
  2. docker run -it --privileged=true /tmp/test:/tmp/docker --name c1 centos /bin/bash
  3. # 使用 --volumes-from 继承 u1的容器卷映射配置
  4. docker run -it --privileged=true --volumes-from c1 --name c2 centos

具名和匿名挂载

挂载目录路径的时候,在-v后面只写了一个容器内的路径,没有指定宿主机的路径,这就是匿名挂载。
可以通过docker volume来查看卷的情况
可以看到输出的卷的名字1f581adcdd4df8749da0971bfa19071a08635fc843ee7e2569843b509c74e315就是匿名挂载的nginx的卷名

  1. [root@izj6cev682kqg86i4ogj8rz ~]# docker run -d -p 3344:80 --name nginx03 -v /ect/nginx nginx
  2. 88e927ef258502d1596c72f43666640d203911490152128a6d3a6b26bea11d31
  3. [root@izj6cev682kqg86i4ogj8rz ~]# docker volume ls
  4. DRIVER VOLUME NAME
  5. local 1f581adcdd4df8749da0971bfa19071a08635fc843ee7e2569843b509c74e315
  6. [root@izj6cev682kqg86i4ogj8rz ~]#

当我们在-v后面指定了 名字:容器内路径,这就是具名挂载

  1. [root@izj6cev682kqg86i4ogj8rz ~]# docker run -d -P --name nginx04 -v nginx04test:/ect/nginx nginx
  2. 2457ed3d810b17ad1628de2ffe7a675e9b5652b672a6fb28b6a468f91aabf30e
  3. [root@izj6cev682kqg86i4ogj8rz ~]# docker volume ls
  4. DRIVER VOLUME NAME
  5. local 1f581adcdd4df8749da0971bfa19071a08635fc843ee7e2569843b509c74e315
  6. local nginx04test

通过docker volume inspect 卷名可以查看对应的卷挂载的目录。
/var/lib/docker目录下,所有的docker相关的东西默认都在这个目录下。
匿名和具名挂载的卷都在/var/lib/docker/volumes目录下。

  1. [root@izj6cev682kqg86i4ogj8rz ~]# docker volume inspect nginx04test
  2. [
  3. {
  4. "CreatedAt": "2022-06-01T14:44:02+08:00",
  5. "Driver": "local",
  6. "Labels": null,
  7. "Mountpoint": "/var/lib/docker/volumes/nginx04test/_data",
  8. "Name": "nginx04test",
  9. "Options": null,
  10. "Scope": "local"
  11. }
  12. ]
  13. [root@izj6cev682kqg86i4ogj8rz ~]# cd /var/lib/docker
  14. [root@izj6cev682kqg86i4ogj8rz docker]# ls
  15. buildkit containers image network overlay2 plugins runtimes swarm tmp trust volumes
  16. [root@izj6cev682kqg86i4ogj8rz docker]# cd /var/lib/docker/volumes
  17. [root@izj6cev682kqg86i4ogj8rz volumes]# ls
  18. 1f581adcdd4df8749da0971bfa19071a08635fc843ee7e2569843b509c74e315 backingFsBlockDev metadata.db nginx04test
  19. [root@izj6cev682kqg86i4ogj8rz volumes]#

具名,匿名,指定路径挂载区分

:::success

  • -v 容器内路径:匿名挂载
  • -v 卷名:容器内路径:具名挂载
  • -v /宿主机的绝对路径:容器内路径:指定路径挂载 :::