跳到主要内容

持久化到数据库

原页面

容器的文件系统

当一个容器运行的时候,他会使用镜像所来带的各种层作为自己的文件系统。每个容器也有属于自己的暂存空间来创建、更新、删除文件。

实践

在实践中,我们将启动两个容器,并单独地给他们创建一个文件。你将会看到一个容器中创建的文件不会在另一个容器中看到。

  1. 启动一个 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 后会执行两条命令。第一个是选取一个随机数写入到 /data.txt 中。第二条命令是用来实时查看这个文件,来让这个容器保持运行的状态之中。

  2. 在 Dashboard 中点击容器对应的第一个行为,来查看容器的输出。

    你将会看到一个该 ubuntu 容器的终端。执行下面的命令来查看 /data.txt 的内容。

    cat /data.txt

    如果想用命令行来执行以上操作的话,可以使用 docker exec 命令。你需要容器的 ID (通过使用 docker ps 获取)。

    docker exec <container-id> cat /data.txt

    然后你应该会看到一个随机的数字。

  3. 接着,启动另一个 ubuntu 容器(使用同一个镜像),我们会发现容器中没有刚才的文件。

    docker run -it ubuntu ls /
  4. 使用 docker rm -f 将第一个容器移除。

容器挂载卷 Container Volumes

从上面的实践中发现,容器中文件的变化是相对独立的,但我们可以使用挂载卷来避开这一属性。

挂载卷提供了容器中指定的文件系统与主机相连接的特性。如果一个目录在容器中被挂载了,那么目录中的变化在主机中也是可见的。如果我们挂载同一目录来重启容器,我们会在容器中看到相同的文件。

有两种挂载卷,首先我们使用命名挂载

持久化我们的待办数据

由于数据库是单个文件,如果我们能将这个文件保留在主机中并且能够在下一个容器中使用,则它应该知道上一次该文件放在那儿并获取它。通过创建一个挂载卷并挂载存储数据所在的目录,我们就能持久化数据。因为我们的容器在 todo.db 文件中写入,我们应当将它挂载在主机中。

我们将会使用命名挂载,docker 会保留磁盘中的物理路径,同时你只需记得挂载卷的名称即可。

  1. 创建一个挂载卷,通过使用 docker volume create 命令。
    docker volume create todo-db
  2. 在 Dashboard 中停止我们的待办应用容器(或者使用 docker rm -f <id>)。
  3. 启动我们的待办应用,但这次我们加上 -v 修饰符来明确挂载一个卷。我们将使用一个命名卷来挂载到 /etc/todos 中,这个路径会捕捉所有文件。
    docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
  4. 一旦容器运行了,我们打开应用然后在待办中添加一些事件。
  5. 移除该容器。使用 Dashboard ,或者是使用 docker ps 来获取容器 ID ,然后用 docker rm -f <id> 来移除。
  6. 用刚才相同的命令来启动一个新的容器。
  7. 我们打开应用,发现事件仍然在待办列表中。
  8. 完成后就把容器移除吧。

尽管命名挂载和绑定挂载(稍后会讨论)是 Docker 提供的两种主要的挂载卷类型,但还有许多用来支持 NFS、SFTP、NetApp 等的挂载卷驱动插件可用。一旦开始在具有Swarm,Kubernetes等集群环境中的多个主机上运行容器,这将尤其重要。

深入了解挂载卷

如果你想知道命名挂载存放数据的实际位置,可以使用 docker volume inspect 命令。

docker volume inspect todo-db
[
{
"CreatedAt": "2019-09-26T02:18:36Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/todo-db/_data",
"Name": "todo-db",
"Options": {},
"Scope": "local"
}
]

其中,Mountpoint 就是我们实际的数据存储位置。

在 Docker Desktop 中运行时,Docker 命令实际上在计算机上的小型VM内运行。 如果要查看 Mountpoint 目录的实际内容,则需要首先进入 VM 。