#container #run-time #northstar #manifest #embedded-linux #cargo-manifest #process

bin+lib cargo-npk

Northstar 是针对嵌入式系统的 Linux 容器运行时

5 个不稳定版本

0.9.0 2023 年 10 月 19 日
0.8.2 2023 年 8 月 4 日
0.8.1 2023 年 5 月 10 日
0.8.0 2023 年 5 月 10 日
0.7.1 2023 年 3 月 21 日

#306Cargo 插件

每月 22 次下载

Apache-2.0 协议

510KB
12K SLoC

Northstar

CI Status Docs License Issues Top Language

Northstar 是 Linux 的嵌入式容器运行时原型。

Demo

目录

关于

Northstar 是一个开源的嵌入式容器运行时,针对速度和资源使用进行了优化。Northstar 结合了几个标准的 Linux 进程隔离和沙箱功能,以在容器/进程之间获得中等程度的隔离。Northstar 运行时由两部分组成:容器处理和进程创建。为了构建最有效和最健壮的解决方案,Northstar 完全使用 Rust 语言开发,这是一种旨在提供 C/C++ 性能而不具有其缺陷的语言。

Northstar - 嵌入式容器运行时 白皮书描述了 Northstar 的动机和初步概念和想法。

安全性是一个重要的关注点,并且难以实现。Northstar 使用了大量的操作系统接口,这些接口在安全性和稳定性方面存在错误空间。此 报告 描述了对 Northstar 嵌入式 Linux 容器运行时的安全评估结果。该评估于 2022 年 8 月由 Cure53 进行,包括渗透测试和对源代码的专门审计。结果和采取的措施在项目的 问题跟踪器 标签 audit_0822 中记录。

容器

Northstar容器被称为NPK。NPK格式深受Android APEX技术的启发。一个Northstar容器包含:

  • Squashfs文件系统镜像形式存在的根文件系统(可选压缩)
  • 包含进程配置和容器元信息的Northstar清单

可以使用Northstar工具sextantcargo-npk子命令创建Northstar容器。

进程

启动的Northstar容器是Linux进程。派生容器的属性和环境在NPK中包含的容器清单中描述。容器清单允许配置以下Linux子系统和服务:

  • 传递给容器init的参数
  • 在容器上下文中设置的环境变量
  • 用户和组ID
  • 挂载命名空间
  • PID命名空间
  • IPC命名空间
  • UTS命名空间
  • Cgroups内存(可选)
  • CGroups CPU(可选)
  • 额外的绑定挂载(可选)
  • 能力(可选)
  • 处理stdout/stderr(可选)
  • Seccomp配置(可选)

比较

  • Northstar容器不可移植,针对已知系统(uid/gid/mounts...)进行定制
  • 待办事项

快速入门

Northstar是用Rust编写的。最低支持的Rust版本(MSRV)是1.65.0。Rust最好通过rustup工具安装和管理。Rust有一个为期6周的快速发布流程,支持大量平台,因此任何时候都有许多Rust构建可用。rustup以一致的方式在Rust支持的所有平台上管理这些构建,使得可以从beta和nightly发布渠道安装Rust,同时支持额外的交叉编译目标。

Northstar的构建仅限于Linux系统,并且在Linux系统上运行仅限!Northstar构建为各种系统库生成绑定,并使用mksquashfs命令行工具创建NPK。

通过运行以下命令在基于Debian的发行版上安装构建依赖项:

sudo apt-get install build-essential libclang1 squashfs-tools

需要版本4.6或更高版本的squashfs-tools包。

Northstar附带一系列示例,展示了Northstar的大部分功能。构建示例二进制文件及其相应的NPK是通过

./examples/build.sh

触发示例运行时主

cargo run --bin northstar

Northstar工作区配置配置了一个cargo runner,该runner以超级用户权限调用运行时示例主二进制文件。

使用northstar-nstar实用程序检查和修改运行时状态,例如。

cargo build --release --bin northstar-nstar
...
./target/release/northstar-nstar --help
...
> ./target/release/northstar-nstar -j start hello-world
{"Response":{"Err":{"StartContainerStarted":{"name":"hello-world","version":"0.0.1"}}}}
> ./target/release/northstar-nstar -j kill hello-world
{"Response":{"Ok":null}}

northstar-nstar是开发工具,不适用于任何生产用例。请参阅控制台了解详细信息。

SquashFS 工具

遗憾的是,northstar-sextant依赖于主机上可用的mksquashfs二进制文件。以下是从源代码构建仅支持gzip支持的mksquashfs二进制文件的配方

git clone https://github.com/plougher/squashfs-tools.git
cd squashfs-tools/squashfs-tools
git checkout 4.6.1
sudo make install

对于不同的压缩算法,安装相应的依赖项(基于Debian的发行版)

sudo apt install help2man libz-dev liblzo2-dev liblz4-dev libzstd-dev
git clone https://github.com/plougher/squashfs-tools.git
cd squashfs-tools/squashfs-tools
git checkout 4.6.1
sudo CONFIG=1 LZO_SUPPORT=1 LZ4_SUPPORT=1 ZSTD_SUPPORT=1 XZ_SUPPORT=1 XATTR_SUPPORT=1 make -j $(nproc) install

配置

示例可执行文件 northstar 读取表示 northstar_runtime::config::Config 的配置文件。带注释的示例 在这里

仓库

仓库是一个能够存储运行时 NPK 的实体。仓库在运行时初始化时配置。仓库配置不能在运行时更改。每个配置的仓库都有一个唯一的标识符。目前存在两种类型的仓库: fsmem

fs 类型的仓库由文件系统存储支持。配置的目录(dir)用于存储 NPK。如果此目录为只读,则无法在运行时执行额外的安装请求。如果 fs 仓库配置包含一个 key 字段,则仓库被视为“经过验证”。配置的密钥用于验证容器清单的签名及其验证根哈希。当容器挂载时,验证根哈希用于配置一个设备映射器验证设备,该设备将挂载而不是包含 Squashfs 图像。

没有 key 的仓库被视为可信来源。不执行签名检查。根文件系统以 验证的方式挂载。在 NPK 中可能存在的验证根哈希被忽略。可信仓库应该是经过验证的只读文件系统。

fs 仓库的 mount_on_start 标志设置为 true,使运行时在启动时挂载所有现有容器。挂载操作并行执行。

mem 类型的仓库使用 memfd 进行存储。在容器安装过程中不持久存储数据。显然,在运行时启动时不可能在 mem 仓库中预安装 NPK。主要将 mem 仓库用于测试。

控制台

Northstar 使用 JSON 对与客户端共享的消息进行编码。消息由换行符分隔。这是一个常见的做法,便于在任何编程语言中实现客户端。然而,作为库的 Northstar 提供了一个方便的 Client 类型,可以用于使用 Rust 进行更简单的客户端实现。

有关 Northstar 控制台详情 在这里。一个很好的起点是运行带有 -j 标志的 northstar-nstar 工具。这将指示 northstar-nstar 显示与运行时交换的原始 JSON 负载。

有关作为 JSON 负载使用的模型的详情 在这里

调试

调试容器可能很困难。大多数有用的信息可以通过配置与容器一起生成的各种调试命令来获得,例如 strace。检查 运行时配置 中的 debug 部分,以获取示例。

cargo-npk

cargo-npk 子命令是用于从 Rust 二进制包构建 npk 的 cargo 子命令。清单可以是完全指定的(针对特定目标)在 cargo 清单中,也可以是链接的

[package.metadata.npk]
# Default manifest
manifest = "manifest.yaml"

例如,请参阅 hello-world 以获取完整示例。

cargo npk pack --target aarch64-unknown-linux-gnu --release --manifest-path examples/hello-world/Cargo.toml
ls target/aarch64-unknown-linux-gnu/release/hello-world-0.0.1.npk 
  target/aarch64-unknown-linux-gnu/release/hello-world-0.0.1.npk

集成测试

集成测试启动运行时实例,并断言来自运行时的容器通知的日志输出。测试套件由 Rust 测试系统调用,并由项目 CI 执行。有关详细信息,请查看 northstar-tests crate。Northstar 项目推荐使用 nextest :)。

./examples/build.sh
cargo test -p northstar-tests

有关将 Northstar 集成到嵌入式 Linux 系统的说明,请参阅此处

集成

说明文件中挂载条目的选项是可选的。要应用其中之一挂载选项 rwnoexecnosuidnodevrec,必须显式设置。

容器启动序列


清单格式

挂载文件系统默认为 只读。设置为 rw 的挂载通常很难从集成角度处理(SELinux 和权限)。尽管如此——以下是如何将主机系统的 /tmp 目录挂载到 /tmp 的示例。绑定挂载不会重新挂载为 ro。请注意,ro 绑定挂载需要两个挂载操作。

挂载

资源容器 不能rw 挂载。资源容器的文件系统是 squashfs,不可写。资源容器可以挂载而不设置 noexec 标志,以提供二进制文件。

以下是一个设置可执行标志但设置 nodevnosuid(可选)的资源挂载示例。

/tmp:
  type: bind
  host: /tmp
  options: rw, nosuid, noexec

以下是一个 tmpfs 挂载示例。tmpfs 挂载永远不是 ro ;-)

挂载类型 persist 由运行时为容器支持。运行时会负责将一个 可读可写 目录挂载到容器文件系统中。该目录仅为此容器专用。该目录不会与其他容器共享。

/bin/java:
  type: resource
  name: java13
  version:
  dir: /
  options: nodev, nosuid

要向容器提供 /dev 的最小文件系统,请向说明文件添加一个类型为 dev 的挂载条目。

/tmpfs:
  type: tmpfs
  size: 20M

/dev

/data:
  type: persist

是填充了

/dev:
  type: dev

全空

  • 随机
  • 随机
  • 随机
  • 随机
  • 随机
  • 随机

如果容器二进制文件需要更多设备,请绑定挂载主机系统的 /dev

Seccomp

Northstar 支持 Seccomp 来过滤容器的系统调用。向容器添加 seccomp 的最简单方法是向容器的说明文件添加 default 配置文件。

seccomp:
  profile:
    default

default 配置文件类似于 Docker 的默认配置文件

可以实现更具体的 seccomp 规则,以针对过滤系统调用。例如,以下说明条目允许 default 配置文件以及 delete_module 系统调用,如果其二进制参数等于 1 或匹配掩码 0x06

seccomp:
  profile:
    default
  allow:
    delete_module: !args
      index: 1
      values: [
          1,
      ]
      mask: 0x06

seccomp 说明条目的完整格式描述如下 此处

如果 seccomp 在说明文件中定义,并且容器尝试访问不在允许调用列表上的系统调用,则进程将立即终止。

能力

在清单的 capabilities 字段中分配给容器的每个功能,都会指示运行时在 创建 容器后 不要 丢弃此功能。请注意,capabilities 字段中列出的功能是在 环境 集中提升的。

在清单中设置空的权限集后,在容器启动时将丢弃所有集的所有权限。

清单中的示例权限设置

capabilities: [ CAP_NET_RAW, CAP_NET_ADMIN ]

自定义

Northstar 清单格式允许集成商在 custom 字段中向清单添加自定义字段,例如

custom:
  something: "hello"

可以通过 控制台 连接和 ìnspect 命令接收清单。

路线图

查看 开放问题 以获取建议功能和已知问题的列表。

问题和帮助

关于 Northstar 的任何相关内容,欢迎提问!要提问,请在此存储库中 创建一个问题

在提问前请记住以下几点指南

  • 确保你的问题尚未被回答。如果已被回答但答案不能令你满意,请随意在问题中评论,我们将重新打开它。
  • 使用简洁的标题和描述。尽可能添加尽可能多的信息,例如清单、npks、应用程序等...
  • 如果你的问题已被充分回答,请为该问题添加点赞(或你选择的任何表情符号!)这有助于我们识别人们通常遇到的问题。
  • 最后,保持文明、礼貌和耐心。 :)

贡献

贡献是使开源社区成为一个如此奇妙的学习、灵感和创造的地方的原因。你所做的任何贡献都 非常感激

  1. 分支项目
  2. 创建你的功能分支(git checkout -b feature/AmazingFeature
  3. 提交你的更改(git commit -m 'Add some AmazingFeature'
  4. 将更改推送到分支(git push origin feature/AmazingFeature
  5. 打开拉取请求

许可

在 Apache 2.0 许可下发行。有关更多信息,请参阅 LICENSE

联系方式

项目链接: https://github.com/esrlabs/northstar

致谢

依赖项

~15–29MB
~479K SLoC