从根本上说,所有主要的软件,甚至是开源软件,都是在基于镜像的容器出现之前设计的。这意味着将软件放入容器从根本上来说是一种平台迁移。这也意味着有些程序很容易迁移到容器中,而另一些程序则更困难。
我大约在 3.5 年前开始使用基于镜像的容器。在这段时间里,我容器化了大量的应用程序。我了解了什么是真实的,什么是迷信。今天,我想简要介绍一下 Linux 容器是如何设计的,并简要介绍一下镜像签名。
Linux 容器的设计原理
大多数人对基于镜像的 Linux 容器感到困惑的是,它实际上是将操作系统分为两部分:内核空间和用户空间。在传统的操作系统中,内核运行在硬件上,你永远不会直接与之交互。用户空间是你实际与之交互的部分,包括你在查看文件浏览器或运行 ls
命令时看到的所有文件、库和程序。当你使用 ifconfig
命令来更改 IP 地址时,你实际上是利用用户空间程序来对 TCP 堆栈进行内核更改。如果人们没有研究过 Linux/Unix 基础知识,这通常会让他们感到震惊。
从历史上看,用户空间中的库支持与内核交互的程序(ifconfig
、sysctl
、tuned-adm
)和面向用户的程序,如 Web 服务器或数据库。所有东西都被倾倒在一个单一的文件系统层次结构中。用户可以检查 /sbin 或 /lib 目录,查看所有支持操作系统本身的应用和库,或者检查 /usr/sbin 或 /usr/lib 目录,查看所有面向用户的程序和库(查看 文件系统层次结构标准)。这种模型的问题在于,操作系统程序和业务支持应用程序之间从来没有完全隔离。/usr/bin 中的程序可能依赖于 /lib 中的库。如果应用程序所有者需要更改某些内容,可能会破坏操作系统。相反,如果负责进行安全更新的团队需要更改库,可能会(而且经常会)破坏面向业务的应用程序。这很混乱。
使用基于镜像的容器(如 Docker、LXD 和 RKT),应用程序所有者可以打包和修改 /sbin、/lib、/usr/bin 和 /usr/lib 中的所有依赖项,而无需担心破坏底层操作系统。本质上,使用基于镜像的容器可以将操作系统干净地隔离成两部分,再次强调,内核和用户空间。现在,开发和运维可以彼此独立地更新东西,有点像...。
不过,也存在一些严重的困惑。通常,每个应用程序所有者(或开发人员)都不想负责更新应用程序依赖项,如 openssl
、glibc
,或加强底层组件,如 XML 解析器或 JVM,或处理性能设置。从历史上看,这些问题被委托给运维团队。由于我们在容器中打包了大量的依赖项,因此将容器中所有部分的责任委托出去仍然是许多组织面临的实际问题。
将现有应用程序迁移到 Linux 容器
将软件放入容器基本上是一种平台迁移。我想强调一下,是什么使得某些应用程序难以迁移到容器中。
开发人员现在可以完全控制 /sbin、/lib、/usr/bin 和 /usr/lib 中的内容。但是,他们面临的挑战之一是,他们仍然需要将数据和配置放入诸如 /etc 或 /var/lib 之类的文件夹中。对于基于镜像的容器,这是一个坏主意。我们真的希望代码、配置和数据之间有良好的分离。我们希望开发人员在容器中提供代码,但我们希望数据和配置来自环境,例如开发、测试或生产环境。
这意味着我们需要在实例化容器时从 /etc 或 /var/lib 的目录中挂载一些文件。这将使我们能够移动容器,并仍然从环境中获取其配置和数据。很酷,对吧?嗯,存在一个问题,这意味着我们必须能够干净地隔离配置和数据。许多现代开源程序(如 Apache、MySQL、MongoDB 或 Nginx)默认情况下会这样做,但许多自研、遗留或专有程序并非设计为默认执行此操作。这是许多组织的痛点。开发人员的最佳实践是开始架构新的应用程序并迁移遗留代码,以便干净地隔离配置和数据。
镜像签名简介
信任是容器的一个主要问题。容器镜像签名允许用户向镜像添加数字指纹。这个指纹稍后可以通过加密测试来验证信任。这允许容器镜像的用户验证来源并信任容器镜像。
容器社区经常使用“容器镜像”这个词,但这种命名可能非常令人困惑。Docker、LXD 和 RKT 基于拉取远程文件并将其作为容器运行的概念进行操作。这些技术中的每一种都以不同的方式处理容器镜像。LXD 拉取具有单层的单个容器镜像,而 Docker 和 RKT 使用基于开放容器镜像 (OCI) 的镜像,这些镜像可以由多层组成。更糟糕的是,不同的团队甚至组织可能负责容器镜像的不同层。容器镜像的概念隐含着容器镜像格式的概念。拥有像 OCI 这样的标准镜像格式将允许围绕容器扫描、签名和云提供商之间的移动建立一个生态系统。
现在开始讨论签名。
容器的一个问题是我们将大量的代码、二进制文件和库打包到容器镜像中。一旦我们打包了代码,我们就将其与我们称为注册服务器的简易文件服务器共享。一旦代码被共享,在没有任何形式的加密签名的情况下,它基本上是匿名的。更糟糕的是,容器镜像通常由镜像层组成,这些镜像层由不同的人或团队控制。每个团队都需要能够检查上一个团队的工作,添加他们的工作,然后盖上他们的批准印章。然后他们需要将其发送给下一个团队。
容器镜像的最终用户(实际上是由多个镜像组成的)确实需要检查监管链。他们需要验证对添加到容器镜像的每个团队的信任。最终用户对容器镜像的每一层都充满信心至关重要。
Scott McCarty 将在 8 月 24 日的 ContainerCon 上做一个名为 Containers for Grownups: Migrating Traditional & Existing Applications 的演讲。参加演讲的人将对容器的工作原理有一个新的理解,并能够利用他们当前的架构知识进入容器的世界。他将教与会者哪些应用程序容易放入容器以及为什么,并且他将解释哪些类型的程序更困难以及为什么。他将提供大量的示例,并帮助与会者在构建和迁移他们自己的应用程序到容器中时获得信心。
评论已关闭。