容器是当今 IT 运营的关键部分。容器映像包含一个打包的应用程序,以及它的依赖项,以及它在启动时运行的进程的信息。

您可以通过提供一组特殊格式的指令来创建容器映像,这些指令可以作为对注册表的提交,也可以作为 Dockerfile。例如,这个 Dockerfile 为 PHP Web 应用程序创建了一个容器:

FROM registry.access.redhat.com/ubi8/ubi:8.1

运行 yum --disableplugin\u003dsubscription-manager -y module enable php:7.3 \

&& yum --disableplugin\u003d订阅管理器 -y 安装 httpd php \

&& yum --disableplugin\u003dsubscription-manager clean all

添加 index.php /var/www/html

运行 sed -i 's/Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf \

&& sed -i 's/listen.acl_users u003d apache,nginx/listen.acl_users u003d/' /etc/php-fpm.d/www.conf \

&& mkdir /run/php-fpm \

&& chgrp -R 0 /var/log/httpd /var/run/httpd /run/php-fpm \

&& chmod -R g\u003du /var/log/httpd /var/run/httpd /run/php-fpm

曝光 8080

用户 1001

CMD php-fpm & httpd -D 前景

此文件中的每条指令都会向容器映像添加一个 layer。每一层只添加与它下面的层的差异,然后,所有这些层堆叠在一起,形成一个只读的容器镜像。

它是如何工作的?

你需要了解一些关于容器镜像的知识,并且按顺序理解这些概念很重要:

1.联合文件系统

  1. 写时复制

  2. 覆盖文件系统

  3. 快照

联合文件系统 (Aufs)

联合文件系统 (UnionFS) 内置于 Linux 内核中,它允许将一个文件系统的内容与另一个文件系统的内容合并,同时保持“物理”内容分离。结果是一个统一的文件系统,即使数据实际上是在分支中结构化的。

这里的想法是,如果您有多个图像具有一些相同的数据,而不是再次复制这些数据,它是通过使用称为 layer 的东西来共享的。

UnionFS

图片来源:

图片 CC BY-SA opensource.com

每一层都是一个文件系统,可以跨多个容器共享,例如,httpd 基础层是官方的 Apache 镜像,可以跨任意数量的容器使用。想象一下我们刚刚为所有容器使用相同的基础层而节省的磁盘空间。

这些镜像层总是只读的,但是当我们从这个镜像创建一个新容器时,我们会在它上面添加一个薄的可写层。这个可写层是您创建/修改/删除或进行每个容器所需的其他更改的地方。

写时复制

当你启动一个容器时,它看起来好像容器有它自己的整个文件系统。这意味着您在系统中运行的每个容器都需要自己的文件系统副本。这不会占用大量磁盘空间并且容器启动也需要大量时间吗?不——因为每个容器都不需要自己的文件系统副本!

容器和镜像使用写时复制机制来实现这一点。写入时复制策略不是复制文件,而是将相同的数据实例共享给多个进程,并且仅在进程需要修改或写入数据时进行复制。所有其他进程将继续使用原始数据。在正在运行的容器中执行任何写操作之前,将要修改的文件的副本放置在容器的可写层上。这是_write_发生的地方。现在您知道为什么它被称为_copy-on-write_。

该策略优化了镜像磁盘空间使用和容器启动时间的性能,并与 UnionFS 结合使用。

覆盖文件系统

覆盖层位于现有文件系统之上,结合了上下目录树,并将它们呈现为单个目录。这些目录称为_layers_。下层保持不变。每层仅添加与其下一层的差异(计算术语中的_diff_),此统一过程称为_union mount_。

最底层的目录或Image层称为_lowerdir_,上层目录称为_upperdir_。最终覆盖或统一的层称为_merged._

分层文件系统

图片来源:

图片 CC BY-SA opensource.com

Linux 容器

  • 什么是 Linux 容器?

  • 容器术语介绍

  • 下载:容器入门

  • Kubernetes Operators:自动化容器编排平台

  • 电子书:用于设计云原生应用程序的 Kubernetes 模式

  • 什么是 Kubernetes?

常用术语由以下层定义组成:

  • 基础层是文件系统文件所在的位置。就容器镜像而言,这一层将是您的基础镜像。

  • Overlay 层通常称为_容器层_,因为对运行中的容器所做的所有更改,如添加、删除或修改文件,都会写入此可写层。对该层所做的所有更改都存储在下一层中,并且是 Base 和 Diff 层的_union_视图。

  • Diff 层包含在 Overlay 层中所做的所有更改。如果您编写的内容已经在 Base 层中,则覆盖文件系统会将文件复制到 Diff 层并进行您打算编写的修改。这称为_copy-on-write_。

快照器

容器可以使用层和图形驱动程序构建、管理和分发更改作为其容器文件系统的一部分。但是使用图形驱动程序确实很复杂并且容易出错。 SnapShotter 与图形驱动程序不同,因为它们不了解图像或容器。

快照器的工作方式与 Git 非常相似,例如拥有树的概念,以及为每次提交跟踪对树的更改。 snapshot 表示文件系统状态。快照使用一组目录具有父子关系。可以在父级与其快照之间进行 _diff 以创建层。

Snapshotter 提供了一个用于分配、快照和挂载抽象的分层文件系统的 API。

总结

您现在对什么是容器映像以及它们的分层方法如何使容器具有可移植性有了很好的了解。接下来,我将介绍容器运行时和内部结构。


本文基于techbeatly的文章,并经许可改编。

Logo

云原生社区为您提供最前沿的新闻资讯和知识内容

更多推荐