Runc 创建、启动和删除容器的调用参数

How runc create, start and delete container?

Posted by PYQ on September 7, 2023

runc是一个基于oci标准实现的一个轻量级容器运行工具,用来创建和运行容器。runc也是最流行的底层运行时工具,docker和k8s等均默认采用runc作为其底层运行时。通常我们不会直接去使用runc去创建和管理容器,也不建议我们直接去操作,而是由更高级的容器运行时(containerd、cri-o等)进行操作和管理。而用户则直接通过docker或者k8s提供的工具和命令与高级容器运行时进行交互,高级容器运行时再下发命令给runc进行容器创建和运行等操作。

Docker、Containerd、RunC分别是什么

在使用oci-add-hooks的过程中出了一些问题,为了找出问题所在,对源码进行了修改,添加了日志输出。因此也借这个机会对通过docker run等命令对容器进行操作时,传递给runc的具体参数是什么有一个了解和记录。

runc

首先看看runc的一个官方描述。

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.

最重要的是第三段,容器是通过bundle进行配置的。bundle包括了容器的配置文件config.json和包含容器内容的root filesystem。

runc的使用。

1
2
3
4
5
6
7
8
9
10
11
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...]

启动一个容器实例最简单的方法是通过runc run [ -b bundle ] <container-id>,bundle默认为当前目录,并且container-id需要是唯一的。

runc的命令和选项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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/1000/runc")
   --criu value        path to the criu binary used for checkpoint and restore (default: "criu")
   --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

How runc create, start and delete container?

日志输出的runc create时的调用参数如下,准确来说应该是global options。

  1. –root指定了用于存储容器状态的根目录,前面对这个根目录的描述提到需要是tmpfs(类Unix系统上暂存档存储空间的常见名称,通常以挂载文件系统方式实现,并将资料存储在易失性存储器即内存而非永久存储设备中),这里是/var/run/docker/runtime-runc/moby。关于moby的介绍
  2. –log指定了runc日志文件。
  3. –log-format指定了runc日志文件格式为json。
  4. –systemd-cgroup开启systemd cgroup支持,这也是容器资源隔离机制的关键。
  5. –bundle指定的目录和runc日志的目录一致。
  6. –pid-file指定了容器进程的pid路径。
1
2
3
4
5
6
7
8
--root /var/run/docker/runtime-runc/moby --log
/run/containerd/io.containerd.runtime.v2.task/moby/6dbd69e6f9e0c7efe3026ae83624012fce6917e2f7e2c73958b8530d369fef05/log.json --log-format json --systemd-cgroup 
create --bundle 
/run/containerd/io.containerd.runtime.v2.task/moby/6dbd69e6f9e0c7efe3026ae83624012
fce6917e2f7e2c73958b8530d369fef05 --pid-file 
/run/containerd/io.containerd.runtime.v2.task/moby/6dbd69e6f9e0c7efe3026ae83624012
fce6917e2f7e2c73958b8530d369fef05/init.pid 
6dbd69e6f9e0c7efe3026ae83624012fce6917e2f7e2c73958b8530d369fef05

日志输出的runc start时的调用参数如下,相比于create参数少了一些,基本参数保持一致,6dbd69e…为容器id。

1
2
3
4
 --root /var/run/docker/runtime-runc/moby --log 
/run/containerd/io.containerd.runtime.v2.task/moby/6dbd69e6f9e0c7efe3026ae83624012
fce6917e2f7e2c73958b8530d369fef05/log.json --log-format json --systemd-cgroup 
start 6dbd69e6f9e0c7efe3026ae83624012fce6917e2f7e2c73958b8530d369fef05

日志输出的runc delete时的调用参数如下,和start的参数一致。

1
2
3
4
--root /var/run/docker/runtime-runc/moby --log 
/run/containerd/io.containerd.runtime.v2.task/moby/6dbd69e6f9e0c7efe3026ae83624012
fce6917e2f7e2c73958b8530d369fef05/log.json --log-format json --systemd-cgroup 
delete 6dbd69e6f9e0c7efe3026ae83624012fce6917e2f7e2c73958b8530d369fef05

在runc delete后,还有个runc delete –force的操作,参数如下。

1
2
3
4
--root /var/run/docker/runtime-runc/moby --log 
/run/containerd/io.containerd.runtime.v2.task/moby/6dbd69e6f9e0c7efe3026ae83624012
fce6917e2f7e2c73958b8530d369fef05/log.json --log-format json delete --force 
6dbd69e6f9e0c7efe3026ae83624012fce6917e2f7e2c73958b8530d369fef05