当一个Docker容器被摧毁时,在现有的Docker镜像上创建一个新的容器,不会对原始容器做任何改变。因此,当你摧毁一个容器并创建一个新的容器时,你会丢失数据。
为了避免丢失数据,Docker提供了卷和绑定挂载这两种机制,用于在Docker容器中持久保存数据。在本教程中,我们将研究卷和绑定挂载,然后再看一些例子和使用情况。
让我们开始吧!
绑定挂载
绑定挂载从Docker最早的时候就可以用于数据持久化。绑定挂载将把一个文件或目录从主机上挂载到你的容器上,然后你可以通过其绝对路径来引用。
要使用绑定挂载,该文件或目录不需要在你的Docker主机上已经存在。如果它不存在,它将被按需创建。绑定挂载依赖于主机的文件系统有一个特定的目录结构可用。你必须明确地创建一个文件或文件夹的路径来放置存储。
关于绑定挂载的另一个重要信息是,它们可以访问敏感文件。根据Docker文档,你可以通过在容器中运行的进程改变主机文件系统。这包括创建、修改和删除系统文件和目录,这可能有相当严重的安全影响。它甚至可能影响到非Docker进程。
开始使用绑定挂载
要在一个容器上使用绑定挂载,你要使用两个标志选项,--mount 和-v 。这两个选项之间最明显的区别是,--mount 更加粗略和明确,而-v 更是--mount 的速记。它将你传递给--mount 的所有选项合并为一个字段。
从表面上看,这两个命令都创建了一个PostgreSQL容器,并设置了一个卷来持久化数据。然而,在某些情况下,使用--mount 和-v 会有明显的不同。例如,当你在处理服务时,最好使用--mount ,因为你需要指定更多的选项,而不是用-v 。
通过运行--mount 标志来指定bind mount。
docker run --rm --name postgres-db -e POSTGRES_PASSWORD=password --mount type=bind,source="$pwd",target=/var/lib/postgresql/data -p 2000:5432 -d postgres
使用这段代码,用-v 标志来指定。
docker run --rm --name postgres-db -e POSTGRES_PASSWORD=password --v "$pwd":/var/lib/postgresql/data -p 2000:5432 -d postgres
注意,在这两种情况下,我们都指定$pwd ,工作目录,作为源。基本上,我们要告诉Docker在我们当前所在的目录中创建绑定挂载。
Docker卷
卷是在Docker容器中添加数据保存层的一个很好的机制,特别是在你需要在关闭容器后保存数据的情况下。
Docker卷完全由Docker本身处理,因此与你的目录结构和主机的操作系统无关。当你使用卷时,在主机上的Docker存储目录中会创建一个新的目录,而Docker会管理该目录的内容。
使用卷的好处
在Docker卷中,存储不与容器的生命周期相联系,而是存在于它的外部。这有很多好处。首先,你可以随心所欲地杀死你的容器,并且仍然保持你的数据。在多个容器中重复使用存储也很容易;例如,一个容器写到存储,而另一个容器从存储中读取。
由于卷不与任何容器绑定,你可以很容易地将它们同时附加到多个运行中的容器。你还会发现,卷不会增加使用它们的Docker容器的大小。最后,你可以使用Docker CLI来管理卷,例如,检索卷的列表或删除未使用的卷。
开始使用卷
现在,让我们看一个例子
假设你想创建一个PostgreSQL容器,而且你对持久化数据感兴趣。从$HOME/docker/volumes/postgres 中一个叫做postgres 的文件夹开始。
像绑定挂载一样,我们可以添加下面的代码,使用--mount 标志指定该卷。
docker run --rm --name postgres-db -e POSTGRES_PASSWORD=password --mount type=volume,source=$HOME/docker/volumes/postgres,target=/var/lib/postgresql/data -p 2000:5432 -d postgres
另外,这里是使用速记标志-v 的相同命令。
docker run --rm --name postgres-db -e POSTGRES_PASSWORD=password --v $HOME/docker/volumes/postgres:/var/lib/postgresql/data -p 2000:5432 -d postgres
如果你使用Mac或Linux,你必须将数据存储在$HOME/docker/volumes/ ,如果你在Windows上,则必须存储在C:\ProgramData\docker\volumes 。否则,Docker不会把你的数据作为一个卷来处理或管理。
使用案例
当决定何时使用卷或绑定挂载时,有几个重要因素需要考虑。如果你希望你的存储或持久层完全由Docker管理,并且只通过Docker容器和Docker CLI访问,你应该选择使用卷。
然而,如果你需要完全控制存储,并计划允许Docker以外的其他进程访问或修改存储层,那么绑定挂载就是正确的工具。
卷和绑定挂载的比较
根据Docker文档,使用卷是开始在Docker容器中持久化数据的最简单方法。总的来说,绑定挂载相比之下更为有限。
根据我们目前看到的情况,这一见解并不奇怪。一个好的经验法则是,如果你对在Docker容器中持久化数据的途径有疑问,就使用卷。
绑定挂载的一个关键区别是,绑定挂载可以被Docker以外的进程访问和修改。如前所述,当你想把Docker和其他进程整合在一起时,这可能是一个好处,但如果你担心安全问题,它也可能导致头痛。
总结
现在我们已经看到了卷和绑定挂载之间的核心区别,让我们回顾一下使卷成为Docker中持久化数据的推荐机制的一些优势。
首先,卷可以更安全地在容器之间共享;它们只能被指定在一个单一的目录中($HOME/docker/volumes ),并且完全由Docker本身管理。你也可以将卷存储在你的主机之外的远程主机或云供应商上。
你可以使用Docker CLI和Docker API来管理卷,而且你可以从容器中预先填充新卷的内容。此外,卷在Linux和Windows上都能工作,使它非常适合使用两种操作系统的团队。
在调查了卷和绑定挂载之后,我们发现卷在更多情况下是保存数据的更好选择。请务必在评论中告诉我你更喜欢哪种方法!
The postDocker volumes vs. bind mountsappeared first onLogRocket Blog.