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",idbusyboxpid41732statusrunningbundle/home/testrootfs/home/test/rootfscreated2018-12-25T14:41:58.82202891Zowner""

 

OCI runtime包含runtimeruntime-linuxconfigconfig-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:容器相关的标注,可选

由于runc实现了OCI runtime,使用runc state查看上述busybox可以得到state相关的信息

{
   ""
}
    • lifecycle 描述了容器从创建到退出的事件触发点
      1. OCI runtime的create调用与bundle的路径和id相关
      2. OCI runtime的必须依据config.json中的设置来创建环境,如果无法创建config.json中指定的环境,则返回错误。此阶段主要创建config.json中的资源,并没有执行用户程序。该步骤之后任何多config.json的修改都不会影响容器
      3. runtime使用容器的唯一id来执行start容器命令
      4. runtine必须执行 prestart hooks,如果 prestart hooks执行失败,则返回错误,并停止容器,执行第9条操作
      5. runtime必须执行用户程序
      6. runtime必须执行poststart hooks,如果poststart hooks执行失败,则必须记录warning日志,而poststart hooks和lifecycle继续运行
      7. 容器进程退出,可能由错误退出,人为退出,程序崩溃或runtime 执行kill命令引起
      8. runtime使用容器的唯一id来执行delete容器操作
      9. 如果在容器创建阶段(第2步)没有完成某些步骤,则容器必须被销毁
      10. 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可能会被后续的容器使用
# runc delete busybox
cannot delete container busybox that is not stopped: running
  • configuration定义了进程运行,环境变量等配置。现有jsongo版本的配置,其中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,1)">solaris Windows is platform-specific configuration for Windows based containers.
Windows *Windows `json:windows,1)">windows VM specifies configuration for virtual-machine-based containers.
VM *VM `json:vm,1)">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之间的值

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"\t"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会使用默认的cgroup路径

可以使用resources字段来配置cgroup,注意:只有在需要更新cgroup的时候才配置该字段内容

    cgroupsPath/myRuntime/myContainerresources: {
        memorylimit100000reservation200000
        },1)">devices: [
            {
                allow": falseaccessrwm
            }
        ]
   }

Device whitelist:用于配置设备白名单

  • allow (boolean,REQUIRED) -允许
  • type (string,OPTIONAL) - 设备类似: a (all),c (char),or b (block). 默认为all
  • major,minor (int64,OPTIONAL) - 设备的主次号. 默认all
  • access (string,OPTIONAL) - 设备的cgroup权限.r (read),w (write),和m (mknod).

Memory:具体可以参见cgroup memory

  • limit (int64,OPTIONAL) - 设置内存使用limit
  • reservation (int64,OPTIONAL) - 设置内存的soft limit
  • swap (int64,OPTIONAL) - 设置memory+Swap使用limit
  • kernel (int64,OPTIONAL) -  设置内存的hard limit
  • kernelTCP (int64,OPTIONAL) - 设置内核TCP buffer的hard limit
  • swapness:设置swap的使用比例
  • disableOOMKiller:是否开启oomkiller

CPU:具体可以参见cgroup CPU

  • shares (uint64,OPTIONAL) - cgroup中task使用的cpu的相对比例
  • quota (int64,OPTIONAL) - 一个period中使用的cpu时间
  • period (uint64,OPTIONAL) - 以毫秒为单位的cpu周期 (CFS scheduler only)
  • realtimeRuntime (int64,OPTIONAL) - 以毫秒为单位的 cgroup tasks连续使用cpu资源的最长周期
  • realtimePeriod (uint64,OPTIONAL) - 实时调度的 period
  • cpus (string,OPTIONAL) - CPU列表
  • mems (string,OPTIONAL) - memory nodes列表

Block IO:

Huge page limits:

  • pageSize :大页大小
  • limit:bytes为单位限制的大页的使用上限

Network:

  • classID:cgroup网络报文的标签
  • priorities

name:网卡名称
priority:网卡优先级

PIDs:

limit:cgroup限制的pid的数目

RDMA

Sysctl:允许在容器运行过程中修改内核参数

Seccomp:在linux内核中为应用提供了一种沙盒机制。更多参见seccomp

seccomp

defaultAction:seccomp的默认动作,允许值类型为syscalls[].action

architectures:系统调用的平台,如下

SCMP_ARCH_X86
SCMP_ARCH_X86_64
SCMP_ARCH_X32
SCMP_ARCH_ARM
SCMP_ARCH_AARCH64
SCMP_ARCH_MIPS
SCMP_ARCH_MIPS64
SCMP_ARCH_MIPS64N32
SCMP_ARCH_MIPSEL
SCMP_ARCH_MIPSEL64
SCMP_ARCH_MIPSEL64N32
SCMP_ARCH_PPC
SCMP_ARCH_PPC64
SCMP_ARCH_PPC64LE
SCMP_ARCH_S390
SCMP_ARCH_S390X
SCMP_ARCH_PARISC
SCMP_ARCH_PARISC6

syscalls:匹配seccomp的系统调用,该属性可选

name:系统调用的名称,至少有一个

action:seccomp的动作规则。libseccomp v2.3.2中如下:

SCMP_ACT_KILL
SCMP_ACT_TRAP
SCMP_ACT_ERRNO
SCMP_ACT_TRACE
SCMP_ACT_ALLOW

args:

index (uint,REQUIRED) - 系统调用的index
value (uint64,REQUIRED) - 系统调用参数的值
valueTwo (uint64,OPTIONAL) - 系统调用参数的值
op (string,REQUIRED) - 系统调用参数的动作。 libseccomp v2.3.2如下

SCMP_CMP_NE
SCMP_CMP_LT
SCMP_CMP_LE
SCMP_CMP_EQ
SCMP_CMP_GE
SCMP_CMP_GT
SCMP_CMP_MASKED_EQ

Rootfs Mount Propagation

rootfsPropagation:设置rootfs的mount Propagation类型,slave,private或shared

      • Linux Runtime:该规范规定了容器文件描述符相关的内容。默认下runtime只会打开stdin,stdout和stderr这3个文件描述符

Masked Paths

maskedPaths:容器无法读取该设置的路径

    "maskedPaths": [
        "/proc/kcore"
    ]

Readonly Paths

readonlyPaths:容器只读该设置的路径

    • POSIX-platform Hooks:支持使用hooks来设置lifecycle中用户自定义动作
      • hooks
        • prestart:在用户程序运行前以及容器命名空间创建后执行,包含如下属性的数组:
          • path:类似execv的路径,为均对路径
          • args:类似execv的参数
          • env:环境变量
          • timeout:终端hooks的超时时间
        • poststart:在用户程序执行之后且在start步骤返回前执行,同 prestart的数组一样
        • poststop:在容器删除之后且在delete步骤返回前执行,同prestart的数组一样
    • Annotations:为key-value类型的任意字符串,如果没有annotation,该字段可以为空,也可以不存在
    • extensibility:遇到无法识别的字段需要返回错误

 TIPS:

  • openshift 3.11版本的runc采用的是其自己实现的runtime,位于/usr/libexec/docker/docker-runc-current,实际与runc类似。

 

参考:

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

Rootfs Mount Propagation

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


最近一直在开发Apworks框架的案例代码,同时也在一起修复Apworks框架中的Bug和一些设计上的不足。遇到的一个普遍问题是,代码的调试过程需要依赖很多外部系统,比如MongoDB、PostgreSQL、RabbitMQ等。当然可以在本机逐一安装这些服务,然后对服务进行配置,使其满足自己开发调试
最近每天都在空闲时间努力编写Apworks框架的案例代码WeText。在文本发布和处理微服务中,我打算使用微软的SQL Server for Linux来做演示,于是也就在自己的docker-compose中加入了MS SQL Server的服务。其实在Docker中运行SQL Server是非常容
在《Kubernetes中分布式存储Rook-Ceph部署快速演练》文章中,我快速介绍了Kubernetes中分布式存储Rook-Ceph的部署过程,这里介绍如何在部署于Kubernetes的ASP.NET Core MVC的应用程序中使用Rook-Ceph所创建的存储对象。 构建ASP.NET C
最近在项目中有涉及到Kubernetes的分布式存储部分的内容,也抽空多了解了一些。项目主要基于Rook-Ceph运行,考虑到Rook-Ceph部署也不那么简单,官方文档的步骤起点也不算低,因此,在整合官方文档的某些步骤的基础上,写篇文章简单总结一下。 Rook-Ceph是Kubernetes中分布
CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.netcore(二) 之 Dockerfile CentOS下Docker与.netcore(三)之 三剑客之一Docker-Compose CentOS下Docker与.netcore(四)之 三剑客之一D
CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.netcore(二) 之 Dockerfile CentOS下Docker与.netcore(三)之 三剑客之一Docker-Compose CentOS下Docker与.netcore(四)之 三剑客之一D
构建镜像最具挑战性的一点是使镜像大小尽可能的小。Dockerfile中的每条指令都为图像添加了一个图层,您需要记住在移动到下一层之前清理任何不需要的工件。对于多阶段构建,您可以在Dockerfile中使用多个FROM语句。每个FROM指令可以使用不同的基础,并且每个指令都开始一个新的构建。您可以选择
本文介绍compose配置文件参数的使用,熟练编写compose文件 [root@docker lnmp]# cat lnmp.yaml version: &#39;3&#39; services: nginx: build: /root/docker_demo/nginx/ ports: - &q
环境 docker-machine主机:192.168.1.9 docker主机:192.168.1.10 步骤: 安装docker-machine 创建ssh密钥对,实现两主机无密登录 创建docker主机,命名host1 变更docker环境变量 运行容器查看两端是否同步 镜像容器同步测试成功
CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.netcore(二) 之 Dockerfile CentOS下Docker与.netcore(三)之 三剑客之一Docker-Compose CentOS下Docker与.netcore(四)之 三剑客之一D
https://blog.csdn.net/wanglei_storage/article/details/77508620 实践中会发现,生产环境中使用单个 Docker 节点是远远不够的,搭建 Docker 集群势在必行。然而,面对 Kubernetes, Mesos 以及 Swarm 等众多容
1.引言 紧接上篇.NET Core容器化@Docker,这一节我们先来介绍如何使用Nginx来完成.NET Core应用的反向代理,然后再介绍多容器应用的部署问题。 2. Why Need Nginx .NET Core中默认的Web Server为Kestrel。 Kestrel is grea
docker rm `docker ps -a | grep Exited | awk &#39;{print $1}&#39;` 删除异常停止的docker容器 docker rmi -f `docker images | grep &#39;&lt;none&gt;&#39; | awk &#3
什么是Docker Compose 在微服务盛行的今天,我们通常是这么定义Compose的:对容器的统一启动和关闭的编排工具。 但是我以前还是有个疑惑,谁会用Compose在一台服务器上部署多个服务呢?干脆直接用单体服务就行了!直到我遇到了以下的一个需求,让我明白了在一台服务器上不得不用多个服务的时
CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.netcore(二) 之 Dockerfile CentOS下Docker与.netcore(三)之 三剑客之一Docker-Compose CentOS下Docker与.netcore(四)之 三剑客之一D
很多时候,我们在本地开发过程中程序运行很正常,但是发布到线上之后由于环境的原因,可能会有一些异常。通常我们会通过日志来分析问题,除了日志还有一种常用的调试手段就是:附加进程。 VS中的附加进程非常强大,目前提供了9种常用的附加方式。 在当前.Net Core支持跨平台的大背景下,其中Linux环境和
https://www.cnblogs.com/bigberg/p/8867326.html 一、简介 Docker有个编排工具docker-compose,可以将组成某个应该的多个docker容器编排在一起,同时管理。同样在Swarm集群中,可以使用docker stack 将一组相关联的服务进行
.Net6中想实现对某个网址截屏,可通过Selenium模拟访问网址并实现截图。 实现 安装Nuget包 &lt;PackageReference Include=&quot;Selenium.Chrome.WebDriver&quot; Version=&quot;85.0.0&quot; /&g
原文&#160;https://www.cnblogs.com/gispathfinder/p/5871043.html 我们在使用docker run创建Docker容器时,可以用--net选项指定容器的网络模式,Docker有以下4种网络模式: host模式,使用--net=host指定。 co