1.概述
Docker容器用于在隔离的环境中运行应用程序。默认情况下,容器停止时,容器内的所有更改都将丢失。如果我们想在两次运行之间保留数据,那么Docker卷和绑定挂载会有所帮助。
在本教程中,我们将学习Docker Volumes以及如何管理它们并将其连接到容器。
2.什么是Docker Volume卷?
2.1。 Docker文件系统
docker容器运行镜像中定义的软件堆栈。镜像由一组在称为联合文件系统的文件系统上工作的只读层组成。当我们启动一个新容器时,Docker在映像层的顶部添加了一个可读写层,从而使该容器可以像在标准Linux文件系统上一样运行。
因此,容器内的任何文件更改都会在读写层中创建一个工作副本。但是,当容器停止或删除时,该读写层会丢失。
我们可以通过运行先写入然后读取文件的命令来进行尝试:
$ docker run bash:latest \
bash -c "echo hello > file.txt && cat file.txt"
结果是:
hello
但是,如果我们仅使用命令运行相同的镜像以输出文件的内容:
$ docker run bash:latest bash -c "cat file.txt"
cat: can't open 'file.txt': No such file or directory
容器的第二次运行在干净的文件系统上运行,因此找不到该文件。
2.2 Bind Mounts
Docker绑定挂载是从容器到主机上目录的高性能连接。它允许主机与容器共享其自己的文件系统,可以将其设置为只读或读写。
这使我们可以使用容器来运行我们不想在主机上安装的工具,但仍可以使用主机的文件。例如,如果我们想为特定脚本使用bash
的自定义版本,则可以在安装到当前工作目录的bash
容器中执行该脚本:
$ docker run -v $(pwd):/var/opt/project bash:latest \
bash -c "echo Hello > /var/opt/project/file.txt"
– v
选项可用于所有形式的挂载,并在这种情况下指定主机上的源– $(pwd)
输出中的工作目录–容器中的目标挂载点– /var/opt/project
。
运行此命令后,我们将在主机的工作目录中找到file.txt
。这是在Docker容器调用之间提供持久性文件的一种简单方法,尽管在容器代表主机工作时最有用。
一个很好的用例是在Docker中执行各种版本的语言构建工具,以避免在开发人员机器上发生冲突的安装。
我们应该注意,Windows bash shell有时需要$(pwd -W)
可以以bash shell的形式提供工作目录传递给Docker。
2.3。 Docker卷
绑定安装使用主机文件系统,但是**Docker卷是Docker固有的**。数据保存在连接到主机的存储中的某个位置(通常是本地文件系统)。卷本身的生命周期长于容器的生命周期,因此可以持续到不再需要为止。卷可以在容器之间共享。
在某些情况下,卷的形式不能由主机直接使用。
3.管理卷
Docker允许我们通过docker volume
命令集管理卷。我们可以给卷指定一个明确的名称(命名卷),或者允许Docker生成一个随机的卷(匿名卷)。
3.1。创建卷
我们可以通过使用create
子命令并传递一个名称作为参数来创建一个卷:
$ docker volume create data_volume
data_volume
如果未指定名称,则Docker会生成一个随机名称:
$ docker volume create
d7fb659f9b2f6c6fd7b2c796a47441fa77c8580a080e50fb0b1582c8f602ae2f
3.2。查看所有卷
ls
子命令显示了Docker已知的所有卷:
$ docker volume ls
DRIVER
VOLUME NAME
local
data_volume
local d7fb659f9b2f6c6fd7b2c796a47441fa77c8580a080e50fb0b1582c8f602ae2f
我们可以使用-f
或–filter
标志并传递key=value
参数进行过滤,以实现更高的精度:
$ docker volume ls -f name=data
DRIVER
VOLUME NAME
local
data_volume
3.3。检查卷
要显示一个或多个卷上的详细信息,我们使用inspect
子命令:
$ docker volume inspect ca808e6fd82590dd0858f8f2486d3fa5bdf7523ac61d525319742e892ef56f59
[
{
"CreatedAt": "2020-11-13T17:04:17Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/ca808e6fd82590dd0858f8f2486d3fa5bdf7523ac61d525319742e892ef56f59/_data",
"Name": "ca808e6fd82590dd0858f8f2486d3fa5bdf7523ac61d525319742e892ef56f59",
"Options": null,
"Scope": "local"
}
]
我们应该注意,该卷的Driver
描述了Docker主机如何定位该卷。例如,卷可以通过nfs放在远程存储中。在此示例中,该卷位于本地存储中。
3.4。删除卷
要分别删除一个或多个卷,我们可以使用rm
子命令:
$ docker volume rm data_volume
data_volume
3.5。删除卷及其数据
我们可以使用prune
子命令删除所有未使用的卷:
$ docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
data_volume
4.启动具有卷的容器
4.1。使用-v
正如我们在前面的示例中看到的,我们可以使用-v
选项通过绑定安装启动一个容器:
$ docker run -v $(pwd):/var/opt/project bash:latest \
bash -c "ls /var/opt/project"
此语法还支持装入卷:
$ docker run -v data-volume:/var/opt/project bash:latest \
bash -c "ls /var/opt/project"
由于我们的卷是空的,因此从挂载点开始没有列出任何内容。但是,如果我们要在一次容器调用期间写入卷:
$ docker run -v data-volume:/var/opt/project bash:latest \
bash -c "echo Baeldung > /var/opt/project/Baeldung.txt"
然后,我们随后使用装有该卷的容器,将可以访问文件:
$ docker run -v data-volume:/var/opt/project bash -c "ls /var/opt/project"
Baeldung.txt
-v
选项包含三个组成部分,以冒号分隔:
- 源目录或卷名
- 容器内的安装点
- (可选)
ro
如果安装是只读的)
4.2。使用–mount
选项
我们可能更喜欢使用更易解释的–mount
选项来指定我们要挂载的卷:
$ docker run --mount \
'type=volume,src=data-volume,\
dst=/var/opt/project,volume-driver=local,\
readonly' \
bash -c "ls /var/opt/project"
–mount
的输入是一串键值对,以逗号分隔。我们在这里设置:
-
type
–作为volume
以指示卷装入 -
src
–卷的名称,但是如果我们一直在进行绑定安装,则它可能是源目录 -
dst
–作为容器中的目标安装点 -
volume-driver
–在这种情况下是local
驱动程序 -
readonly
-使此挂载为只读;我们可以选择rw
进行读/写
我们应该注意,如果上面的命令尚不存在,它也会创建一个卷。
4.3。使用–volumes-from
共享卷
我们应该注意,将卷附加到容器会在容器和卷之间建立长期连接。即使容器已经退出,该关系仍然存在。这使我们可以使用已退出的容器作为模板,以将同一组卷安装到新的卷上。
假设我们在具有data-volume
装载的容器中运行了echo
脚本。稍后,我们可以列出我们使用过的所有容器:
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4920602f8048 bash "docker-entrypoint.s…" 7 minutes ago Exited (0) 7 minutes ago exciting_payne
通过复制此容器使用的卷,可以运行下一个容器:
$ docker run --volumes-from 4920 \
bash:latest \
bash -c "ls /var/opt/project"
Baeldung.txt
实际上, –volumes-from
通常用于链接正在运行的容器之间的卷。 Jenkins使用它在作为Docker容器运行的代理之间共享数据。
5.结论
在本文中,我们了解了Docker通常如何创建带有新文件系统的容器,但是绑定安装和卷如何允许在容器生命周期之外长期存储数据。
我们看到了如何列出和管理Docker卷,以及如何通过命令行将卷连接到正在运行的容器。
0 评论