大家好!我是大聪明-PLUS

近年来,容器技术(尤其是Linux 容器)越来越受欢迎。

数据中心和云计算环境中容器的使用每年都在增长,Docker和Kubernets等工具已经变得非常流行。

嵌入式 Linux 领域也一样,近年来开始出现一些基于容器的嵌入式系统 Linux 发行版,如balenaOS和Linux microPlatform。

但是,容器是什么?它们解决了哪些问题?涉及哪些技术?我们应该使用容器在嵌入式系统上部署应用程序吗?我将在本文中尝试回答这些问题以及其他许多问题!

为什么我们需要 Linux 容器?

假设您正在开发一个具有多个依赖项的应用程序。该应用程序可能依赖于库、配置文件,甚至其他应用程序。

现在假设您需要将此应用程序分发到不同的环境。例如,您正在 Ubuntu 18.04 上进行开发,并希望将应用程序部署到运行 Fedora、Debian 甚至其他版本 Ubuntu 的计算机上。

如何确保这些不同发行版的执行环境满足您的应用程序的依赖关系?

解决此问题的一种方法是使用autotools或cmake构建系统分发应用程序的源代码,以便在任何依赖项未得到满足时进行验证并通知用户。除了源代码之外,您还可以分发一份手册(例如README),记录应用程序的安装过程,包括安装其依赖项的步骤。

可以运行,对吧?但是,任何曾经开发和分发必须在多个 GNU/Linux 发行版上运行的应用程序的人都知道,随着应用程序随时间变化,创建和维护构建系统配置文件需要做大量工作。

此外,记录应用程序的安装过程及其依赖关系也相当繁琐。例如,如果您想要支持 10 个不同的 Linux 发行版,您可能需要在本手册中包含在所有这些发行版上安装应用程序的步骤!

这是一个无法扩展的解决方案。更不用说你会强迫用户安装一些他们可能不需要的依赖项,这甚至可能导致他们的环境出现问题。

你能看出这里的问题吗?运行时环境和应用程序(及其依赖项)之间没有隔离,这使得在 GNU/Linux 发行版上部署应用程序的过程非常困难,有时甚至很痛苦!

为了解决这个问题,我们可以在虚拟机中虚拟化应用程序的执行。这样,只需创建一个包含所有应用程序依赖项的虚拟机映像,然后使用QEMU、VirtualBox或VMWare Workstation Player等虚拟化工具运行该映像即可。

然而,虚拟机非常繁重。它运行完全隔离的操作系统实例(内核和根文件系统),大大增加了资源消耗(CPU、内存、I/O)。

为什么我们不把这个根文件系统与系统隔离,但运行在同一个内核上呢?为什么不把所有运行该应用程序不需要的应用程序和库从这个根文件系统中删除呢?简而言之,这就是 Linux 容器!

什么是 Linux 容器?

Linux 容器是一个最小文件系统,仅包含运行特定应用程序或应用程序组所需的软件组件,并且内核能够完全隔离地“运行”与系统其余部分隔离的容器。

Linux 容器可以解决将应用程序分发到具有不同配置的环境的问题。与虚拟机解决方案不同,容器化解决方案更轻量且资源占用更低,因为容器镜像比虚拟机镜像更小,并且内核与操作系统上运行的其他进程和容器共享

因此,Linux 容器是用户空间层的一个实例,它分配有多种资源(CPU、内存、I/O),并且与系统其他部分隔离运行。一个容器可以只运行一个应用程序,也可以运行整个根文件系统(包括 init 系统)。您还可以同时启动和运行多个容器。

如果您访问容器内的终端并运行ps命令,您将仅看到容器进程。如果您运行mount命令,您将仅看到容器挂载点。如果您运行ls 命令,您将仅看到容器文件系统。如果您运行restart命令,则只有容器应用程序会重启,并且可能需要不到 1 秒的时间!

使用 Linux 容器的优势

容器有助于应用程序的分发并允许它们在完全不同的环境中执行。

更新应用程序的过程也得到了简化,因为更新应用程序及其依赖项只需要更新容器映像即可。

容器化解决方案的扩展性更好,因为您可以同时运行和控制容器的多个实例。

安全因素也很重要。如果配置得当,容器可以完全独立于主机操作系统运行,从而提高系统安全性。

最后,与虚拟机解决方案相比,容器具有更好的性能并且使用更少的资源。

Linux容器是如何实现的?

容器实现使用了几个 Linux 内核功能,包括 cgroups 和 namespaces。

控制组或cgroups是一个非常有趣的 Linux 内核功能,它允许按进程或进程组划分系统资源(CPU、内存、I/O)。

另一方面,命名空间功能可以隔离 Linux 上进程的执行(PID、用户、网络连接、挂载点等)

使用这些和其他一些功能,可以为 Linux 上的应用程序创建一个完全隔离的执行环境,这就是工具的作用所在。

有几种工具可用于处理 Linux 上的容器,包括 LXC、systemd-nspawn 和 Docker。

LXC是 Linux 内核容器功能的用户空间接口。它通过简单的命令行工具,帮助 Linux 用户轻松创建和管理系统或应用程序容器。

Systemd-nspawn(systemd 的一部分)是一个非常简单有效的命令行工具,用于在容器内运行应用程序或完整的根文件系统。

在我撰写本文时,Docker是最流行的容器管理工具。它由Docker Inc开发,与 LXC 和 systemd-nspawn 等低级工具相比,它操作简单,功能更丰富。Docker 甚至还有一个名为Docker Hub的公共容器仓库。

最后,我们有Kubernetes,这是一个开源容器编排系统,用于自动化应用程序的部署、扩展和管理。Docker 和 LXC 能够创建和运行容器,而 Kubernetes 能够自动化容器的管理。

Linux 基金会有一个名为开放容器计划(Open Container Initiative)的项目,旨在制定和维护 Linux 中容器技术的开放标准,目前有两个规范,一个是定义管理容器执行标准的运行时规范,另一个是标准化容器镜像格式的镜像规范。

但是在嵌入式系统上使用容器怎么样?

嵌入式系统上的容器

尽管容器并不是一个新概念,但近年来它们的使用成倍增加,现在有几种适用于嵌入式 Linux 的容器解决方案可供选择,包括balenaOS、Linux microPlatforms、Pantahub和Torizon。

嵌入式领域仍存在许多挑战和问题需要解决。我们是否有足够的硬件资源在嵌入式系统上运行容器?如何轻松地将交叉编译的应用程序及其依赖项打包到容器镜像中?如何管理软件组件(基础操作系统、容器镜像等)的许可证?

后续,我们将重点关注在嵌入式系统上使用 Linux 容器,并更详细地研究这些挑战和其他挑战。

Logo

加入「COC·上海城市开发者社区」,成就更好的自己!

更多推荐