Docker——Docker介绍——第一章
Docker——Docker运行底层原理和为什么Docker比Vm快——小知识
Docker——Docker命令——工作最常用——第二章
Docker——镜像介绍——第三章
Docker——容器数据卷——第四章
Docker——DockerFile——第五章
文章目录
本章介绍了Docker存储卷以及容器之间如何管理数据的方法。
就像在容器中运行一个数据库程序一样, 你可以将这个软件打包在镜像中,当启动容器时,它将会初始化一个空数据库。当其他程序接入该数据库并存入数据,这些数据要如何才能保存下来呢?是以容器中一个文件的形式吗?当你暂停一个 容器或者删除这个容器,这些数据要怎么办?如果你想要升级数据库程序,这些数据怎么搬迁?
考虑一下另一种情况,一组不同的web应用程序运行在在不同的容器中。为了让它们的日志文件保存在容器之外,你准备把它们写到哪儿去呢?你将如何取得这些日志来排除故障呢?如何让其他程序(比如日志摘要工具)来访问这些文件呢?这些问题的答案就涉及存储卷的使用。
1:存储卷简介
一个 主机或容器的目录树是由一组挂载点创建而成,这些挂载点描述了如何能构建出一个或多 个文件系统。存储卷是容器目录树上的挂载点,其中一部分主机目录树已经被挂载了。
如果没有存储卷,Docker 用户会受限于Union文件系统,仅提供镜像挂载。如图4-1所示容器中运行着的一个程序, 正写数据到文件中。第一个文件写入到了根文件系统。操作系统控制根文件系统将改变的部分装入Union文件系统的顶层。第二个文件则写入到已经挂载于容器目录树/data中。改动会通过存储卷直接影响到主机文件系统上。
虽然Union文件系统适用于构建和分享镜像,但对持久化或共享数据而言,并不是理想的方法。存储卷填补了这些用例,并在容器化系统设计中发挥了关键作用。
1.1 存储卷提供容器无关的数据管理方式
从语义上来说,存储卷是一个数据分割和共享的工具, 有一个与容器无关的范围或生命周期。这使得存储卷成为了容器化系统设计中关于文件分享或写入最重要的一部分。数据示例根据其范围或者接入容器方式的不同,分成以下几种:
数据库软件与数据库中的数据
web应用程序与日志数据
web数据处理应用程序的输入和输出数据
web服务器与静态内容
产品与支持工具
存储卷可分离关注点,并为架构组件创建模块化。这种模块化设计帮助你更轻松地了解、构建、支持和重用大型系统的部件。
按以下方式来思考:镜像适合打包和分发相对静态的文件,如程序;存储卷则持有动态或专门数据。这种区别使得镜像可重用,数据也可以简单分享。这种相对静态和动态文件空间的分离,允许应用程序或镜像的作者,实现高级模式,例如多态和可组合工具。
多态工具维护一致的接口,但可能有多种实现,分别做不同的事情。考虑这样一个应用程序,如一个通用的应用服务器。例如,Apache Tomcat,在网上提供了一个HTTP接口并分发其接收到的任何请求给可插拔的各类程序。因此Tomcat具有多态行为。使用存储卷可以将其行为配置插入到容器中,而无须修改镜像。另外,考虑MongoDB或MySQL这样的数据库。数据库的值由其包含的数据所定义。数据库程序总呈现相同的接口,但其值则完全不同,这取决于插入卷的数据。
更为基本的是,存储卷可以隔离应用程序和主机的关系。镜像被装载到主机,创建出一个容器。Docker 不知道主机在哪里运行,只能判断哪些文件在容器中可用。这意味着Docker本身就没有办法利用主机上的设施,如装载的网络存储,或混合光纤和固态硬盘。但有主机知识的用户可以使用存储卷,在容器中将这些目录映射到主机的存储上。
2:存储卷的类型
存储卷有两种类型。每一个存储卷就是容器目录树的挂载点在主机目录树中的位置,但不同的存储卷类型在主机的位置是不同的。第一种类型是绑定挂载存储卷。绑定挂载存储卷使用用户提供的主机目录或文件。第二类型是管理存储卷。管理存储卷使用由Docker守护进程控制的位置,被称为Docker管理空间。存储卷类型如图4-3所示。
每种存储卷类型都有优缺点,根据情况使用
2.1 绑定挂载卷
绑定挂载卷是一种存储卷,指向主机文件系统上用户指定的位置。绑定挂载卷在主机提供的文件或目录需要挂载到容器目录的特点位置,非常有用,如图4.4
如果你想将数据分享给运行在容器外的进程,比如主机系统组件,绑定挂载卷是很有用的。如果你想将主机数据通过已知的主机目录分享给容器中运行的特定程序,绑定挂载卷也管用。示例如下
在这个示例中,你使用了-v选项和位置映射来创建绑定挂载卷。该映射以冒号分隔(这是Linux命令行工具的常见风格)。映射键(冒号之前的路径)是主机文件系统上的一个绝对路径,该键值(冒号后的路径)是容器中挂载的目标存储位置。你必须使用绝对路径指定该位置。
Docker提供了一种机制将挂载卷和存储卷设为只读权限。你可以通过在存储卷映射规则后追加: ro 来完成。例如,你应该会修改run命令:如下
通过挂载只读卷,可以避免容器内的任何进程修改该卷的内容。
-
绑定挂载卷并不仅限于目录,但目录是它们常用的方式。你可以使用绑定挂载卷装入单个文件。在创建或链接资源时,避免了与其他资源的冲突,提供了灵活性。考虑一下当你要安装一一个特定的文件到一一个包含其他文件的目录。具体而言,假设你只想在镜像分发的web内容外添加一个额外的文件。如果你用一整个目录绑定挂载到该位置,那么其他文件都将丢失。通过使用一个特定的文件作为存储卷,可以只覆盖或插入单个文件。
-
在这种情况下,需要注意的重点是,文件必须在创建容器之前就存在于主机上。否则Docker会认为你想用一个目录,并在主机上创建它,把它挂载在需要的位置(即使该位置由另一个文件占用)。
-
使用绑定挂载卷的第一个问题是是它们将可移植容器绑定到特定主机的文件系统。如果容器的定义取决于主机文件系统特定位置上的内容,无论所在位置的内容可用或不可用,该定义无法跨主机移植。
-
第二个问题是,创造了与其他容器发生冲突的机会。启动Cassandra的多个实例,都使用相同的主机位置挂载存储卷,这将是一一个糟糕的主意。在这种情况下,每个实例将竞争相同的一 组文件。如果没有其他工具,比如文件锁定,这将有可能导致数据库损坏。
-
绑定挂载卷比较适合需要使用特殊挂载点的工作站或机器。最好在通用平台或硬件池避免这类特定的绑定。你可以使用Docker管理卷,以与主机无关和便携的方式利用该存储卷。
2.2 Docker管理卷
管理卷不同于绑定挂载卷,这是因为Docker守护程序会在主机文件系统中创建存储卷,并由Docker管理,如图4-5所示
使用管理卷是一种在文件系统特定位置解耦卷的方法。当你执行dockerrun使用-v选项(或–volume),只要指定容器目录树中的挂载点,管理卷即可创建。
3:共享存储卷
3.1 主机依赖的共享
假设你有一个跑在容器中的web服务器,所有接收到的请求都记录在/logs/access.如果要将这些日志从你的web服务器转移到持久化存储上,你可能会想通过另一个容器中的脚本来做到。这时候容器间的卷分享的价值就更加明显。正如有两种类型的存储卷,这儿也有两种方法来共享容器之间的存储卷。
在这个示例中,你创建了两个容器:一个名为plath的容器写文件,另一个则读该文件。这些容器都有一个共同的绑定挂载卷。容器之外,你可以通过列出目录中的内容或查看新的文件来观察这些变化。
探索一下容器可能以这种方式连接在一起。接下来的示例启动四个容器,两个日志写入者和两个读取者:
在这个示例中,你创建了四个容器,每一个都有绑定挂载卷。前两个容器写入到卷的不同文件中。第三和第四个容器则在不同的位置挂载卷,并作为只读。这是一个玩具示例,但它清楚地展示了一个功能,即有多种方法可构建镜像和软件。
主机依赖的共享要求你使用绑定挂载卷,如果你有大量的机器,主机依赖的共享可能会导致问题或维护起来过于昂贵。
4:容器内添加数据卷的两种方式
4.1 直接命令添加
第一步:执行命令添加数据卷
& docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
如下
& docker run -it -v /宿主机绝对路径目录:/容器内目录 --privilege=true 镜像名
我们可以查看数据是否挂载成功
我们调用如下命令,查看容器数据卷是否挂载成功
# 查看容器内部细节
docker inspect
实现挂载成功后,我们可以实现容器和宿主之间的数据共享,容器停止退出后,主机修改后数据实现同步
4.2 DockerFile添加
根据如下步骤进行
Dockefile文件中的内容如下
对Dockefile文件的解释
出现如下图,说明build构建成功
5:数据卷容器
根据以下步骤,自己动手做一变