Starnix 容器

Starnix 容器支持在不同的 Linux 环境中运行 Linux 二进制文件。

Starnix 容器概览

Starnix 容器(在概念上类似于 Linux 容器或虚拟机)是用于运行一系列 Linux 进程的 Starnix 内核实例和磁盘映像的组合。例如,debian_container 组件是一个 Starnix 容器,其中包含一个基于 Debian 的小型 Linux 系统。请注意,此组件将 starnix 指定为其运行程序(请参阅 debian_container.cml)。这意味着此 Starnix 容器组件并不代表单个进程,而是代表 Starnix 在 Fuchsia 上运行和管理的整个 Linux 环境。

Starnix 容器、Starnix 内核和 Starnix runner

以下定义有助于理解本页面中的概念:

  • Starnix 容器:包含 Starnix 内核实例的配置值的 Fuchsia 组件。
  • Starnix 内核 (starnix_kernel):一个 Fuchsia 组件,负责执行 Linux 程序。此组件会运行 Starnix 容器,并在 Starnix 容器中创建和执行 Linux 进程。此组件还可以在 Starnix 容器中运行其他 Fuchsia 组件(设置为运行 Linux 二进制文件)。
  • Starnix runner (starnix_runner):一个 Fuchsia 组件,负责创建 Starnix 内核实例。

将 Starnix 容器作为 Fuchsia 组件运行

为了启动 Starnix 容器,Fuchsia 要求 Starnix 运行程序启动 Starnix 容器组件的启动。Starnix 运行程序会创建一个新的 Starnix 内核实例,作为此容器的内核。然后,Starnix 内核会从 Starnix 容器组件中读取 program 块,该块会提供以下信息:

  • 要在 Linux 环境中的哪些路径装载哪些磁盘映像。
  • 要作为 init(启动 Linux 启动过程的初始进程)运行的二进制文件。

虽然 Starnix 内核运行 Starnix 容器组件,但 Starnix 容器不是 Starnix 内核组件层次结构的一部分(参见图 1),就像 ELF 运行程序不是它所运行的组件的父项一样。

Starnix 组件层次结构

图 1. 运行 Starnix 组件的 Fuchsia 系统的简化组件层次结构。

Starnix 容器中的 Linux 环境

在 Starnix 容器内的 Linux 环境中,就像典型的 Linux 系统一样,大多数 Linux 进程从 init 进程(不过是由 Starnix 容器中的 Starnix 内核创建)从其他 Linux 进程派生。例如,init 可能会复刻并创建一个 sshd 进程,然后该进程会监听端口。当 sshd 在该端口上收到网络连接时,可能会生成一个 sh 进程作为该连接的命令行 shell。

在 Starnix 容器中运行 Linux 二进制文件

作为 Fuchsia 组件的 Linux 二进制文件可以在现有 Starnix 容器内运行。Starnix 容器本身是一个组件运行程序,可在容器内运行 Fuchsia 组件。

以下 Linux 二进制文件可以在 Starnix 容器中作为 Fuchsia 组件运行:

  • Fuchsia 软件包中包含的 Linux 二进制文件
  • 正在运行的 Starnix 容器中存在的 Linux 二进制文件

换句话说,如果开发者想要在 Starnix 容器内运行 Linux 程序,可以通过以下方式之一定义 Fuchsia 组件:

  • 一个组件,用于在其 Fuchsia 软件包中包含 Linux 二进制文件(设置为在 Starnix 容器中运行)。
  • 用于引用已在运行的 Starnix 容器中 Linux 二进制文件的组件。

然后,Starnix 内核会生成一个新的 Linux 进程作为该组件的 init 子进程。

作为组件运行程序的 Starnix 容器

Starnix 容器可以包含 Fuchsia 组件框架中的子组件 collection(请参阅 container.shard.cml)。在这种情况下,Starnix 容器会将其运行程序提供给集合。如果新组件在集合中启动(或在组件拓扑中已路由 Starnix 容器的运行程序的任何位置),则该组件可以将 Starnix 容器用作其运行程序(有关示例,请参阅 hello_starnix 组件)。

Starnix 容器的组件拓扑

图 2. 一个组件拓扑,显示了 Starnix 容器下的一系列子组件。

当要求 Starnix 容器使用其运行程序运行组件时(根据组件的 program 块),Starnix 容器在其 Linux 环境中生成一个 Linux 进程,作为 init 进程的子级。

在 Fuchsia 软件包中包含 Linux 二进制文件

hello_starnix 组件中,program 代码块指定 Starnix 容器运行 hello_starnix 组件所在软件包中的 bin/hello_starnix 二进制文件。hello_starnix 组件可以从自己的软件包运行 bin/hello_starnix 二进制文件,因为 Starnix 容器的运行程序将 hello_starnix 组件的命名空间装载为 Starnix 容器的 Linux 环境中的根文件系统目录。(但是,program 块还可以指定 Starnix 容器使用绝对路径(例如 /bin/fortune)从 Linux 环境自己的文件系统运行二进制文件。)

这种运行来自 Fuchsia 软件包的 Linux 二进制文件的机器最常用于测试。测试通常附带测试夹具和其他需要与测试一起存在于容器内的数据。通常,会将此数据与测试二进制文件(即 Linux 二进制文件)打包在一起作为 Fuchsia 组件,并要求测试专用 Starnix 容器运行测试。此机制允许测试在 Starnix 容器内运行时访问其夹具和其他数据。

但是,Linux 二进制文件应在包含其所有运行时依赖项的环境中运行。这些运行时依赖项从二进制文件到二进制文件并不总是兼容。例如,一些二进制文件需要 glibc,而另一些二进制文件可能需要 musl。因此,Fuchsia 软件包中的 Linux 二进制文件需要与 Starnix 容器提供的 Linux 环境兼容。例如,如果 Linux 二进制文件链接到 glibc,则必须在具有 glibc 的 Starnix 容器(例如 Debian Linux 发行版)中运行。同样,许多 Linux 二进制文件都会假定文件系统布局。此类 Linux 二进制文件需要在文件系统布局符合预期的 Starnix 容器中运行。