容器数据持久化
说明
容器启动时,它使用镜像提供的文件和配置。每个容器都可以创建、修改和删除文件,并且不会影响其他容器。当容器被删除时,这些文件更改也会被删除。
虽然容器这种短暂的特性非常有用,但在需要持久化数据时会带来挑战。例如,如果你重启一个数据库容器,你可能不希望从一个空的数据库开始。那么,如何持久化文件呢?
容器卷
卷是一种存储机制,它提供了在单个容器生命周期之外持久化数据的能力。你可以将其视为从容器内部到容器外部的快捷方式或符号链接。
例如,假设你创建一个名为 log-data
的卷。
$ docker volume create log-data
使用以下命令启动容器时,该卷将挂载(或附加)到容器内的 /logs
目录。
$ docker run -d -p 80:80 -v log-data:/logs docker/welcome-to-docker
如果卷 log-data
不存在,Docker 会自动为你创建它。
容器运行时,写入 /logs
文件夹的所有文件将保存在此卷中,位于容器外部。如果你删除容器并使用相同的卷启动新容器,文件仍然会存在。
使用卷共享文件
你可以将同一个卷附加到多个容器,以在容器之间共享文件。这在日志聚合、数据管道或其他事件驱动型应用程序等场景中可能很有用。
管理卷
卷拥有自己的生命周期,独立于容器的生命周期,并且根据你使用的数据和应用程序类型,卷可能会变得相当大。以下命令有助于管理卷:
docker volume ls
- 列出所有卷docker volume rm <volume-name-or-id>
- 移除卷(仅在卷未附加到任何容器时有效)docker volume prune
- 移除所有未使用的(未附加的)卷
尝试一下
在本指南中,你将练习创建和使用卷来持久化 Postgres 容器创建的数据。数据库运行时,它会将文件存储到 /var/lib/postgresql/data
目录中。通过将卷附加到此处,你将能够在多次重启容器的同时保留数据。
使用卷
下载并安装 Docker Desktop。
使用以下命令启动一个容器,使用 Postgres 镜像
$ docker run --name=db -e POSTGRES_PASSWORD=secret -d -v postgres_data:/var/lib/postgresql/data postgres
这将在后台启动数据库,为其配置密码,并将卷附加到 PostgreSQL 将持久化数据库文件的目录。
使用以下命令连接到数据库:
$ docker exec -ti db psql -U postgres
在 PostgreSQL 命令行中,运行以下命令创建一个数据库表并插入两条记录:
CREATE TABLE tasks ( id SERIAL PRIMARY KEY, description VARCHAR(100) ); INSERT INTO tasks (description) VALUES ('Finish work'), ('Have fun');
在 PostgreSQL 命令行中运行以下命令,验证数据是否已在数据库中:
SELECT * FROM tasks;
你应该会看到如下所示的输出:
id | description ----+------------- 1 | Finish work 2 | Have fun (2 rows)
通过运行以下命令退出 PostgreSQL shell:
\q
停止并移除数据库容器。请记住,即使容器已被删除,数据仍会持久化在
postgres_data
卷中。$ docker stop db $ docker rm db
通过运行以下命令启动新容器,并附加带有持久化数据的同一个卷:
$ docker run --name=new-db -d -v postgres_data:/var/lib/postgresql/data postgres
你可能已经注意到,
POSTGRES_PASSWORD
环境变量已被省略。这是因为该变量仅在引导新的数据库时使用。通过运行以下命令,验证数据库是否仍然包含这些记录:
$ docker exec -ti new-db psql -U postgres -c "SELECT * FROM tasks"
查看卷内容
Docker Desktop 控制面板提供了查看任何卷内容的能力,以及导出、导入和克隆卷的能力。
打开 Docker Desktop 控制面板,导航到卷 (Volumes)视图。在该视图中,你应该能看到 postgres_data 卷。
选择 postgres_data 卷的名称。
数据 (Data) 选项卡显示卷的内容,并提供导航文件的能力。双击文件可以查看内容并进行更改。
右键单击任何文件即可保存或删除它。
移除卷
在移除卷之前,它不得附加到任何容器。如果你尚未移除之前的容器,请使用以下命令进行移除(-f
参数会先停止容器再移除它):
$ docker rm -f new-db
有几种方法可以移除卷,包括以下几种:
在 Docker Desktop 控制面板中,选择卷上的 删除卷 (Delete Volume) 选项。
使用
docker volume rm
命令$ docker volume rm postgres_data
使用
docker volume prune
命令移除所有未使用的卷$ docker volume prune
附加资源
以下资源将帮助你了解更多关于卷的信息:
下一步
既然你已经了解了容器数据持久化,接下来该学习如何与容器共享本地文件了。