docker OCI runtime(待完善)
Posted charlieroro
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker OCI runtime(待完善)相关的知识,希望对你有一定的参考价值。
Open Container Initiative(OCI)目前有2个标准:runtime-spec以及image-spec。前者规定了如何运行解压过的filesystem bundle。OCI规定了如何下载OCI镜像并解压到OCI filesystem bundle,这样OCI runtime就可以运行OCI bundle了。OCI(当前)相当于规定了容器的images和runtime的协议,只要实现了OCI的容器就可以实现其兼容性和可移植性。implements中列出了部分OCI标准的实现。本文不讨论windows下的实现,具体参见Open Container Initiative Runtime Specification
system bundle是个目录,用于给runtime提供启动容器必备的配置文件和文件系统。标准的容器bundle包含以下内容:
config.json:该文件包含了容器运行的配置信息,该文件必须存在bundle的根目录,且名字必须为config.json
容器的根目录,可以由config.json中的root.path指定
下面使用runc来运行一个容器,runc是根据OCI标准生成的一个cli工具。前面两个命令用于提取filesystem,最后一个用于生成config.json,两者组织在一起就是一个filesystem bundle
# mkdir rootfs # docker export $(docker create busybox) | tar -C rootfs -xvf -
# runc spec
使用runc来运行这个bundle,可以使用state查看该容器的状态
# runc run busybox # runc state busybox { "ociVersion": "1.0.0", "id": "busybox", "pid": 41732, "status": "running", "bundle": "/home/test", "rootfs": "/home/test/rootfs", "created": "2018-12-25T14:41:58.82202891Z", "owner": ""
OCI runtime包含runtime,runtime-linux,config,config-linux
- runtime规定了如下内容
- state
ociVersion:创建容器时的OCI版本
- id:容器唯一的ID
- status:容器的runtime状态,可以为如下值
- creating:容器正在被创建(lifecycle的第2步)
- created:容器完成创建,但没有返回错误且没有执行用户程序(lifecycle的第2步之后)
- running:容器正在执行用户程序且没有返回错误(lifecycle的第5步之后)
- stoped:容器进程退出(lifecycle的第7步)
- pid:host上看到的容器进程
- bundle:host上容器bundle目录的绝对路径
- annotation:容器相关的标注,可选
- state
由于runc实现了OCI runtime,使用runc state查看上述busybox可以得到state相关的信息
{ "ociVersion": "1.0.0", "id": "busybox", "pid": 41732, "status": "running", "bundle": "/home/test", "rootfs": "/home/test/rootfs", "created": "2018-12-25T14:41:58.82202891Z", "owner": "" }
-
- lifecycle 描述了容器从创建到退出的事件触发点
- OCI runtime的create调用与bundle的路径和id相关
- OCI runtime的必须依据config.json中的设置来创建环境,如果无法创建config.json中指定的环境,则返回错误。此阶段主要创建config.json中的资源,并没有执行用户程序。该步骤之后任何多config.json的修改都不会影响容器
- runtime使用容器的唯一id来执行start容器命令
- runtine必须执行 prestart hooks,如果 prestart hooks执行失败,则返回错误,并停止容器,执行第9条操作
- runtime必须执行用户程序
- runtime必须执行poststart hooks,如果poststart hooks执行失败,则必须记录warning日志,而poststart hooks和lifecycle继续运行
- 容器进程退出,可能由错误退出,人为退出,程序崩溃或runtime 执行kill命令引起
- runtime使用容器的唯一id来执行delete容器操作
- 如果在容器创建阶段(第2步)没有完成某些步骤,则容器必须被销毁
- runtime必须执行poststop hooks,如果poststop hooks执行失败,则必须记录warning日志,而poststop hooks和lifecycle继续运行
- operation runtime必须支持如下操作
- query state:
state <container-id>,参见上述state描述
- create:
create <container-id> <path-to-bundle>,runtime应该提供检测id唯一性的功能。该操作中会用到config.json除process之外的配置属性(因为process实在start阶段用到的)。实现中可能会与本规范不一致,如在create操作之前实现了pre-create
- start:
start <container-id>,执行config.json的process中定义的程序,如果process没有设定,则返回错误
- kill:
kill <container-id> <signal>,向一个非running状态的容器发送的信号会被忽略。此操作用于向容器进程发送信号
- delete:
delete <container-id>,尝试删除一个非stopped的容器会返回错误。容器删除后其id可能会被后续的容器使用
- query state:
- lifecycle 描述了容器从创建到退出的事件触发点
# runc delete busybox
cannot delete container busybox that is not stopped: running
-
- hooks:定义了每个操作前后的动作,参见runtime configuration for hooks
- configuration定义了进程运行,环境变量等配置。现有json和go版本的配置,其中go中定义了与平台(linux,solaris,windows相关的tag),如下:
// Linux is platform-specific configuration for Linux based containers. Linux *Linux `json:"linux,omitempty" platform:"linux"` // Solaris is platform-specific configuration for Solaris based containers. Solaris *Solaris `json:"solaris,omitempty" platform:"solaris"` // Windows is platform-specific configuration for Windows based containers. Windows *Windows `json:"windows,omitempty" platform:"windows"` // VM specifies configuration for virtual-machine-based containers. VM *VM `json:"vm,omitempty" platform:"vm"`
-
- Specification version:必选,指定了bundle使用的OCI的版本
- root:
- path:容器的bundle路径,可以是相对路径和绝对路径,该值通常为rootfs
- readonly:当设置为true时,容器的根文件为只读,默认false
- mount:按照配置的顺序进行挂载
- destination:容器中的挂载点,必须是绝对路径
- source:挂载的设备名称,文件或目录名称(bind mount时),当option中有bind或rbind时改mount类型为bind mount
- option:mount的选项,参见mount
- process:定义了容器的进程信息
- terminal:默认false,为true时,linux系统会为该进程分配一个pseudoterminal(pts),并使用标准输入输出流
consoleSize:指定terminal的长宽规格,width和height
- cwd:执行命令的绝对路径
- env:环境变量
- args:命令参数,至少需要指定一个参数,首参数即被execvp执行的文件
根据平台不同支持如下配置
POSIX process 支持设置POSIX和Linux平台
-
- rlimits:设置进程的资源,如cpu,内存,文件大小等,参见getrlimit。docker里面使用--ulimit来设置单个进程的资源
- type:linux和Solaris
- soft:内核分配给该进程的资源
- hard;可配置的资源的最大值,即soft的最大值。unprivileged进程(没有CAP_SYS_RESOURCE capability)可以将soft设置为0-hard之间的值
- rlimits:设置进程的资源,如cpu,内存,文件大小等,参见getrlimit。docker里面使用--ulimit来设置单个进程的资源
Linux process:
-
apparmorProfile:指定进程的apparmor文件
capabilities:指定进程的
capabilities
noNewPrivileges:设置为true后可以防止进程获取额外的权限(如使得suid和文件capabilities失效),该标记位在内核4.10版本之后可以在/proc/$pid/status中查看NoNewPrivs的设置值。更多参见no_new_privs
oomScoreAdj
:给进程设置oom_score_adj值,进程的oom涉及以下3个文件,oom_adj和oom_score_adj功能类似,oom_adj主要用于兼容老版本,oomScoreAdj的功能就是设置/proc/$PID/oom_score_adj中的值(范围-1000~1000),系统通过该值和oom_score来决定kill进程的优先级。oom_score为只读文件,oom通过对系统所有进程的oom_score进行排序,值越大,越可能在内存不足时被kill掉。(参见linux oom机制分析和oom介绍)
/proc/$PID/oom_adj /proc/$PID/oom_score /proc/$PID/oom_score_adj
可以通过如下命令查看系统所有进程的oom_score
ps -eo pid,comm,pmem --sort -rss | awk ‘{"cat /proc/"$1"/oom_score" | getline oom; print $0" "oom}‘
-
selinuxLabel
:设置进程的SELinux 标签,即MAC值- user 用于控制运行进程的用户
- uid:指定容器命名空间的user id
- gid:指定容器命名空间的group id
- additionalGids:指定容器命名空间中附加的group id
- hostname:指定容器进程看到的hostname
- Platform-specific configuration:包含在linux,Windows,solaris,vm等host平台上使用namespaces,cgroup等。下面以linux为例
- Default Filesystems:如下路径需要正确挂载到容器中,以便容器进程的正确执行
Path Type /proc proc /sys sysfs /dev/pts devpts /dev/shm tmpfs
-
-
- namespaces,为包含如下参数的数组
- type:指定namespace类型,为ipc,mount,user,network,uts,pid,cgroup,如果没有指定namespace type,则继承父namespace的属性
- path:namespace的文件,如果没有指定,则生成一个新的namespace
- User namespace mappings,uidMappings和gidMappings指定了user和group从host到容器的映射关系,为结构图数组,包含containerid,hostid和size这3个属性
- device:列出了必须在容器中存在的设备,为结构体数组,有如下属性
- type:设备的类型
- path:容器中的全路径
- major, minor:设备的主设备号和次设备号,主设备号表示类型,次设备号表示分区,可以使用"ls -al /dev"查看主次设备号。设置可以参见device
- fileMode:文件ADC访问权限
- uid:容器中设备的uid
- gid:容器中设备的gid
- cgroup:用于控制容器的资源以及设备接入等。
- Cgroups Path:cgroup的路径(待cgroup完善湖更新)
- namespaces,为包含如下参数的数组
-
-
- POSIX-platform Hooks:支持使用hooks来设置lifecycle中用户自定义动作
- hooks
- prestart:在用户程序运行前以及容器命名空间创建后执行,包含如下属性的数组:
- path:类似execv的路径,为均对路径
- args:类似execv的参数
- env:环境变量
- timeout:终端hooks的超时时间
- poststart:在用户程序执行之后且在start步骤返回前执行,同 prestart的数组一样
- poststop:在容器删除之后且在delete步骤返回前执行,同prestart的数组一样
- prestart:在用户程序运行前以及容器命名空间创建后执行,包含如下属性的数组:
- hooks
- Annotations:为key-value类型的任意字符串,如果没有annotation,该字段可以为空,也可以不存在
- extensibility:遇到无法识别的字段需要返回错误
- POSIX-platform Hooks:支持使用hooks来设置lifecycle中用户自定义动作
- Linux Runtime:该规范规定了容器文件描述符相关的内容。默认下runtime只会打开stdin, stdout和stderr这3个文件描述符
runtime包含1, config.md, config-linux.md, and runtime-linux.md.
参考:
https://cizixs.com/2017/11/05/oci-and-runc/
https://github.com/opencontainers/runtime-spec/blob/master/config.md
https://github.com/opencontainers/runtime-spec/blob/master/specs-go/config.go
以上是关于docker OCI runtime(待完善)的主要内容,如果未能解决你的问题,请参考以下文章
docker: Error response from daemon: OCI runtime create failed 解决办法
Docker 问题集锦(24) - 解决:OCI runtime exec failed: exec failed: container_linux.go:367
docker OCI runtime create failed: /var/lib/dokveroverlay2/xxxxxxx/merged is not an absolute path or
CentOS7 docker报错 /usr/bin/docker-current: Error response from daemon: oci runtime error(需要禁用SELinux)
CentOS7 docker报错 /usr/bin/docker-current: Error response from daemon: oci runtime error(需要禁用SELinux)