runc和bundle
runC 是 Docker 公司按照 OCI 标准规范编写的一个操作容器的命令行工具,其前身是 libcontainer 项目演化而来,runC 实际上就是 libcontainer 配上了一个轻型的客户端,是一个命令行工具端,根据 OCI(开放容器组织)的标准来创建和运行容器,实现了容器启停、资源隔离等功能。runc的主要作用是使用Linux Kernel提供的诸如namespaces, cgroup等进程隔离机制以及SELinux等security功能,构建供容器运行的隔离环境。
docker run命令启动容器时,其中有两个步骤,第一个是解压镜像,第二个是启动容器。runc就是用来启动容器的,在containerd那一步会进行解压镜像,创建bundle文件。
下面是一个runc启动容器的例子:
1、已有镜像busybox:latest,将tar文件解压后制作成容器所需的Filesystem bundle,然后使用runc spec
命令获得设置文件(config.json)。
#mkdir busybox
#cd busybox
#mkdir rootfs
#docker export $(docker create busybox) | tar -C rootfs -xvf -
#ls rootfs
bin dev etc home proc root sys tmp usr var
#runc spec -b rootfs
#ls
config.json rootfs
2、运行runc run
,Filesystem bundle作为参数,启动容器
#cd ..
#runc run --bundle busybox/ demo1
/ # ls
bin dev etc home proc root sys tmp usr var
/ #
所以bundle中包括镜像解压后的文件,config.json(该文件包含了容器运行的配置信息,该文件必须存在bundle的根目录,且名字必须为config.json)
bundle一般存在/run/containerd/io.containerd.runtime.v1.linux/moby/container-id中
/run/docker/runtime-runc/moby/container-id/state.json是容器的状态文件
ps:
1、config.json文件的示例:关于每一项内容的意思,可参考https://github.com/opencontainers/runtime-spec/blob/main/config.md
{
"ociVersion": "1.0.1",
"process": {
"terminal": true,
"user": {
"uid": 1,
"gid": 1,
"additionalGids": [
5,
6
]
},
"args": [
"sh" 这个是容器启动命令
],
"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"
],
"permitted": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
],
"inheritable": [
"CAP_AUDIT_WRITE",
"CAP_KILL",
"CAP_NET_BIND_SERVICE"
],
"effective": [
"CAP_AUDIT_WRITE",
"CAP_KILL"
],
"ambient": [
"CAP_NET_BIND_SERVICE"
]
},
"rlimits": [
{
"type": "RLIMIT_CORE",
"hard": 1024,
"soft": 1024
},
{
"type": "RLIMIT_NOFILE",
"hard": 1024,
"soft": 1024
}
],
"apparmorProfile": "acme_secure_profile",
"oomScoreAdj": 100,
"selinuxLabel": "system_u:system_r:svirt_lxc_net_t:s0:c124,c675",
"noNewPrivileges": true
},
"root": {
"path": "rootfs",
"readonly": true
},
"hostname": "slartibartfast",
"mounts": [
{
"destination": "/proc",
"type": "proc",
"source": "proc"
},
{
"destination": "/dev",
"type": "tmpfs",
"source": "tmpfs",
"options": [
"nosuid",
"strictatime",
"mode=755",
"size=65536k"
]
},
{
"destination": "/dev/pts",
"type": "devpts",
"source": "devpts",
"options": [
"nosuid",
"noexec",
"newinstance",
"ptmxmode=0666",
"mode=0620",
"gid=5"
]
},
{
"destination": "/dev/shm",
"type": "tmpfs",
"source": "shm",
"options": [
"nosuid",
"noexec",
"nodev",
"mode=1777",
"size=65536k"
]
},
{
"destination": "/dev/mqueue",
"type": "mqueue",
"source": "mqueue",
"options": [
"nosuid",
"noexec",
"nodev"
]
},
{
"destination": "/sys",
"type": "sysfs",
"source": "sysfs",
"options": [
"nosuid",
"noexec