runc
介绍
runc 是一个 CLI 工具,用于根据 OCI 规范生成和运行容器。
发布
runc 依赖并跟踪 runtime-spec 存储库。我们将尝试确保 runc 和 OCI 规范的主要版本保持同步。这意味着 runc 1.0.0 应该实现规范的1.0版本。
您可以在 release 页面上找到 runc 的正式发行版。
当前,以下特性还不能用于生产:
安全
此处概述了报告过程和披露沟通。
安全审核
Cure53 执行了第三方安全审核,您可以在这里查看完整的报告。
构建
runc 当前支持具有各种体系结构支持的 Linux 平台。必须使用 Go 1.13 或更高版本构建。
为了启用 seccomp 支持,您将需要在平台上安装 libseccomp。
例如 CentOS 的 libseccomp-devel 或 Ubuntu 的 libseccomp-dev
#在您的 GOPATH/src 中创建一个 'github.com/opencontainers' go get github.com/opencontainers/runc cd $GOPATH/src/github.com/opencontainers/runc make sudo make install
您还可以使用 go get 安装到您的 GOPATH,假设您已经在 src 下创建了 github.com 父文件夹:
go get github.com/opencontainers/runc cd $GOPATH/src/github.com/opencontainers/runc make sudo make install
runc 将安装到系统上的 /usr/local/sbin/runc。
构建标签
runc 支持可选的构建标记以编译对各种功能的支持,其中一些功能默认情况下处于启用状态(请参阅顶层 Makefile 中的 BUILDTAGS)。
要更改默认的构建标记,请为make设置BUILDTAGS变量,例如
make BUILDTAGS='seccomp apparmor'
Build Tag | Feature | Enabled by default | Dependency |
---|---|---|---|
seccomp | Syscall filtering | yes | libseccomp |
selinux | selinux process and mount labeling | yes | |
apparmor | apparmor profile support | yes | |
nokmem | disable kernel memory accounting | no |
运行测试套件
runc 当前支持通过 Docker 运行其测试套件。要运行套件,只需输入 make test。
make test
还有其他make目标可以在容器外部运行测试,但不建议这样做,因为编写测试时会期望它们可以在任何地方写入和删除。
您可以通过设置 TESTFLAGS 变量来运行特定的测试用例。
# make test TESTFLAGS="-run=SomeTestFunction"
您可以通过设置 TESTPATH 变量来运行特定的集成测试。
# make test TESTPATH="/checkpoint.bats"
您可以通过设置 ROOTLESS_TESTPATH 变量来运行特定的 rootless 集成测试。
# make test ROOTLESS_TESTPATH="/checkpoint.bats"
您可以通过设置CONTAINER_ENGINE_BUILD_FLAGS 和 CONTAINER_ENGINE_RUN_FLAGS 变量来使用容器引擎的标志运行测试。
# make test CONTAINER_ENGINE_BUILD_FLAGS="--build-arg http_proxy=http://yourproxy/" CONTAINER_ENGINE_RUN_FLAGS="-e http_proxy=http://yourproxy/"
依存关系管理
runc 使用 Go Modules 进行依赖项管理。请参阅 Go Modules 以了解如何添加或更新新的依赖项。更新依赖项时,请确保您正在运行 Go 1.14 或更高版本。
# Update vendored dependencies make vendor # Verify all dependencies make verify-dependencies
使用 runc
创建一个 OCI 捆绑包
为了使用 runc,您必须具有 OCI 捆绑包格式的容器。 如果安装了 Docker,则可以使用其 export 方法从现有 Docker 容器中获取根文件系统。
# create the top most bundle directory mkdir /mycontainer cd /mycontainer # create the rootfs directory mkdir rootfs # export busybox via Docker into the rootfs directory docker export $(docker create busybox) | tar -C rootfs -xvf -
填充根文件系统后,您只需生成捆绑包内 config.json 文件格式的规范即可。 runc 提供了一个 spec 命令来生成基本模板规范,然后可以对其进行编辑。 要查找规范中字段的功能和文档,请参考 specs 存储库。
runc spec
运行容器
假设您具有上一步中的 OCI 捆绑包,则可以两种不同的方式执行容器。
第一种方法是使用便捷命令运行,它将在退出容器后处理容器的创建,启动和删除操作。
# run as root cd /mycontainer runc run mycontainerid
如果您使用未修改的“runc spec”模板,则应该在容器内为您提供 sh 会话。
启动容器的第二种方法是使用 specs 生命周期操作。 这使您可以更好地控制容器在运行时如何创建和管理。 这也将在后台启动容器,因此您必须编辑 config.json 来删除此处简单示例的终端设置。 您的 config.json 中的处理字段如下所示,带有 "terminal": false and "args": ["sleep", "5"]。
"process": { "terminal": false, "user": { "uid": 0, "gid": 0 }, "args": [ "sleep", "5" ], "env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "TERM=xterm" ], "cwd": "/", "capabilities": { "bounding": [ "CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE" ], "effective": [ "CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE" ], "inheritable": [ "CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE" ], "permitted": [ "CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE" ], "ambient": [ "CAP_AUDIT_WRITE", "CAP_KILL", "CAP_NET_BIND_SERVICE" ] }, "rlimits": [ { "type": "RLIMIT_NOFILE", "hard": 1024, "soft": 1024 } ], "noNewPrivileges": true },
现在,我们可以在您的 Shell 中进行生命周期操作。
# run as root cd /mycontainer runc create mycontainerid # view the container is created and in the "created" state runc list # start the process inside the container runc start mycontainerid # after 5 seconds view that the container has exited and is now in the stopped state runc list # now delete the container runc delete mycontainerid
这允许更高级别的系统在创建容器之后和/或在删除容器之前通过设置各种设置来扩展容器创建逻辑。 例如,容器的网络堆栈通常在创建之后但在启动之前进行设置。
Rootless 容器
runc 能够在没有 root 特权的情况下运行容器。 这称为 rootless。 您需要将一些参数传递给 runc 才能运行 rootless 容器。 参见下文,并与以前的版本进行比较。
注意:为了使用此功能,必须在内核中编译并启用“User Namespaces”。根据发行版的不同,有不同的方法来实现这一点:
- 确认已在内核配置中设置
CONFIG_USER_NS=y
(通常在 /proc/config.gz 中找到) - Arch/Debian:
echo 1 > /proc/sys/kernel/unprivileged_userns_clone
- RHEL/CentOS 7:
echo 28633 > /proc/sys/user/max_user_namespaces
以普通用户身份运行以下命令:
# Same as the first example mkdir ~/mycontainer cd ~/mycontainer mkdir rootfs docker export $(docker create busybox) | tar -C rootfs -xvf - # The --rootless parameter instructs runc spec to generate a configuration for a rootless container, which will allow you to run the container as a non-root user. runc spec --rootless # The --root parameter tells runc where to store the container state. It must be writable by the user. runc --root /tmp/runc run mycontainerid
Supervisors
runc 可以与流程管理器和初始化系统一起使用,以确保容器退出时重新启动。 一个示例的 systemd unit 文件看起来像这样。
[Unit] Description=Start My Container [Service] Type=forking ExecStart=/usr/local/sbin/runc run -d --pid-file /run/mycontainerid.pid mycontainerid ExecStopPost=/usr/local/sbin/runc delete mycontainerid WorkingDirectory=/mycontainer PIDFile=/run/mycontainerid.pid [Install] WantedBy=multi-user.target
cgroup v2
许可
该代码和文档根据 Apache 2.0 许可发布。
(The first version translated by vz on 2020.07.19)