logo

什么是标准容器(2021 版)

作者:喵咕酱2021.10.19 18:32浏览量:583

简介:在本文中,我不是要回顾创建容器的所有可能方法。相反,本文是对 OCI 运行时规范的分析。

OCI 运行时规范:

  • 容器是运行进程的隔离和受限的盒子 📦
  • 容器将应用程序及其所有依赖项(包括操作系统库)打包在一起
  • 容器是为了可移植性——任何兼容的运行时都可以运行标准容器
  • 容器可以使用 Linux、Windows 和其他操作系统来实现
  • 虚拟机也可以用作标准容器 🤐

有很多方法可以创建容器,尤其是在 Linux 等上。除了超级广泛的 Docker 实现,您可能听说过 LXC、systemd-nspawn,甚至 OpenVZ。

容器的一般概念是相当模糊的。什么是对的通常取决于上下文,但上下文本身并不总是明确给出。例如,有一种常见的说法,容器是 Linux 进程,或者容器不是虚拟机。然而,第一个陈述只是对解释 Linux 容器的过于简单化的尝试,第二个陈述并不总是正确的。

在本文中,我不是要回顾创建容器的所有可能方法。相反,本文是对 OCI 运行时规范的分析。结果证明该规范是一个有见地的阅读!例如,它给出了标准容器的定义(不,它不是一个过程),并阐明了何时可以将虚拟机视为容器。

Docker 和 Podman 带给我们的容器是符合 OCI 的。今天,我们甚至可以互换使用术语容器、Docker 容器和 Linux 容器。然而,这只是一种符合 OCI 的容器。所以,让我们仔细看看 OCI 运行时规范。

什么是开放容器计划 (OCI)

Open Container Initiative (OCI) 是一个开放的治理结构,由 Docker 和其他容器行业的知名参与者于 2015 年建立,旨在表达围绕容器格式和运行时创建开放行业的标准。换句话说,OCI 为操作系统进程和应用程序容器的标准制定规范。

这是我的理解。到 2015 年,Docker 已经获得了相当大的知名度,但还有其他竞争项目在实现自己的容器,如 rkt 和 lmctfy。显然,OCI 的建立是为了标准化做容器的方式。事实上,它使 Docker 的容器实现成为一个标准的实现,但也包含了一些非 Docker 部分。

什么是 OCI 容器

那么,如今 OCI 是如何定义 Container 的呢?

标准容器是用于执行具有环境被隔离和资源受限制的进程环境。

为什么我们需要容器?

定义软件交付单元…标准容器的目标是以自描述和可移植的格式封装软件组件及其所有依赖项,以便任何兼容的运行时都可以运行它而无需额外的依赖项,不管底层机器和容器的内容。

好的,我们可以用容器做什么?

可以使用标准容器工具创建、启动和停止;使用标准文件系统工具复制和快照;并使用标准网络工具下载和上传。

图片.jpg
OCI 运行时必须支持的容器操作:Create、Start、Kill、Delete和Query State。
嗯,有道理。但是……容器不能是进程!根据 OCI 运行时规范,它更像是一个隔离且受限制的盒子,用于在内部运行一个或多个进程。

Linux 容器与其他容器

除了容器的操作和生命周期,OCI Runtime Spec 还规定了容器的配置和执行环境。

根据 OCI 运行时规范,要创建容器,需要为运行时提供所谓的文件系统包,该包由一个必需 config.json 文件和一个包含未来容器根文件系统的可选文件夹组成。

题外话:bundle 通常是通过解压容器镜像获得的,但镜像不是运行时规范的一部分。相反,它们受专用 OCI 镜像规范的约束。

config.json 包含对容器实施标准操作所需的数据(创建、启动、查询状态、终止和删除)。但是当涉及到 config.json 文件的实际结构时,事情开始变得非常有趣。

配置由公共部分和特定于平台的部分组成。公共部分包括 ociVersion,root 包内的文件系统路径, 额外 mounts 的 root,process 在容器中启动的 user, 和 hostname. 嗯…但是著名的命名空间和 cgroup 在哪里?

在撰写本文时,OCI 运行时规范为以下平台定义了容器:Linux、Solaris、Windows、z/OS 和 Virtual Machine。

等等,什么?!虚拟机是容器??!🤯

特别是,Linux 特定部分引入了(除其他外)pid、network、mount、ipc、uts 和用户命名空间、控制组和 seccomp。相比之下,特定于 Windows 的部分带有自己的隔离和限制机制,由 Windows 主机计算服务 (HCS) 提供。

图片.jpg
因此,只有 Linux 容器依赖于命名空间和 cgroup。但是,并非所有标准容器都是 Linux。

虚拟机与容器

最广泛使用的 OCI 运行时是 runc 和 crun。不出所料,两者都实现了 Linux 容器。但正如我们刚刚看到的,OCI 运行时规范提到了 Windows、Solaris 和其他容器。对我来说更有趣的是,它定义了 VM 容器!

容器不是要取代虚拟机作为相同执行环境抽象的更轻量级的实现吗?

不管怎样,让我们仔细看看 VM 容器。

显然,它们不受 Linux 命名空间和 cgroup 的支持。相反,特定于虚拟机的容器配置提到了管理程序、内核和 VM 镜像。因此,隔离是通过虚拟化某些硬件(管理程序)然后在其上启动成熟的操作系统(内核 + 镜像)来实现的。由此产生的环境是我们的盒子,即一个容器。

图片.jpg
请注意,OCI 运行时规范中提到的 VM 镜像与用于创建包的传统容器镜像无关。捆绑根文件系统单独挂载到 VM 容器中。

因此,基于 VM 的容器是一回事!

但是,OCI VM 容器的唯一未弃用实现,即 Kata 容器,在其常见问题解答中包含以下内容:

Kata Containers 仍处于形成阶段,但该项目的技术基础——Clear Containers 和 runV——被中国最大的电子商务公司京东等组织在全球企业范围内使用(按收入计算)。

MicroVM 与容器

Linux 容器最酷的部分之一是它们比虚拟机轻得多。启动时间不到一秒,几乎没有空间和运行时开销。然而,他们最强大的部分也是他们的弱点。Linux 容器之所以如此之快,是因为它们是常规的 Linux 进程。因此,它们与底层 Linux 主机一样安全。因此,Linux 容器仅适用于受信任的工作负载。

由于共享基础设施变得越来越普遍,因此仍然需要更强大的隔离。无服务器/FaaS 计算可能是最突出的例子之一。通过在 AWS Lambda 或类似环境中运行代码,您就不再需要处理服务器抽象了。因此,开发团队不需要虚拟机或容器。但从平台提供商的角度来看,使用 Linux 容器在同一主机上运行不同客户的工作负载将是一场安全噩梦。相反,函数需要在像 Linux 容器一样轻量级和像虚拟机一样安全的东西中运行。

Firecracker 的主要组件是一个虚拟机监视器 (VMM),它使用 Linux 内核虚拟机 (KVM) 来创建和运行微型虚拟机。Firecracker 拥有简约的设计。它排除了不必要的设备和面向访客的功能,以减少每个 microVM 的内存占用和攻击面区域。这提高了安全性,减少了启动时间,并提高了硬件利用率。Firecracker 也已集成到容器运行时中,例如 Kata Containers 和 Weaveworks Ignite。

但无论是否令人惊讶,Firecracker 本身并不是 OCI 兼容的运行时……然而,似乎有一种方法可以将 OCI 运行时放入 Firecracker 微型虚拟机中并获得所有领域的最佳效果 - 容器的可移植性,Firecracker 微型虚拟机的轻便性,并与主机操作系统完全隔离。

图片.jpg

安全容器领域另一个有趣的项目是谷歌的 gVisor:

gVisor 是一个用 Go 编写的应用程序内核,它实现了 Linux 系统表面的很大一部分。它包括一个名为 runc 的开放容器计划 (OCI) 运行时,它在应用程序和主机内核之间提供隔离边界。runc 运行时与 Docker 和 Kubernetes 集成,使运行沙盒容器变得简单。

与 Firecracker 不同,gVisor 提供了一个 OCI-complaint 运行时。但是对于 gVisor 支持的容器,没有像 KVM 这样成熟的虚拟机管理程序。相反,它模拟用户空间中的内核。听起来很酷,但运行时开销可能很明显。

不仅仅是结论

总而言之,容器不仅仅是稍微孤立和受限的 Linux 进程。相反,它们是标准化的执行环境,可提高工作负载的可移植性。Linux 容器是当今最普遍的容器形式,但对更安全的容器的需求正在增长。OCI 运行时规范定义了 VM 支持的容器,而 Kata 项目使它们成为现实。所以,现在是探索容器世界的激动人心的时刻!

作者:yiwan
来源:云原生技术爱好者社区

相关文章推荐

发表评论