3.5 持久化数据库
您是否注意到,每次我们启动容器时,我们的待办事项列表都会被清除干净。为什么是这样?让我们深入了解容器的工作原理。
容器的文件系统
当容器运行时,它使用镜像中的各个层作为其文件系统。每个容器也有自己的“暂存空间”来创建/更新/删除文件。任何更改都不会在另一个容器中看到,即使它们使用的是相同的镜像。
在实践中观察
为查看实际效果,我们将启动两个容器并在每个容器中创建一个文件。您将看到在一个容器中创建的文件在另一个容器中不可用。
-
启动一个
ubuntu
容器,该容器将创建/data.txt文件,写入1 到 10000 之间的随机数。$ docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"
如果您对命令感到好奇,我们将启动一个 bash shell 并调用两个命令(为什么我们有
&&
)。第一部分选择一个随机数并将其写入/data.txt
. 第二个命令只是监视文件以保持容器运行。 -
通过访问容器中的终端验证您是否可以看到输出。为此,请转到Docker Desktop 中的容器,将鼠标悬停在运行ubuntu镜像的容器上,然后选择显示容器操作菜单。从下拉菜单中,选择Open in terminal。
您将在 ubuntu 容器中看到一个运行 shell 的终端。运行以下命令以查看
/data.txt
文件的内容。之后再次关闭此终端。$ cat /data.txt
如果你更喜欢命令行,你可以使用
docker exec
命令来做同样的事情。您需要获取容器的 ID(用于docker ps
获取它)并使用以下命令获取内容。$ docker exec <container-id> cat /data.txt
你应该看到一个随机数!
-
现在,让我们启动另一个
ubuntu
容器(相同的镜像),我们将看到我们没有相同的文件。$ docker run -it ubuntu ls /
看!那里没有
data.txt
文件!那是因为它只写入了第一个容器的暂存空间。 -
继续并使用
docker rm -f <container-id>
命令删除第一个容器。
容器数据卷
通过前面的实验,我们看到每个容器每次启动时都是从镜像定义开始的。虽然容器可以创建、更新和删除文件,但当容器被移除并且所有更改都隔离到该容器时,这些更改将丢失。有了数据卷,我们可以改变这一切。
数据卷提供了将容器的特定文件系统路径连接回主机的能力。如果挂载了容器中的目录,则该目录中的更改也会在主机上看到。如果我们在容器重新启动时挂载相同的目录,我们会看到相同的文件。
有两种主要类型的数据卷。我们最终会同时使用两者,但我们将从命名数据卷开始。
持久化待办事项数据
默认情况下,待办事项应用程序将其数据存储在容器文件系统中的SQLite 数据库中的/etc/todos/todo.db
,如果您不熟悉 SQLite,不用担心!它只是一个关系数据库,其中所有数据都存储在一个文件中。虽然这不是大型应用程序的最佳选择,但它适用于小型演示。稍后我们将讨论将其切换到不同的数据库引擎。
由于数据库是单个文件,如果我们可以将该文件持久保存在主机上并使其可供下一个容器使用,它应该能够从上一个容器停止的地方继续。通过创建一个数据卷并将其附加(通常称为“挂载”)到数据存储的目录,我们可以持久化数据。当我们的容器写入todo.db
文件时,它将持久化数据卷到主机中。
如前所述,我们将使用命名卷。将命名卷简单地视为数据桶。Docker 维护磁盘上的物理位置,您只需要记住卷的名称。每次使用卷时,Docker 都会确保提供正确的数据。
-
使用
docker volume create
命令创建卷。$ docker volume create todo-db
-
在 Dashboard(或使用
docker rm -f <id>
)中再次停止并删除待办事项应用程序容器,因为它仍在运行而不使用持久卷。 -
启动 todo 应用程序容器,但添加
-v
标志以指定卷安装。我们将使用命名卷并将其挂载到/etc/todos
,这将捕获在该路径创建的所有文件。$ docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
-
容器启动后,打开应用程序并将一些项目添加到待办事项列表中。
-
停止并删除待办事项应用程序的容器。使用仪表板或
docker ps
获取 ID,然后docker rm -f <id>
将其删除。 -
使用上面的相同命令启动一个新容器。
-
打开应用程序。您应该会看到您的项目仍在您的列表中!
-
检查完列表后,继续并移除容器。
万岁!您现在已经了解了如何持久化数据!
笔记
虽然命名卷和绑定挂载(我们将在一分钟内讨论)是默认 Docker 引擎安装支持的两种主要类型的数据卷,但有许多数据卷驱动程序插件可用于支持 NFS、SFTP、NetApp 等!一旦您开始在使用 Swarm、Kubernetes 等的集群环境中的多个主机上运行容器,这一点将尤为重要。
深入数据卷
很多人经常问“当我使用命名卷时, Docker实际上将我的数据存储在哪里?” 如果你想知道,你可以使用docker volume inspect
命令。
$ docker volume inspect todo-db
[
{
"CreatedAt": "2022-11-16T02:18:36Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
"Name": "todo-db",
"Options": {},
"Scope": "local"
}
]
Mountpoint
是磁盘上存储数据的实际位置。请注意,在大多数机器上,您需要具有根访问权限才能从主机访问此目录。但是,那就是它所在的地方!
直接在 Docker Desktop 上访问数据卷数据
在 Docker Desktop 中运行时,Docker 命令实际上是在您机器上的小型 VM 中运行。如果您想查看 Mountpoint 目录的实际内容,您需要先进入 VM 内部。
个人写的小程序,有需求的可以看看:
全网热门头像馆
热门头像|个性头像|高清头像|性感壁纸|美女壁纸|炫酷壁纸|省电壁纸|唯美壁纸
海量资源 应用尽有 免费下载