runc

runc 是一个轻量级命令行工具,用于根据 OCI(Open Container Initiative)规范创建和运行容器。它是现代容器生态系统的最底层执行引擎,被 Docker、containerd、Podman、CRI-O 等几乎所有主流容器运行时所依赖。

基本概念

runc 用 Go 编写,直接调用 Linux 内核特性(如 namespaces、cgroups、capabilities、seccomp 等)。它不管理镜像、网络、存储卷,只负责”启动一个隔离的进程”。runc 的职责非常单一且关键:

功能说明
创建容器基于 config.json + rootfs 启动新进程
隔离环境使用 Linux namespaces(pid, net, ipc, mnt, user, uts)
资源限制通过 cgroups v1/v2 限制 CPU、内存、IO 等
安全控制支持 capabilities、seccomp、AppArmor、SELinux
生命周期管理start / stop / pause / resume / delete

工作流程:

+------------------+
| containerd       | ← 高层运行时(管理镜像、API)
+--------+---------+
         |
         | 提供 rootfs + config.json
         v
+--------+---------+
| runc             | ← 实际创建容器进程
+--------+---------+
         |
         v
+--------+---------+
| Linux Kernel     | ← namespaces, cgroups, capabilities...
+------------------+

典型调用链:

kubelet 
  → containerd (via CRI) 
    → runc 
      → fork/exec 容器进程

runc 的使用

postgres@slpc:~$ runc --help
NAME:
   runc - Open Container Initiative runtime

runc is a command line client for running applications packaged according to
the Open Container Initiative (OCI) format and is a compliant implementation of the
Open Container Initiative specification.

runc integrates well with existing process supervisors to provide a production
container runtime environment for applications. It can be used with your
existing process monitoring tools and the container will be spawned as a
direct child of the process supervisor.

Containers are configured using bundles. A bundle for a container is a directory
that includes a specification file named "config.json" and a root filesystem.
The root filesystem contains the contents of the container.

To start a new instance of a container:

    # runc run [ -b bundle ] <container-id>

Where "<container-id>" is your name for the instance of the container that you
are starting. The name you provide for the container instance must be unique on
your host. Providing the bundle directory using "-b" is optional. The default
value for "bundle" is the current directory.

USAGE:
   runc [global options] command [command options] [arguments...]

VERSION:
   1.2.5
commit: v1.2.5-0-g59923ef
spec: 1.2.0
go: go1.23.7
libseccomp: 2.5.5

COMMANDS:
   checkpoint  checkpoint a running container
   create      create a container
   delete      delete any resources held by the container often used with detached container
   events      display container events such as OOM notifications, cpu, memory, and IO usage statistics
   exec        execute new process inside the container
   kill        kill sends the specified signal (default: SIGTERM) to the container's init process
   list        lists containers started by runc with the given root
   pause       pause suspends all processes inside the container
   ps          ps displays the processes running inside a container
   restore     restore a container from a previous checkpoint
   resume      resumes all processes that have been previously paused
   run         create and run a container
   spec        create a new specification file
   start       executes the user defined process in a created container
   state       output the state of a container
   update      update container resource constraints
   features    show the enabled features
   help, h     Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug             enable debug logging
   --log value         set the log file to write runc logs to (default is '/dev/stderr')
   --log-format value  set the log format ('text' (default), or 'json') (default: "text")
   --root value        root directory for storage of container state (this should be located in tmpfs) (default: "/run/user/1001/runc")
   --systemd-cgroup    enable systemd cgroup support, expects cgroupsPath to be of form "slice:prefix:name" for e.g. "system.slice:runc:434234"
   --rootless value    ignore cgroup permission errors ('true', 'false', or 'auto') (default: "auto")
   --help, -h          show help
   --version, -v       print the version

runc 工作演示

准备 rootfs(容器文件系统):

# 创建目录
mkdir mycontainer
cd mycontainer

mkdir rootfs

# 导出一个 Alpine 镜像的 rootfs(需先有 Docker)
docker export $(docker create alpine) | tar -C rootfs -xvf -

生成 OCI 配置文件:

# 生成默认 config.json
runc spec

运行容器:

# 在前台运行(会占用终端)
sudo runc run mycontainer-id

# 或后台运行
sudo runc run -d mycontainer-id

管理容器:

root@slpc:~# runc list
ID               PID         STATUS      BUNDLE                                                          CREATED                          OWNER
mycontainer-id   28216       running     /home/postgres/works/my-github/dbnotes/kubernetes/mycontainer   2025-12-16T02:42:13.374563293Z   root

root@slpc:~# runc state mycontainer-id
{
  "ociVersion": "1.2.0",
  "id": "mycontainer-id",
  "pid": 28216,
  "status": "running",
  "bundle": "/home/postgres/works/my-github/dbnotes/kubernetes/mycontainer",
  "rootfs": "/home/postgres/works/my-github/dbnotes/kubernetes/mycontainer/rootfs",
  "created": "2025-12-16T02:42:13.374563293Z",
  "owner": ""
}

runc kill mycontainer-id SIGKILL

runc 与 containerd / Docker 的关系

组件角色
Docker Engine高层工具(build, push, network, volume)
containerd中间层运行时(管理生命周期、镜像、CRI)
runc底层执行器(实际调用 kernel 创建容器)

当 containerd 需要启动容器时,它会:

  • 准备 rootfs(从 snapshotter 解压)
  • 生成 OCI config.json
  • 执行 runc create + runc start

runc 在 K8s 中至关重要:

  • kubelet → 调用 containerd(via CRI)
  • containerd → 调用 runc 创建 pause 容器和业务容器
  • runc → 调用 Linux 内核创建隔离进程

总结

项目说明
定位OCI 标准的容器执行引擎
核心作用调用 Linux 内核特性创建隔离进程
是否独立使用一般不直接使用(由 containerd / Podman 调用)
Kubernetes 角色底层容器创建器(不可或缺)
关键优势轻量、标准、安全、高性能

💡 你可以把 runc 理解为”容器世界的 execve()” —— 它是让容器真正”跑起来”的最后一环。