如何在 Ubuntu 14.04 上使用 Docker 数据卷
介绍
在本文中,我们将介绍 Docker 数据卷的概念:它们是什么、为什么有用、不同类型的卷、如何使用它们以及何时使用它们。我们还将通过一些示例介绍如何通过 docker
命令行工具使用 Docker 卷。
到本文结束时,您应该能够轻松创建和使用任何类型的 Docker 数据卷。
先决条件
要学习本教程,您需要具备以下条件:
- Ubuntu 14.04 Droplet
- 具有 sudo 权限的非根用户(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 管理数据的存储位置通常是最简单的方法。
保持数据持久
无法在 Docker 中直接创建“数据卷”,因此我们创建了一个数据卷容器,并附加了一个卷。对于您随后想要连接到此数据的任何其他容器volume 容器,使用 Docker 的 --volumes-from
选项从这个容器中获取 volume 并将它们应用到当前容器。乍一看这有点不寻常,让我们来看一个简单的例子我们如何使用这种方法使我们的 byebye
文件即使在容器被移除的情况下仍然存在。
首先,创建一个新的数据卷容器来存储我们的卷:
docker create -v /tmp --name datacontainer ubuntu
这基于 ubuntu
图像和目录 /tmp
中创建了一个名为 datacontainer
的容器。
现在,如果我们使用 --volumes-from
标志运行一个新的 Ubuntu 容器,并像之前那样再次运行 bash
,我们写入 /tmp 的任何内容
目录将保存到 datacontainer
容器的 /tmp
卷中。
首先,启动 ubuntu
镜像:
docker run -t -i --volumes-from datacontainer ubuntu /bin/bash
-t
命令行选项从容器内部调用终端。 -i
标志使连接具有交互性。
在 ubuntu
容器的 bash 提示符下,在 /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
目录,但这是 Docker 内部的 /var/log/nginx
Nginx 容器。通常它不能从主机文件系统访问。
让我们创建一个文件夹来存储我们的日志,然后使用共享卷运行 Nginx 映像的副本,以便 Nginx 将其日志写入我们主机的文件系统而不是 /var/log/nginx
inside容器:
- mkdir ~/nginxlogs
然后启动容器:
- docker run -d -v ~/nginxlogs:/var/log/nginx -p 5000:80 -i nginx
这个 run
命令与我们目前使用的命令有点不同,所以让我们逐个分解它:
- <李>
-v ~/nginxlogs:/var/log/nginx
- 我们设置了一个卷,将 Nginx 容器内的 /var/log/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
放在这里,让镜像的创建者为我们选择在容器中运行的命令。
所以,我们现在有一个 Nginx 的副本在我们机器上的 Docker 容器内运行,我们主机的端口 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-compose.yml
文件中配置 Docker 数据卷。查看如何在 Ubuntu 14.04 上安装和使用 Docker Compose 了解详细信息。
祝你好运,Docker 快乐!