容器数据卷

什么是容器数据卷

docker的理念回顾

将应用和运行的环境打包形成容器运行,运行可以伴随着容器,但是我们对于数据的要求,是希望能够持久化的!

就好比,你安装一个 MySQL,结果你把容器删了,就相当于删库跑路了,这TM也太扯了吧!

所以我们希望容器之间有可能可以共享数据,docker 容器产生的数据,如果不通过 docker commit 生成新的镜像,使得数据作为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了!这样是行不通的!

为了能保存数据在 docker 中我们就可以使用卷!让数据挂载到我们本地!这样数据就不会因为容器删除而丢失了

作用

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

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

特点

  • 持久性:容器数据卷可以在容器的生命周期中保留数据。即使容器被删除或重新创建,数据卷仍然存在,可以被其他容器继续使用。

  • 共享性:容器数据卷可以被多个容器同时挂载和使用,实现容器之间的数据共享。这样可以方便地实现容器间的数据传递和共享。

  • 独立性:容器数据卷是独立于容器的,它可以存在于容器之外。这意味着即使容器被删除,数据卷仍然保留在主机上,可以被其他容器或主机访问和使用。

所以:总结一句话: 就是容器的持久化,以及容器间的继承和数据共享

使用数据卷

可以使用docker volume create创建一个容器数据卷,也可以在执行docker run 容器时添加-v(等价于--volume)参数使用数据卷(推荐)

docker run -it -v 服务器目录:容器目录 镜像名或镜像id

首先删除所有镜像和容器进行测试

执行以下命令

docker run -it -v /home/test:/root/test centos /bin/bash

下载完毕后我们进入服务器的 home 目录下

[root@iZbp15293q8kgzhur7n6kvZ ~]# cd /home
[root@iZbp15293q8kgzhur7n6kvZ home]# ls
test

可以看到, home 目录下多了一个 test 目录

我们再进入到容器的 root 目录下

[root@e9667f583715 /]# cd /root
[root@e9667f583715 ~]# ls
anaconda-ks.cfg  anaconda-post.log  original-ks.cfg  test

可以看到同样多了一个 test 目录,这说明挂载了数据卷,自动创建对应的文件夹

接下来,在容器的 test 目录下创建一个文件

[root@e9667f583715 ~]# cd test/
[root@e9667f583715 test]# touch a.txt
[root@e9667f583715 test]# ls
a.txt

看一看服务器的 test 目录

[root@iZbp15293q8kgzhur7n6kvZ home]# cd test/
[root@iZbp15293q8kgzhur7n6kvZ test]# ls
a.txt

可以看到 test 目录下多了个 a.txt 文件

再在服务器的 test 目录下创建一个文件

[root@iZbp15293q8kgzhur7n6kvZ test]# touch b.txt
[root@iZbp15293q8kgzhur7n6kvZ test]# ls
a.txt  b.txt

看一看容器的 test 目录

[root@e9667f583715 test]# ls
a.txt  b.txt

可以看到 test 目录下多了 b.txt 文件,这说明两边的目录完全共通,都可以进行读写操作

可以查看一下容器的元数据,里面有一段:

"Mounts": [
    {
        "Type": "bind",
        "Source": "/home/test",
        "Destination": "/root/test",
        "Mode": "",
        "RW": true,
        "Propagation": "rprivate"
    }
],

删除容器

[root@iZbp15293q8kgzhur7n6kvZ ~]# docker rm -f e9667f583715

查看服务器的 test 目录下的数据还在不在?

[root@iZbp15293q8kgzhur7n6kvZ test]# ls
a.txt  b.txt

可以看到数据依然存在

重新运行一个容器进行挂载数据卷

[root@iZbp15293q8kgzhur7n6kvZ ~]# docker run -it -v /home/test:/root/test centos /bin/bash
[root@ba07c0614e65 /]# cd /root
[root@ba07c0614e65 ~]# ls
anaconda-ks.cfg  anaconda-post.log  original-ks.cfg  test
[root@ba07c0614e65 ~]# cd test/
[root@ba07c0614e65 test]# ls
a.txt  b.txt

可以看到数据没有丢失

安装 mysql 挂载数据卷

容器数据卷是非常适合于 mysql 的,通过将 mysql 的数据挂载到本地服务器上,即时 mysql 宕机了或者删除了,数据也不会丢失

使用以下命令安装 mysql

docker run -d -p 3306:3306 \
-v /home/mysql/conf:/etc/mysql/conf.d \
-v /home/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name mymysql \
mysql:5.7

安装完成后,进入服务器的 /home/mysql 目录下

[root@iZbp15293q8kgzhur7n6kvZ ~]# cd /home
[root@iZbp15293q8kgzhur7n6kvZ home]# cd mysql/
[root@iZbp15293q8kgzhur7n6kvZ mysql]# ls
conf  data

可以看到有 conf、data 两个目录,进入到 data 目录下

[root@iZbp15293q8kgzhur7n6kvZ mysql]# cd data/
[root@iZbp15293q8kgzhur7n6kvZ data]# ls
auto.cnf    ca.pem           client-key.pem  ibdata1      ib_logfile1  mysql               private_key.pem  server-cert.pem  sys
ca-key.pem  client-cert.pem  ib_buffer_pool  ib_logfile0  ibtmp1       performance_schema  public_key.pem   server-key.pem

可以看到跟我们在 windows 系统下安装的 mysql 目录一致

我们在外部使用 navicat 连接一下这个数据库

主机就是服务器的 ip 地址,密码为123456

docker入门(七)—— 容器数据卷介绍及使用-LMLPHP

接下来我们创建一个数据库

docker入门(七)—— 容器数据卷介绍及使用-LMLPHP

docker入门(七)—— 容器数据卷介绍及使用-LMLPHP

可以看到数据库的数据已经保存在了本地上

这样即使你的 mysql 容器宕机导致数据丢失了,本地的数据也不会消失

匿名挂载和具名挂载

匿名挂载

匿名挂载,顾名思义,在挂载数据卷时没有指定主机的挂载目录,-v后只有容器内路径

首先我们使用docker volume ls来查看已经拥有的数据卷

[root@iZbp15293q8kgzhur7n6kvZ test]# docker volume ls
DRIVER    VOLUME NAME
local     50e59a468588177437d3ab4d1a1831c74708d277495c96708d2b10735f6a9c9b
local     99f858f4eb9b980bc322c38e57124062fae4a7f0996e562b1fba62f651feea2d
local     bc66eca0b45126f5c4ebed6f5225825e2ded2877a1e3310b45f3333dce8a74c4

接下来我们使用匿名挂载创建一个容器

[root@iZbp15293q8kgzhur7n6kvZ test]# docker run -d --name newcentos -v /root/test centos
aba914f3fcb394acd6307eaff1a498c5e819d09c2910d6e4ad4649be14527704
[root@iZbp15293q8kgzhur7n6kvZ test]# docker volume ls
DRIVER    VOLUME NAME
local     50e59a468588177437d3ab4d1a1831c74708d277495c96708d2b10735f6a9c9b
local     99f858f4eb9b980bc322c38e57124062fae4a7f0996e562b1fba62f651feea2d
local     bc66eca0b45126f5c4ebed6f5225825e2ded2877a1e3310b45f3333dce8a74c4
local     d903842c735ce7543fbb8441cccdad41aff96943cfb2151a867dedbc8f13cad1

可以看到数据卷多了一个d903842c735ce7543fbb8441cccdad41aff96943cfb2151a867dedbc8f13cad1

我们可以查看一下这个数据卷的信息

docker入门(七)—— 容器数据卷介绍及使用-LMLPHP

可以看到默认情况,会挂载到本地的这个目录下

匿名挂载适用于临时存储或者不需要在多个容器之间共享的数据。例如,可以将日志文件、临时文件或其他容器产生的数据挂载到主机上的特定目录,以便于查看和处理。

需要注意的是,由于匿名挂载是直接指定主机上的路径,所以在不同主机上挂载相同路径的容器可能会导致冲突或数据不一致。因此,在使用匿名挂载时,需要确保主机路径的唯一性和正确性。

在使用 dockerfile 构建镜像时,通过 VOLUME 保留字挂载数据卷就是使用匿名挂载,不会出现忘记挂载目录而导致数据丢失的情况

具名挂载

具名挂载,顾名思义,就是在挂载数据卷时指定了数据卷的名字,为了可以在多个容器中共享重要的数据

[root@iZbp15293q8kgzhur7n6kvZ test]# docker run -d --name newcentos01 -v centosdir:/root/test centos
ee3c1fa72526f6d8e3983fc280389ff55cb53ecc3c7329cfcba347b03fa2768b
[root@iZbp15293q8kgzhur7n6kvZ test]# docker volume ls
DRIVER    VOLUME NAME
local     50e59a468588177437d3ab4d1a1831c74708d277495c96708d2b10735f6a9c9b
local     99f858f4eb9b980bc322c38e57124062fae4a7f0996e562b1fba62f651feea2d
local     bc66eca0b45126f5c4ebed6f5225825e2ded2877a1e3310b45f3333dce8a74c4
local     centosdir
local     d903842c735ce7543fbb8441cccdad41aff96943cfb2151a867dedbc8f13cad1

可以看到数据卷中多了一个名字为 centosdir 的数据卷,查看一下它的信息

[root@iZbp15293q8kgzhur7n6kvZ test]# docker volume inspect centosdir
[
    {
        "CreatedAt": "2024-03-20T18:17:12+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/centosdir/_data",
        "Name": "centosdir",
        "Options": null,
        "Scope": "local"
    }
]

具名挂载提供了一种方便和灵活的方式来管理容器的数据。它可以在多个容器之间共享和重用数据,使容器之间的数据交互更加简单和高效。同时,具名挂载由 docker 自动管理,减轻了手动管理数据的负担。

数据卷容器

容器数据卷:容器的持久化

数据卷容器:容器,当做一个持久化的卷。

数据卷容器(Data Volume Container)是一种在 docker 中用于管理和共享数据的特殊容器。它是一种轻量级的容器,主要用于创建和管理数据卷,而不运行实际的应用程序。

数据卷容器的工作原理如下:

  • 创建数据卷容器:首先,创建一个专门用于管理数据的容器,称为数据卷容器。可以使用 docker create 命令创建一个数据卷容器。
  • 挂载数据卷:然后,在其他容器中使用 --volumes-from 参数来挂载数据卷容器中的数据卷。这样,其他容器就可以访问和共享数据卷容器中的数据。
  • 管理数据卷:数据卷容器可以使用 docker run 命令启动和停止,或者使用 docker startdocker stop 命令进行管理。通过管理数据卷容器,可以管理和保持数据卷的持久性。

数据卷容器的主要优点如下:

  • 数据共享:数据卷容器允许多个容器访问和共享相同的数据卷。它提供了一种简单且可靠的方式来管理和共享数据。
  • 数据持久性:通过使用数据卷容器,数据卷的生命周期不再依赖于任何特定的容器。即使容器被删除或重新创建,数据卷仍然存在。
  • 简化管理:通过将数据卷的管理和持久性交给数据卷容器,可以简化数据的管理和维护。容器的启动和停止不会影响数据卷的存在。
  • 数据版本控制:数据卷容器可以用于管理和保存不同版本的数据。通过创建不同的数据卷容器,可以保存不同时间点的数据快照。

需要注意的是,数据卷容器是一种较早的数据管理方法,现在也有更灵活的数据管理方式,如使用具名挂载(Named Volume)或使用 docker 卷插件。这些方法提供了更多的功能和性能,因此在选择数据管理方式时需要根据实际需求进行选择。

接下来进行测试:

首先删除所有的数据卷和容器

# 删除所有数据卷命令
docker volume rm $(docker volume ls -q)
[root@iZbp15293q8kgzhur7n6kvZ test]# docker volume rm $(docker volume ls -q)
50e59a468588177437d3ab4d1a1831c74708d277495c96708d2b10735f6a9c9b
99f858f4eb9b980bc322c38e57124062fae4a7f0996e562b1fba62f651feea2d
bc66eca0b45126f5c4ebed6f5225825e2ded2877a1e3310b45f3333dce8a74c4
centosdir
d903842c735ce7543fbb8441cccdad41aff96943cfb2151a867dedbc8f13cad1
[root@iZbp15293q8kgzhur7n6kvZ test]# docker volume ls
DRIVER    VOLUME NAME

运行容器 centos01,使用匿名挂载

[root@iZbp15293q8kgzhur7n6kvZ data]# docker run -it --name centos01 -v /root/test centos
[root@5ee3e5785b46 /]# cd /root
[root@5ee3e5785b46 ~]# ls -l
total 16
-rw------- 1 root root 2361 Sep 15  2021 anaconda-ks.cfg
-rw-r--r-- 1 root root  608 Sep 15  2021 anaconda-post.log
-rw------- 1 root root 2059 Sep 15  2021 original-ks.cfg
drwxr-xr-x 2 root root 4096 Mar 20 10:36 test

查看所有数据卷

[root@iZbp15293q8kgzhur7n6kvZ test]# docker volume ls
DRIVER    VOLUME NAME
local     f844ece6524ca50f313ac5065f70f24900a624a22ae167edb3b23934f476e0c2

接下来,运行容器 centos02,使用 --volumes-from 挂载 centos01 的数据卷

[root@iZbp15293q8kgzhur7n6kvZ ~]# docker run -it --name centos02 --volumes-from centos01 centos
[root@3a0633d18652 /]# cd /root
[root@3a0633d18652 ~]# ls -l
total 16
-rw------- 1 root root 2361 Sep 15  2021 anaconda-ks.cfg
-rw-r--r-- 1 root root  608 Sep 15  2021 anaconda-post.log
-rw------- 1 root root 2059 Sep 15  2021 original-ks.cfg
drwxr-xr-x 2 root root 4096 Mar 20 10:36 test

可以看到 centos02 中也存在 test 目录

再次查看所有数据卷

[root@iZbp15293q8kgzhur7n6kvZ test]# docker volume ls
DRIVER    VOLUME NAME
local     f844ece6524ca50f313ac5065f70f24900a624a22ae167edb3b23934f476e0c2

发现数据卷没有增加

这时候在 centos01 和 centos02 的 test 目录下进行测试,发现二者是完全共通的,这就是数据卷容器,类似于 java 中的继承,这里是 centos02 继承了 centos01 的数据卷,二者达成共通

那么在多个相同的容器中,如果想要共享数据,使用数据卷容器,将容器作为一个父数据卷,其他容器来挂载到我这个父卷下,就可以实现共享了

可以再多增加几个容器进行测试,删除父容器查看其余子容器是否共通,自行测试即可,最后可以得出结论:

容器之间配置信息的传递,数据卷的生命周期会一直持续到没有容器使用它为止

存储在本机的文件则会一直保留

03-21 12:57