docker持久化

本文介绍了Docker中如何实现数据持久化,通过容器的文件系统展示了容器内部更改的临时性,然后详细讲解了如何使用容器卷来持久化如SQLite数据库这样的应用数据,并通过实例演示了卷装载的创建和使用。此外,还解释了绑定挂载的概念,它是将主机目录共享给容器,实现实时代码同步和开发环境的理想选择,并给出了在Linux和Windows环境下使用绑定挂载的示例。
摘要由CSDN通过智能技术生成

docker持久化

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"

进入容器通过shell终端查看data.txt文件内容,之后关闭这个终端

cat data.txt

也可以通过docker命令来查看容器内的文件内容

# 查看容器内文件
docker exec <container-id> cat /data.txt

启动相同镜像的另一个容器,发现没有内容,这是因为文件只写入了第一个文件的暂存空间

docker run -it ubuntu ls /

2.容器卷

​ 在前面的案例中,我们看到每个容器在每次启动时都从镜像定义开始。虽然容器可以创建、更新和删除文件,但是当容器被删除时,这些更改将丢失,所有更改都与该容器隔离。通过卷,我们可以改变这一切。

​ 卷提供了将容器的特定文件系统路径连接回主机的能力。如果挂载了容器中的一个目录,则该目录中的更改也可以在主机上看到。如果我们跨容器重新启动挂载相同的目录,我们将看到相同的文件。

有两种主要的卷类型,我们最终将同时使用它们,但是我们将从卷装入开始。

1.保持 todo 数据

​ 默认情况下,todo 应用程序将其数据存储在容器的文件系统中的/etc/todos/todo.db 的 SQLite 数据库中。如果您不熟悉 SQLite,不用担心!它只是一个关系数据库,所有的数据都存储在一个文件中。虽然这不是最好的大型应用程序,但它适用于小型演示。稍后我们将讨论将其切换到另一个数据库引擎。

​ 由于数据库是一个单独的文件,如果我们可以在主机上持久存储该文件并使其可用于下一个容器,那么它应该能够从上一个容器停止的地方继续。通过创建卷并将其附加(通常称为“挂载”)到存储数据的目录,我们可以持久化数据。当我们的容器写入 todo.db 文件时,它将被持久化到卷中的主机。

​ 1.1正如前面提到的,我们将使用一个卷加载。可以将卷装入看作是一个不透明的数据桶。Docker 完全管理卷,包括卷存储在磁盘上的位置。您只需要记住卷的名称。

​ 通过docker volume create 命令创建

docker volume create todo-db

​ 1.2启动 todo app 容器,但是添加—— mount 选项来指定卷装入。我们将为卷命名,并将其挂载到容器中的/etc/todos,这将捕获在路径中创建的所有文件。

docker run -dp 3000:3000 --mount type=volume,src=todo-db,target=/etc/todos 1042798703/getting-started

​ 1.3容器启动之后,打开应用程序,并添加一些项目到您的待办事项列表。

Items added to todo list

​ 1.4 停止并删除 todo 应用程序的容器。使用 Dashboard 或 docker ps 获取 ID,然后 docker rm-f < ID > 删除它。

​ 1.5 使用上面的相同命令启动一个新容器。

​ 1.6 打开应用程序。您应该看到您的项目仍然在您的列表!

​ 1.7检查完列表后,继续移除容器。

现在,已经学会了如何持久化数据

2.深入研究卷

很多人经常问“当我使用卷时,Docker 在哪里存储我的数据?”如果您想知道,可以使用 docker 卷检查命令。

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 是存储数据的磁盘上的实际位置。请注意,在大多数机器上,您需要有根访问权限才能从主机访问这个目录。但是,它就在那里!

3.使用绑定挂载

​ 在上面,我们讨论并使用卷装载来保存数据库中的数据。当您需要在某个地方持久存储应用程序数据时,卷挂载是一个很好的选择。

​ 绑定挂载是另一种类型的挂载,它允许您将一个目录从主机的文件系统共享到容器中。在处理应用程序时,可以使用绑定挂载将源代码挂载到容器中。一旦保存文件,容器就会立即看到您对代码所做的更改。这意味着您可以在容器中运行进程,以监视文件系统的更改并对其作出响应。

两种挂载的区别

卷挂载 Named volumes绑定挂载 Bind mounts
主机位置docker选择你来选择
挂载示例(使用—— Mount)type=volume,src=my-volume,target=/usr/local/data``Type = volul,src = my-volul,target =/usr/local/datatype=bind,src=/path/to/data,target=/usr/local/data``Type = bind,src =/path/to/data,target =/usr/local/data
用容器内容填充新卷YesNo
支持卷驱动程序YesNo

下面让我们使用下绑定挂载

在研究如何使用绑定挂载来开发我们的应用程序之前,让我们运行一个快速的实验来实际了解绑定挂载是如何工作的。

1.打开一个终端,确保你当前的工作目录位于开始存储库的 app 目录中

2.运行以下命令在带绑定挂载的 ubuntu 容器中启动 bash。

docker run -it --mount type=bind,src="$(pwd)",target=/src ubuntu bash

--mount 选项告诉 Docker 创建一个绑定挂载,其中 src 是主机上的当前工作目录(getting-start/app) ,target 是该目录应该出现在容器(/src)中的位置。

3.运行该命令后,Docker 在容器文件系统的根目录中启动一个交互式 bash 会话。

root@ac1237fad8db:/# pwd
/
root@ac1237fad8db:/# ls
bin   dev  home  media  opt   root  sbin  srv  tmp  var
boot  etc  lib   mnt    proc  run   src   sys  usr

现在我们在容器/src中新增一个文件

root@ac1237fad8db:/src# touch myfile.txt
root@ac1237fad8db:/src# ls
Dockerfile  myfile.txt  node_modules  package.json  spec  src  yarn.lock

返回在宿主机可以看到

[root@VM-24-10-centos app]# ls
Dockerfile  myfile.txt  node_modules  package.json  spec  src  yarn.lock
[root@VM-24-10-centos app]#

4.从宿主机中删除 myfile.txt 文件。

5.进入容器查看文件,发现myflie.txt 文件也不存在了

root@ac1237fad8db:/src# ls
Dockerfile  node_modules  package.json  spec  src  yarn.lock
3.1实际操作

​ 1.下面的步骤说明如何运行具有绑定挂载的开发容器,该绑定挂载执行下列操作:

​ 2.安装所有依赖项

​ 3.启动 nodemon来监视文件系统的更改

  1. stop掉所有1042798703/getting-started相关容器

​ 在linux使用下面命令

docker run -dp 3000:3000 \
    -w /app --mount type=bind,src="$(pwd)",target=/app \
    node:18-alpine \
    sh -c "yarn install && yarn run dev"

如果使用 Windows,请在 PowerShell 中使用以下命令。

docker run -dp 3000:3000 `
    -w /app --mount type=bind,src="$(pwd)",target=/app `
    node:18-alpine `
    sh -c "yarn install && yarn run dev"
  • - dp 3000:3000-和之前一样。在分离(背景)模式下运行并创建一个端口映射

  • - w/app-设置命令运行的“工作目录”或工作目录

  • - mount type = bind,src = “ $(pwd)”,target =/app-bind 将工作目录从主机挂载到容器中的/app 目录中

  • Node: 18-alpine-要使用的镜像。注意,这是 Dockerfile 中我们应用程序的基础图像

您可以使用 docker 日志来查看日志,当您看到以下内容时,您将知道您已经准备好了:

docker logs -f <container-id>
nodemon src/index.js
[nodemon] 2.0.20
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] starting `node src/index.js`
Using sqlite database at /etc/todos/todo.db
Listening on port 3000

看完日志后,按 Ctrl + C 退出。

4.现在,更改应用程序。在 src/static/js/app.js 文件的第109行,将“ Add Item”按钮改为“ Add”:

- {submitting ? 'Adding...' : 'Add Item'}
+ {submitting ? 'Adding...' : 'Add'}

在浏览器中刷新页面,您应该会立即看到更改的反映。Node 服务器重新启动可能需要几秒钟。如果出现错误,请在几秒钟后尝试刷新。

Screenshot of updated label for Add button

你想做什么改变都可以。每次进行更改并保存文件时,noemon 进程都会自动重新启动容器中的应用程序。完成后,停止容器并使用以下方法构建新图像:

docker build -t getting-started .

刷新页面,您应该会立即看到更改的反映。Node 服务器重新启动可能需要几秒钟。如果出现错误,请在几秒钟后尝试刷新。

[外链图片转存中…(img-37t6ONR2-1676526270202)]

你想做什么改变都可以。每次进行更改并保存文件时,noemon 进程都会自动重新启动容器中的应用程序。完成后,停止容器并使用以下方法构建新图像:

docker build -t getting-started .
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值