runc是一个基于oci标准实现的一个轻量级容器运行工具,用来创建和运行容器。runc也是最流行的底层运行时工具,docker和k8s等均默认采用runc作为其底层运行时。通常我们不会直接去使用runc去创建和管理容器,也不建议我们直接去操作,而是由更高级的容器运行时(containerd、cri-o等)进行操作和管理。而用户则直接通过docker或者k8s提供的工具和命令与高级容器运行时进行交互,高级容器运行时再下发命令给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。
- –root指定了用于存储容器状态的根目录,前面对这个根目录的描述提到需要是tmpfs(类Unix系统上暂存档存储空间的常见名称,通常以挂载文件系统方式实现,并将资料存储在易失性存储器即内存而非永久存储设备中),这里是/var/run/docker/runtime-runc/moby。关于moby的介绍
- –log指定了runc日志文件。
- –log-format指定了runc日志文件格式为json。
- –systemd-cgroup开启systemd cgroup支持,这也是容器资源隔离机制的关键。
- –bundle指定的目录和runc日志的目录一致。
- –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