一、卷与持久化数据-简介¶
数据主要分为两类,持久化与非持久化
持久化数据是需要保存数据的,例如客户信息等;非持久化数据是不需要保存的哪些数据。
二、卷与持久化数据-详解¶
2.1 容器与非持久化数据¶
每个容器都被自动分配了本地存储。默认情况下,这是容器全部文件和文件系统保存的地方。非持久化存储属于容器的一部分,并且与容器的生命周期一致(容器创建时会创建非持久化存储,同时该存储也会随容器的删除而删除)。
在Linux系统中,该存储的目录在/var/lib/docker/<storage-driver>/之下,是容器的一部分。
默认情况下,容器的所有存储都使用本地存储。所以,默认情况下,容器全部目录都是用该存储。
2.2 容器与持久化数据¶
在容器中持久化数据推荐采用卷。
首先用户创建卷,然后创建容器,将卷挂载到容器上。卷会挂载到容器文件系统的某个目录之上,任何写到该目录下的内容都会写到卷中。即使容器被删除,卷与其上面的数据仍然存在。
默认情况下,Docker创建新卷时采用内置的local驱动。可用-d参数用于指定不同的驱动。使用local驱动创建的卷在Docker主机上均有其专属目录,在/var/lib/docker/volumes/myvol/_data/下(myvol为卷名)。
第三方驱动可以通过插件方式接入,这些驱动提供了高级存储特性,并为Docker集成了外部存储系统。
2.2.1 演示卷在容器和服务中的使用¶
1、执行以下命令创建一个新的独立容器,并挂载一个名为bizvol的卷。其中-it参数是用来告诉Docker开启容器的交互模式并将读者当前的Shell连接到容器终端,-d参数表示在后台运行容器并打印容器 ID
root@zq-virtual-machine:~# docker container run -dit --name voltainer --mount source=bizvol,target=/vol alpine
b4264c1ed7e81635dc2ded0fb2312a32515cb80e39d745e74dbcd22cfec0e4fc
2、执行docker container ls命令查看容器
root@zq-virtual-machine:~# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b4264c1ed7e8 alpine "/bin/sh" 27 seconds ago Up 24 seconds voltainer
3、执行docker volume ls命令查看卷是否创建成功,这里观察到,卷bizvol已成功创建。
root@zq-virtual-machine:~# docker volume ls
DRIVER VOLUME NAME
local bizvol
4、执行以下命令将Shell连接到一个运行中的容器终端,并创建一个名为file1的文件,写入Hello world内容后退出。其中-it参数是用来告诉Docker开启容器的交互模式并将读者当前的Shell连接到容器终端,sh代表是以sh方式进行连接。
root@zq-virtual-machine:~# docker container exec -it voltainer sh
/ # echo "Hello world" > /vol/file1
/ # ls -l /vol
total 4
-rw-r--r-- 1 root root 12 Nov 5 11:06 file1
/ # cat /vol/file1
Hello world
/ # exit
5、执行以下命令,这里观察到,虽然删除了容器。但是卷和数据仍然存在。
#删除容器
root@zq-virtual-machine:~# docker container rm voltainer -f
voltainer
#查看容器是否存在,这里观察到已删除
root@zq-virtual-machine:~# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#查看卷
root@zq-virtual-machine:~# docker volume ls
local bizvol
#查看卷数据
root@zq-virtual-machine:~# cat /var/lib/docker/volumes/bizvol/_data/file1
Hello world
6、执行以下命令创建一个名为hellcat的新服务,并将bizvol挂载到该服务器副本的/vol目录。
root@zq-virtual-machine:~# docker service create --name hellcat --mount source=bizvol,target=/vol alpine sleep1d
7、执行docker container ls命令获取副本容器ID
root@zq-virtual-machine:~# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
df6...a7b alpine "sleep 1d" Up 24 seconds hellcat.1.13
8、执行以下命令将Shell连接到一个运行中的容器终端,并查看file1文件内容。观察到,卷中保存了原始数据,并可以在新容器中进行使用。
root@zq-virtual-machine:~# docker container exec -it df6 sh
/ # cat /var/file1
Hello world
2.3 在集群节点间共享存储¶
Docker能够集成外部存储系统,使得集群间节点共享外部存储数据变得简单。一般应用于数据损坏。
数据损坏是如何产生的??? Node1上的容器A在共享卷中更新了部分数据。为了快速返回,数据实际写入了本地缓存而不是卷中。此时,容器A认为数据已经更新,但是Node1的容器A将缓存数据刷新并提交到卷前,Node2的容器B更新了相同部分的数据,但是值不同,并且更新方式为直接写入卷中。此时两个容器均认为自己已经将数据写入卷中,但实际上只有容器B写入了。容器A会在稍后将自己的缓存数据写入缓存,覆盖了Node2的容器B所做的一些变更。但是Node2上的容器B对此一无所知。
针对以上情况,在应用程序中进行控制。
三、卷与持久化数据-相关操作¶
3.1 创建卷¶
1、执行docker volume create myvol命令创建一个名为myvol的卷,-d参数用于指定不同的驱动。默认情况下,Docker创建新卷时采用内置的local驱动。
[root@localhost ~]# docker volume create myvol
myvol
2、执行docker volume ls命令查看创建的卷。
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local myvol
3.2 查看卷¶
1、执行docker volume ls命令简单查看卷
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local myvol
2、执行docker volume inspect myvol命令查看卷详情,这里观察到Driver和Scope都是local,说明卷默认使用local驱动创建,只能用于当前Docker主机上的容器。
[root@localhost ~]# docker volume inspect myvol
[
{
"CreatedAt": "2022-11-05T18:27:09+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/myvol/_data",
"Name": "myvol",
"Options": {},
"Scope": "local"
}
]
3.3 删除卷¶
3.3.1 删除未装入到某个容器或服务的全部卷¶
1、执行docker volume prune命令删除未装入到某个容器或服务的全部卷
[root@localhost ~]# docker volume prune
3.3.2 删除指定卷¶
1、执行docker volume rm myvol命令删除指定卷myvol
[root@localhost ~]# docker volume rm myvol
myvol
3.4 卷在容器中的应用¶
1、执行以下命令创建一个新的独立容器,并挂载一个名为bizvol的卷。其中-it参数是用来告诉Docker开启容器的交互模式并将读者当前的Shell连接到容器终端,-d参数表示在后台运行容器并打印容器 ID
root@zq-virtual-machine:~# docker container run -dit --name voltainer --mount source=bizvol,target=/vol alpine
b4264c1ed7e81635dc2ded0fb2312a32515cb80e39d745e74dbcd22cfec0e4fc
2、执行docker container ls命令查看容器
root@zq-virtual-machine:~# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b4264c1ed7e8 alpine "/bin/sh" 27 seconds ago Up 24 seconds voltainer
3、执行docker volume ls命令查看卷是否创建成功,这里观察到,卷bizvol已成功创建。
root@zq-virtual-machine:~# docker volume ls
DRIVER VOLUME NAME
local bizvol
4、执行以下命令将Shell连接到一个运行中的容器终端,并创建一个名为file1的文件,写入Hello world内容后退出。其中-it参数是用来告诉Docker开启容器的交互模式并将读者当前的Shell连接到容器终端,sh代表是以sh方式进行连接。
root@zq-virtual-machine:~# docker container exec -it voltainer sh
/ # echo "Hello world" > /vol/file1
/ # ls -l /vol
total 4
-rw-r--r-- 1 root root 12 Nov 5 11:06 file1
/ # cat /vol/file1
Hello world
/ # exit
5、执行以下命令,这里观察到,虽然删除了容器。但是卷和数据仍然存在。
#删除容器
root@zq-virtual-machine:~# docker container rm voltainer -f
voltainer
#查看容器是否存在,这里观察到已删除
root@zq-virtual-machine:~# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#查看卷
root@zq-virtual-machine:~# docker volume ls
local bizvol
#查看卷数据
root@zq-virtual-machine:~# cat /var/lib/docker/volumes/bizvol/_data/file1
Hello world
3.5 卷在服务中的应用¶
注意,以下操作在3.4基础上进行操作的!!! 1、执行以下命令创建一个名为hellcat的新服务,并将bizvol挂载到该服务器副本的/vol目录。
root@zq-virtual-machine:~# docker service create --name hellcat --mount source=bizvol,target=/vol alpine sleep1d
2、执行docker container ls命令获取副本容器ID
root@zq-virtual-machine:~# docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
df6...a7b alpine "sleep 1d" Up 24 seconds hellcat.1.13
3、执行以下命令将Shell连接到一个运行中的容器终端,并查看file1文件内容。观察到,卷中保存了原始数据,并可以在新容器中进行使用。
root@zq-virtual-machine:~# docker container exec -it df6 sh
/ # cat /var/file1
Hello world