如何在 Ubuntu 14.04 上使用 Docker 数据卷
介绍
在本文中,我们将介绍 Docker 数据卷的概念:它们是什么、它们为什么有用、不同类型的卷、如何使用它们以及何时使用它们。我们还将介绍一些如何通过命令docker
行工具使用 Docker 卷的示例。
当我们读完本文时,您应该能够轻松创建和使用任何类型的 Docker 数据卷。
先决条件
要遵循本教程,您需要满足以下条件:
- Ubuntu 14.04 Droplet
- 具有 sudo 权限的非 root 用户(Ubuntu 14.04 的初始服务器设置解释了如何进行设置。)
- 按照如何在 Ubuntu 14.04 上安装和使用 Docker Compose第 1 步的说明安装 Docker
注意:尽管先决条件提供了在 Ubuntu 14.04 上安装 Docker 的说明,但docker
只要安装了 Docker,本文中有关 Docker 数据卷的命令也应该可以在其他操作系统上运行。
解释 Docker 容器
使用 Docker 需要了解相当多的 Docker 特定概念,而且大多数文档都侧重于解释如何使用 Docker 的工具集,而没有过多解释为什么要使用这些工具。如果您是 Docker 新手,这可能会让您感到困惑,因此我们将从一些基础知识开始,然后开始使用 Docker 容器。如果您以前使用过 Docker,只想知道如何开始使用数据卷,请直接跳到下一部分。
Docker 容器类似于虚拟机。它基本上允许您在容器内运行预先打包的“Linux 盒”。Docker 容器与典型虚拟机之间的主要区别在于,Docker 并不像普通虚拟机那样与周围环境完全隔离。Docker 容器与主机操作系统共享 Linux 内核,这意味着它不需要像虚拟机那样“启动”。
由于共享的内容如此之多,启动 Docker 容器是一种快速且廉价的操作——在大多数情况下,您可以在运行普通命令行程序所需的时间内启动一个完整的 Docker 容器(相当于普通虚拟机)。这很棒,因为它使部署复杂系统的过程变得更加容易和模块化,但它与通常的虚拟机方法不同,并且对于来自虚拟化世界的人来说有一些意想不到的副作用。
了解 Docker 数据卷的类型
Docker 数据卷主要有三种用例:
- 在删除容器时保留数据
- 在主机文件系统和 Docker 容器之间共享数据
- 与其他 Docker 容器共享数据
第三种情况稍微高级一些,因此我们不会在本教程中讨论它,但前两种情况很常见。
在第一种(也是最简单的)情况下,您只是希望即使删除了容器,数据仍然能够保留,因此最简单的方法通常是让 Docker 管理数据的存储位置。
保持数据持久
在 Docker 中无法直接创建“数据卷”,因此我们创建一个附加了卷的数据卷容器--volumes-from
。对于您想要连接到此数据卷容器的任何其他容器,请使用 Docker 的选项从此容器中获取卷并将其应用于当前容器。乍一看这有点不寻常,所以让我们通过一个简单的示例来说明如何使用这种方法使我们的byebye
文件即使容器被删除也能保留下来。
首先,创建一个新的数据卷容器来存储我们的卷:
docker create -v /tmp --name datacontainer ubuntu
datacontainer
这将根据ubuntu
图像并在目录中创建一个名为的容器/tmp
。
现在,如果我们使用该标志运行一个新的 Ubuntu 容器并像之前一样再次--volumes-from
运行bash
,那么我们写入/tmp
目录的任何内容都将保存到容器/tmp
的卷中datacontainer
。
首先,启动ubuntu
镜像:
docker run -t -i --volumes-from datacontainer ubuntu /bin/bash
命令-t
行选项从容器内部调用终端。该-i
标志使连接具有交互性。
在容器的 bash 提示符下ubuntu
,创建一个文件/tmp
:
echo "I'm not going anywhere" > /tmp/hi
继续输入exit
以返回主机的 shell。现在,再次运行相同的命令:
docker run -t -i --volumes-from datacontainer ubuntu /bin/bash
这次hi
文件已经存在了:
cat /tmp/hi
您应该看到:
Output of cat /tmp/hiI'm not going anywhere
您可以根据需要添加任意数量的--volumes-from
标志(例如,如果您想要组装一个使用来自多个数据容器的数据的容器)。您还可以根据需要创建任意数量的数据卷容器。
这种方法的唯一缺点是,您只能/tmp
在创建数据卷容器时选择容器内的挂载路径(在我们的示例中)。
在主机和 Docker 容器之间共享数据
Docker 容器的另一个常见用途是作为主机和 Docker 容器之间共享文件的一种方式。这与上一个示例的工作方式不同。无需先创建“仅数据”容器。您只需运行任何 Docker 映像的容器,并使用主机系统上目录的内容覆盖其中一个目录即可。
举一个简单的现实示例,假设您想使用官方 Docker Nginx 镜像,但又想保留 Nginx 日志文件的永久副本以供日后分析。默认情况下,nginx
Docker 镜像会记录到/var/log/nginx
目录,但该目录位于/var/log/nginx
Docker Nginx 容器内。通常无法从主机文件系统访问它。
让我们创建一个文件夹来存储我们的日志,然后使用共享卷运行 Nginx 映像的副本,以便 Nginx 将其日志写入我们主机的文件系统中而不是/var/log/nginx
容器内部:
mkdir ~/nginxlogs
然后启动容器:
docker run -d -v ~/nginxlogs:/var/log/nginx -p 5000:80 -i nginx
此run
命令与我们迄今为止使用的命令略有不同,因此让我们逐一分解它:
-
-v ~/nginxlogs:/var/log/nginx
— 我们设置了一个卷,将/var/log/nginx
Nginx 容器内部的目录链接到~/nginxlogs
主机上的目录。Docker 使用将:
主机的路径与容器路径分开,并且主机路径始终在前。 -
-d
— 分离进程并在后台运行。否则,我们只能看到一个空的 Nginx 提示符,并且除非我们关闭 Nginx,否则无法使用此终端。 -
-p 5000:80
— 设置端口转发。Nginx 容器默认监听端口 80,这会将 Nginx 容器的端口 80 映射到主机系统上的端口 5000。
如果您仔细观察,可能还会注意到与前面的run
命令还有另一个区别。到目前为止,我们在所有run
语句的末尾指定了一个命令(通常是/bin/bash
),以告诉 Docker 在容器内运行什么命令。由于 Nginx 镜像是官方 Docker 镜像,因此它遵循 Docker 最佳实践,并且镜像的创建者将镜像设置为运行命令以自动启动 Nginx。我们可以在这里放弃常规操作/bin/bash
,让镜像的创建者为我们选择在容器中运行什么命令。
因此,我们现在在我们的机器上的 Docker 容器内运行了一个 Nginx 副本,并且我们的主机端口 5000 直接映射到 Nginx 端口 80 的副本。让我们使用 curl 进行快速测试请求:
curl localhost:5000
您将从 Nginx 获得一整屏 HTML,显示 Nginx 已启动并正在运行。但更有趣的是,如果您查看~/nginxlogs
主机上的文件夹并查看文件,access.log
您将看到来自 Nginx 的一条日志消息,其中显示了我们的请求:
cat ~/nginxlogs/access.log
您将会看到类似以下内容:
Output of `cat ~/nginxlogs/access.log`172.17.42.1 - - [23/Oct/2015:05:22:51 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.35.0" "-"
如果您对文件夹进行任何更改~/nginxlogs
,您也可以实时地从 Docker 容器内部看到它们。
结论
总结一下!我们现在已经介绍了如何创建数据卷容器,我们可以使用这些卷来保存其他容器中的数据,以及如何在主机文件系统和 Docker 容器之间共享文件夹。这涵盖了 Docker 数据卷的所有用例,除了最先进的用例。
如果您使用 Docker Compose,则可以在文件中配置 Docker 数据卷docker-compose.yml
。有关详细信息,请参阅如何在 Ubuntu 14.04 上安装和使用 Docker Compose。
祝你好运并快乐地进行 Dockering!