赞
踩
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
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
接下来我们创建一个数据库
可以看到数据库的数据已经保存在了本地上
这样即使你的 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
我们可以查看一下这个数据卷的信息
可以看到默认情况,会挂载到本地的这个目录下
匿名挂载适用于临时存储或者不需要在多个容器之间共享的数据。例如,可以将日志文件、临时文件或其他容器产生的数据挂载到主机上的特定目录,以便于查看和处理。
需要注意的是,由于匿名挂载是直接指定主机上的路径,所以在不同主机上挂载相同路径的容器可能会导致冲突或数据不一致。因此,在使用匿名挂载时,需要确保主机路径的唯一性和正确性。
在使用 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 start
和 docker 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 的数据卷,二者达成共通
那么在多个相同的容器中,如果想要共享数据,使用数据卷容器,将容器作为一个父数据卷,其他容器来挂载到我这个父卷下,就可以实现共享了
可以再多增加几个容器进行测试,删除父容器查看其余子容器是否共通,自行测试即可,最后可以得出结论:
容器之间配置信息的传递,数据卷的生命周期会一直持续到没有容器使用它为止。
存储在本机的文件则会一直保留!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。