OCI Runtime spec 运行时规范

OCI Runtime spec 运行时规范

一 概述

参考

OCI 运行时规范目的是为了标准化一个容器的配置执行环境生命周期管理。容器的配置文件由名为 config.json 文件内指定,配置文件内容提供所支持系统平台和创建一个容器所需的详细信息。执行环境是为了确保在容器内运行的应用程序与运行时具备的一致的环境,以及为容器的生命周期管理定义的了标准的公共操作。

容器原则

参考

OCI 定义软件交付的最小单元称之为"标准容器",标准容器是为了按自描述性和可移值性的格式封装应用程序及其依赖的所有组件,实现任何遵从规范的运行时再无需额外依赖的运行,以及与底层机器设备和容器内部内容都无关。

标准容器的5个原则:

  • 标准操作
  • 内容无关
  • 基础设施无关
  • 为自动化设计
  • 工业级交付

二 容器文件系统包

参考

OCI Image 可通过镜像名称发现、下载、hash值来验证、签名受信以及解包成 OCI 运行时 Bundle。一个标准的容器 bundle 包含容器加载和运行所有所需的信息,其包含如下:

  1. config.json 容器配置数据文件,必须与文件系统同目录下,文件名必须为 config.json。后面配置部分有详细说明此 config 定义内容与详解。
  2. root filesystem 容器 root 文件系统(启动的只读文件),在 config.json 文件内有指定 root.path。

三 运行时与生命周期

参考

容器作用域

除了访问控制问题,使用运行时创建容器的实体必须能够针对同一容器使用本规范中定义的操作。其他实体使用相同或其他实例的运行时是否可以看到该容器超出本规范的范围。

State 容器状态

容器的状态至少 必须 包含以下的属性:

  • ociVersion: string 创建容器时用到的规范的版本号
  • id: string 容器 ID, 必须 是本地唯一的,但不要求跨主机唯一。
  • status: string 容器的运行时状态。可能是以下值中的一个:
    • created : 容器已经被创建,但是用户代码未被执行。
    • running : 容器被创建,且用户代码正在运行。
    • stopped : 容器被创建,用户代码执行完毕,但不在继续运行。

新的状态可以由运行时自定义,但是它们 必须 用来表示未在上面定义的新运行时状态。

  • pid: int 主机可见的容器进程 ID。
  • bundlePath: string 容器 bundle 目录的绝对路径。提供给 consumers 查找容器的配置和 rootfs 。
  • annotations: map 包含了容器相关的注解列表。如果没提供任何的注解,则 可能 不存在或是个空map。

当使用JSON序列化时,其格式 必须 遵守以下样式:

{
    "ociVersion": "0.2.0",
    "id": "oci-container1",
    "status": "running",
    "pid": 4422,
    "bundlePath": "/containers/redis",
    "annotations": {
        "myKey": "myValue"
    }
}

有关检索容器的状态信息,请看query state。

LifeCycle 容器的生命周期

生命周期描述了从容器被创建到停止退出之间的事件的时间线。

  • create 命令需要配合 bundle 文件地址和唯一 ID 调用。
  • 必须 通过 config.json 中的配置创建容器的运行时环境,如果运行时无法创建环境, 必须 报错。虽然 必须 创建 config.json 中请求的资源,但用户代码不能在此时运行。此阶段后对 config.json 的任何更改 一定不能 影响到容器。
  • 容器所创建的附加操作基于运行时特征选择性的可能被执行,因此有些操作仅基于当前容器的状态才可能有效(如仅有效于运行态)。
  • start 命令需要配合容器的唯一 ID 调用。运行时 必须 通过指定的进程执行用户代码。
  • 容器的进程停止, 可能 是由于进程出错,退出,宕机或调用了运行时的 kill 命令。
  • delete命令需要配合容器的唯一 ID 调用。 必须回滚在 create 阶段期间执行的步骤销毁容器。

Errors 报错

(本规范列举的)操作报错的情况下, 本规范不强制要求具体实现(比如 runc )如何/是否返回或暴露错误给用户。除非另有说明,否则报错后 必须 重置环境的状态到操作没被执行过一样——除了像日志这种比较小的修改。

Operations 操作容器

除非底层的操作系统无法支持,否则兼容 OCI 的运行时 必须 支持下列的操作。这些操作不指定任何命令行 API ,并且这些参数是用于一般操作的入参。

Query State 状态查询

state 

此操作在不提供容器 ID 时 必须 报错。尝试查询一个不存在的容器 必须 报错。此操作 必须 返回同状态一节指定的容器的状态(信息)。

Create 容器创建

create  

此操作在不提供 bundle 文件的路径和容器 ID 时 必须 报错。如果提供了一个在 runtime(管理的)范围内不唯一,或者无效的 ID,其底层实现 必须 报错,且容易 一定不能 被创建。利用 config.json 文件里的数据,此操作 必须 创建一个新的容器,这意味着该容器相关的资源 必须 被创建,但是,用户指定的代码在此阶段 一定不能 被执行。如果运行时不能依照如 config.md 指定的容器,则 必须 报错,且新容器 一定不能 被创建。

成功完成此操作后,此容器的 status属性值 必须created

运行时在创建容器前(步骤2),可以 根据此规范一般或相对于当前系统的能力验证 config.json。 运行时的调用者如果感兴趣 pre-create 校验,可以在此操作(create)前调用 bundle-validation tools 。

成功执行完成此操作后,容器 必须 被创建好。

再此操作执行成功之后,任何针对config.json的修改都不会影响到(创建出来的)容器。

Start 容器运行

start 

此操作在不提供容器ID时 必须 报错。尝试启动一个不存在的容器 必须 报错。尝试启动一个已经运行的容器 必须 没有任何效果,且 必须 报错。此操作 必须进程运行用户代码。

成功执行完成此操作后,此容器的status属性值 必须running

Kill 容器停止

kill  

此操作在不提供容器ID时 必须 报错。尝试向一个非运行的容器发送信号量, 必须 没有任何效果,并且 必须 报错。此操作 必须 向容器内的进程发送指定的信号量。

当容器内的进程停止了,不管是kill操作还是其他原因导致的,这个容器的status属性值 必须stopped

Delete 删除容器

delete 

此操作在不提供容器 ID 时 必须 报错。尝试删除一个不存在容器 必须 报错。尝试删除一个其进程仍然运行的容器 必须 报错。删除容器 必须 释放其创建时申请的资源。注意,非容器创建的, 但是相关的资源, 一定不能 被删除。一旦容器被删除,它的 ID 可能 分配给后续的容器使用。

Hook 容器执行勾子

在本规范中提到的许多操作,都允许在每个操作之前或之后采取附加动作的“钩子”。更多“钩子”的信息请参考运行时配置 hooks 。

Linux 运行时

默认情况下,运行时仅为应用程序打开 stdinstdoutstderr 的文件描述符。 运行时 也可以 给应用程序传入额外的文件描述,以支持如 socket activation 等功能。 有些文件描述符 可能 被重定向到了 /dev/null,即使他们是打开的。

设备符号链接

当(生命周期管理的步骤2)创建容器时,运行时须创建以下标准的符号链接:

Source Destination
/proc/self/fd /dev/fd
/proc/self/fd/0 /dev/stdin
/proc/self/fd/1 /dev/stdout
/proc/self/fd/2 /dev/stderr

四 配置( Linux spec )

容器的顶级目录 必须 包含一个名为 config.json 的配置文件。 本文档中定义的是典型的结构,但是还有 JSON 结构 schema/config-schema.json 和 Go 版本的 specs-go/config.go 。

配置文件包含对容器执行标准操作所需的元数据。这包括运行的进程,要注入的环境变量,要使用的沙箱功能等。

下面是配置文件中定义的每个字段的详细描述。

Specification version

  • ociVersion string, REQUIRED 必须 是符合 SemVer v2.0.0 格式的,并且指定 bundle 符合的开放容器运行时规范的版本。开放容器运行时规范遵守语义化版本并保证 major 版本的向前/后兼容性。例如,如果一个配置兼容本规范的1.1版本,则它必须兼容所有支持1.1和后续版本的运行时),但是不兼容支持1.0的运行时。

示例:

 "ociVersion": "0.1.0"

Root Configuration

root 配置容器的 rootfs 。

  • path string, REQUIRED 指定容器的rootfs路径。 路径可以是绝对路径(以/开头),也可以是相对于bundle的相对路径(不以/开头)。 举个例子, bundle 的目录是 /to/bundle,rootfs 的目录是 /to/bundle/rootfs,那么 path 的值可以写成 /to/bundle/rootfs(绝对路径写法)或 rootfs(相对路径写法)。 path 内填写的目录 必须 存在。
  • readonly bool, OPTIONAL 设置成 true 则容器内的 rootfs 必须 是只读的,默认是 false 。

示例:

"root": {
    "path": "rootfs",
    "readonly": true
}

Mounts

mounts 配置额外的 mount (在 root 之上), 参数与 the Linux mount system call 类似。

  • destination string, REQUIRED 挂载点的目标地址:容器内的路径。此指必须是绝对路径。
  • type string, REQUIRED 需要 mount 的文件系统类型。支持 /proc/filesystems 中列举的文件系统类型(如“minix”,“ext2”,“ext3”,“jfs”,“xfs”,“reiserfs”,”msdos“,”proc“,”nfs“, "iso9660")。 Windows:ntfs。
  • source string, REQUIRED 设备名,也可以是目录名或虚拟设备。
  • options list of strings, OPTIONAL 文件系统 mount 参数。 Linux: [supported](http://man7.org/linux/man-pages/man8/mount.8.html#FILESYSTEM-INDEPENDENT_MOUNT OPTIONS) [options](http://man7.org/linux/man-pages/man8/mount.8.html#FILESYSTEM-SPECIFIC_MOUNT OPTIONS) are listed in mount(8).

示例:

"mounts": [
    {
        "destination": "/tmp",
        "type": "tmpfs",
        "source": "tmpfs",
        "options": ["nosuid","strictatime","mode=755","size=65536k"]
    },
    {
        "destination": "/data",
        "type": "bind",
        "source": "/volumes/testing",
        "options": ["rbind","rw"]
    }
]

Process configuration

process 配置容器的进程。

  • terminal bool, optional 指定是否需要连接该进程的终端,默认是 false。
  • consoleSize object, OPTIONAL 指定终端的控制台窗口大小(如果连接了终端),包含以下属性:
    • height uint, REQUIRED
    • width uint, REQUIRED
  • cwd string, REQUIRED 为可执行文件设置工作目录。此值 必须 是绝对路径。
  • env array of strings, OPTIONAL 包含一组在进程执行前设置到其环境中的变量。数组里的元素指定为 “KEY=value” 格式的字符串。左侧(KEY) 必须 只包含字母,数字和下划线'_',如IEEE Std 1003.1-2001.
  • args array of strings, REQUIRED 可执行文件和一组标志(flags)。可执行文件是第一个数组的第一个元素,并且 必须 存在于给定的路径里。如果可执行文件的路径不是绝对路径,则通过 $PATH 查找可执行文件。

对于基于Linux的系统,进程结构支持以下特定字段:

  • capabilities array of strings, OPTIONAL capabilities是一个数组,用于指定可以提供给容器内部进程的capabilities。有效值均是字符串,且定义在the man page。
  • rlimits array of rlimits, OPTIONAL rlimits是一个数组,用于指定容器内的进程资源的限制。内核支持两种资源限制模式 soft 和 hard ,hard 表示强制的最高的上限。限制值可可通过一个非特权进程进行设置,有效值与资源类型字段定义在 the man page.
  • apparmorProfile string, OPTIONAL 指定容器使用的 apparmor 配置文件名字。有关 Apparmor 的更多信息,请参考Apparmor documentation。
  • selinuxLabel string, OPTIONAL 指定容器内进程运行时使用的 SELinux 标签。有关 SELinux 的更多信息,请参考Selinux documentation。
  • noNewPrivileges bool, OPTIONAL 将 noNewPrivileges 设置成 true 可以阻止容器内的进程申请额外的权限。 The kernel doc上有更多关于该功能如何使用prctl系统调用实现的信息。

User

进程的用户是平台特定的结构,允许控制进程以哪个具体的用户运行。

基于Linux和Solaris的系统,用户结构有以下字段:

  • uid (int, REQUIRED) 指定container namespace内的UID。
  • gid (int, REQUIRED) 指定container namespace内的GID.
  • additionalGids (array of ints, OPTIONAL) 指定添加给进程的额外的GID(在 container namespace内)。

Note: 分别用于uid和gid的symbolic name,例如uname和game,留给更高级去导出(如解析/etcpasswd,NSS等)。

Note: Solaris下,uid和gid指定容器内进程的uid和gid,并且不需要和宿主机一致。

示例:

"process": {
    "terminal": true,
    "consoleSize": {
        "height": 25,
        "width": 80
    },
    "user": {
        "uid": 1,
        "gid": 1,
        "additionalGids": [5, 6]
    },
    "env": [
        "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
        "TERM=xterm"
    ],
    "cwd": "/root",
    "args": [
        "sh"
    ],
    "apparmorProfile": "acme_secure_profile",
    "selinuxLabel": "system_u:system_r:svirt_lxc_net_t:s0:c124,c675",
    "noNewPrivileges": true,
    "capabilities": [
        "CAP_AUDIT_WRITE",
        "CAP_KILL",
        "CAP_NET_BIND_SERVICE"
    ],
    "rlimits": [
        {
            "type": "RLIMIT_NOFILE",
            "hard": 1024,
            "soft": 1024
        }
    ]
}

Hostname

  • hostname string, OPTIONAL 配置容器中运行的进程能看到的容器主机名。Linux环境下,你只能在创建了新的UTS namespace后才能设置此值。

示例:

"hostname": "mrsdalloway"

Platform

platform 指定了配置的目标平台。

  • os string, REQUIRED 指定这个镜像对应的操作系统系列。 如果运行时不支持配置的 os 必须 报错。 Bundles SHOULD use, and runtimes SHOULD understand, os entries listed in the Go Language document for $GOOS. 如果某个操作系统没有列在$GOOS的文档里,那么它 应该 被提交到这个规范里做标准化。
  • arch string, REQUIRED 指定了镜像内二进制文件编译用到的指令集。 如果运行时不支持配置的 arch 必须 报错。 Values for arch SHOULD use, and runtimes SHOULD understand, arch entries listed in the Go Language document for $GOARCH. 如果某个架构没有列在$GOARCH文档里,那么它 应该 被提交到这个规范里做标准化。

示例:

"platform": {
    "os": "linux",
    "arch": "amd64"
}

Platform-specific configuration

platform.os 用于检查进一步的平台相关的配置。

  • linux (object, OPTIONAL) Linux-specific configuration. 仅当 platform.oslinux时才推荐设置。
  • solaris (object, OPTIONAL) Solaris-specific configuration. 仅当 platform.ossolaris时才推荐设置。
  • windows (object, optional) Windows-specific configuration. 仅当 platform.oswindows时才推荐设置。

示例:

{
    "platform": {
        "os": "linux",
        "arch": "amd64"
    },
    "linux": {
        "namespaces": [
          {
            "type": "pid"
          }
        ]
    }
}

Namespaces

命名空间将全局系统资源封装在抽象概念中,使得命名空间中的进程看起来具有自己的全局资源的独立实例。 更改全局资源,对属于命名空间成员中的其他进程可见,但对(非成员的)其他进程不可见。 更多信息请参考the man page。

命名空间被指定为 namespaces 字段中的数组。 设置命名空间可以指定以下参数:

  • type string, REQUIRED - 命名空间类型。支持下列命名空间类型:
    • pid 容器内的进程仅能看见同容器内的其他进程。
    • network 容器有自己的网络栈。
    • mount 容器有自己的挂载表。
    • ipc 容器内的进程仅能通过系统级 IPC 与同一容器内的其他进程通信。
    • uts 容器有自己的主机名和域名。
    • user 容器能将主机中的用户和组 ID 重新映射到容器内的本地用户和组。
    • cgroup 容器具有 cgroup 层次结构的独立视图。
  • path string, OPTIONAL - runtime mount namespace中的命名空间文件路径。

如果没有在 namespaces 数组中指定命名空间类型,则该容器必须继承该类型的运行时命名空间。 如果一个 namespaces 字段包含具有相同 type 的重复命名空间,那么运行时 必须 报错。

示例

"namespaces": [
        {
            "type": "pid",
            "path": "/proc/1234/ns/pid"
        },
        {
            "type": "network",
            "path": "/var/run/netns/neta"
        },
        {
            "type": "mount"
        },
        {
            "type": "ipc"
        },
        {
            "type": "uts"
        },
        {
            "type": "user"
        },
        {
            "type": "cgroup"
        }
    ]

User namespace mappings

uidMappings array of objects, OPTIONAL 描述从宿主机到容器的用户命名空间 uid 映射。

gidMappings array of objects, OPTIONAL 描述从宿主机到容器的用户命名空间 uid 映射。

每个条目都有以下的结构:

  • hostID uint32, REQUIRED - 将被映射到容器内宿主机上的启始 uid/gid
  • containerID uint32, REQUIRED - 在容器内的启始uid/gid
  • size uint32, REQUIRED - 被映射的id数量

运行时 不应该 修改引用文件系统的所有权来实现映射。 Linux内核有5个映射的硬限制。

示例

"uidMappings": [
        {
            "hostID": 1000,
            "containerID": 0,
            "size": 10
        }
    ],
    "gidMappings": [
        {
            "hostID": 1000,
            "containerID": 0,
            "size": 10
        }
    ]

Devices

devices array of objects, OPTIONAL 列出容器中 必须 可用的设备。

每个条目都有以下的结构:

  • type string, REQUIRED - 设备类型:c , b , uI。 更多信息参考mknod(1)。
  • path string, REQUIRED - 容器内设备的完整路径。
  • major, minor *int64, REQUIRED - 设备的major, minor numbers。
  • fileMode uint32, OPTIONAL- 设备的文件模式。 你可以通过cgroups控制设备的访问。
  • uid uint32, OPTIONAL- 设备所有者的ID。
  • gid uint32, OPTIONAL - 设备归属组的ID。

示例

"devices": [
        {
            "path": "/dev/fuse",
            "type": "c",
            "major": 10,
            "minor": 229,
            "fileMode": 438,
            "uid": 0,
            "gid": 0
        },
        {
            "path": "/dev/sda",
            "type": "b",
            "major": 8,
            "minor": 0,
            "fileMode": 432,
            "uid": 0,
            "gid": 0
        }
    ]

默认设备列表:

  • /dev/null
  • /dev/zero
  • /dev/full
  • /dev/random
  • /dev/urandom
  • /dev/tty
  • /dev/console
  • /dev/ptmx

Control groups

称之为cgroups, 被用于容器对资源使用的限制和处理设备的访问限制。cgroups提供通过相应的控制器去限制容器的 cpu 、内存 、IO 、pid 、网络等资源使用。详细信息参考 kernel cgroups documentation.

通过 cgroupsPath 项可指定 cgroups 路径. 通过 resource 项配置容器的资源限制。

Example
"cgroupsPath": "/myRuntime/myContainer",
   "resources": {
      "memory": {
         "limit": 100000,
         "reservation": 200000
      },
      "devices": [
         {
            "allow": false,
            "access": "rwm"
         }
      ]

Device whitelist

devices array of objects, OPTIONAL 配置设备的白名单。

列表内的每项包含以下结构:

  • allow boolean, REQUIRED - 实体项是被否允许或拒绝
  • type string, OPTIONAL - 设备类型: a (all), c (字符), 或 b (块). null 或未设代表 "all"
  • major, minor int64, OPTIONAL - major, minor numbers 设备主、次版本 null 或未设代表 "all" * in the filesystem API.
  • access string, OPTIONAL - 设备cgroup权限. 由r (读), w (写), 和 m(mknod)组成.

示例

"devices": [
        {
            "allow": false,
            "access": "rwm"
        },
        {
            "allow": true,
            "type": "c",
            "major": 10,
            "minor": 229,
            "access": "rw"
        },
        {
            "allow": true,
            "type": "b",
            "major": 8,
            "minor": 0,
            "access": "r"
        }
    ]

Disable out-of-memory killer

disableOOMKiller 设置布尔值 true 或 false为 cgroup 开启或关闭OOM killer机制.详细可参考 the memory cgroup man page。

  • disableOOMKiller (bool, OPTIONAL) - 开启或关闭 OOM killer

示例

"disableOOMKiller": false

Set oom_score_adj

oomScoreAdj设置有关当内存压力情况下内核将如何处理进程的启发式方法。详细可参考 the proc filesystem documentation section 3.1. This is a kernel/system level setting这是一个内核/系统级设置, 其中"disableoomkiller"作用于内存cgroup ,详细可参考 the memory cgroup documentation section 10. OOM Contol.

  • oomScoreAdj int, OPTIONAL - 调节oom-killer的分值
Example
"oomScoreAdj": 100

Memory

memory object, OPTIONAL 表示用 cgroup 子系统 memory 对容器的内存使用进行限制。详细信息参考 the memory cgroup man page.

可指定的参数配置:

  • limit uint64, OPTIONAL - 设置内存使用限制(bytes)
  • reservation uint64, OPTIONAL - 设置内存使用软限制(bytes)
  • swap uint64, OPTIONAL - 设置内存+swap使用限制
  • kernel uint64, OPTIONAL - 设置内核内存硬限制
  • kernelTCP uint64, OPTIONAL - 设置内核TCP缓存内存硬限制
  • swappiness uint64, OPTIONAL - 设置内存交换限制
Example
"memory": {
        "limit": 536870912,
        "reservation": 536870912,
        "swap": 536870912,
        "kernel": 0,
        "kernelTCP": 0,
        "swappiness": 0
    }

CPU

cpu object, OPTIONAL cgroup 子系统 cpu and cpusets. 详细信息参考 the cpusets cgroup man page.

可配置的参数:

  • shares uint64, OPTIONAL - 指定一个在cgroup内任务的可使用的CPU时间相对比重。
  • quota uint64, OPTIONAL - 指定在一个周期(由下面的period参数指定)内cgroup内的所有任务运行的总时间值(microseconds)
  • period uint64, OPTIONAL - 仅适用完全公平调度,指定一个CGroup对CPU资源的访问应该多久重新分配一次(microseconds)
  • realtimeRuntime uint64, OPTIONAL - 指定任务占用CPU资源最长连续周期(microseconds)
  • realtimePeriod uint64, OPTIONAL - 如同period,但仅应用于实时调度器
  • cpus string, OPTIONAL - 容器将被运行的CPU列表
  • mems string, OPTIONAL - 容器将被运行的内存节点列表

示例

"cpu": {
        "shares": 1024,
        "quota": 1000000,
        "period": 500000,
        "realtimeRuntime": 950000,
        "realtimePeriod": 1000000,
        "cpus": "2-3",
        "mems": "0-7"
    }

Block IO Controller

blockIO object, OPTIONAL cgroup blkio子系统,实现对块设备IO控制器。详细信息可参考 the kernel cgroups documentation about blkio.

可指定配置参数:

  • blkioWeight uint16, OPTIONAL - 指定每个 cgroup 权限. 取值区间 10 ~ 1000.
  • blkioLeafWeight uint16, OPTIONAL - 相当于 blkioweight ,当竞争产生时的权重.取值区间 10 ~ 1000
  • blkioWeightDevice array, OPTIONAL - 指定blkio带宽速率限制的设备列表. 每个设备可指定的参数:
    • major, minor int64, REQUIRED - 设备的主、次版本号
    • weight uint16, OPTIONAL - 设备的blkio带宽速率,取值区间 10~1000
    • leafWeight uint16, OPTIONAL - 当与 cgroup 的子 cgoup 产生竞争时设备的带宽速率 cgroups, ,值区间10~1000。仅作用于完全公平调度算法
  • blkioThrottleReadBpsDevice, blkioThrottleWriteBpsDevice, blkioThrottleReadIOPSDevice, blkioThrottleWriteIOPSDevice array, OPTIONAL - IO率限制设备列表
    • major, minor int64, REQUIRED - 设备的主、次版本号
    • rate uint64, REQUIRED - 设备的io率限制
Example
"blockIO": {
        "blkioWeight": 10,
        "blkioLeafWeight": 10,
        "blkioWeightDevice": [
            {
                "major": 8,
                "minor": 0,
                "weight": 500,
                "leafWeight": 300
            },
            {
                "major": 8,
                "minor": 16,
                "weight": 500
            }
        ],
        "blkioThrottleReadBpsDevice": [
            {
                "major": 8,
                "minor": 0,
                "rate": 600
            }
        ],
        "blkioThrottleWriteIOPSDevice": [
            {
                "major": 8,
                "minor": 16,
                "rate": 300
            }
        ]
    }

Huge page limits

hugepageLimits array of objects, OPTIONAL 表示hugetlb控制器允许限制每个控制组的HugeTLB使用和控制器限制错误页, 更多信息参考 kernel cgroups documentation about HugeTLB。

每项有以下结构配置:

  • pageSize string, REQUIRED - hugepage size 大页的大小
  • limit uint64, REQUIRED - HugeTLB 使用限制
Example
"hugepageLimits": [
        {
            "pageSize": "2MB",
            "limit": 9223372036854771712
        }
   ]

Network

network object, OPTIONAL 代表 cgroup 的 net_clsnet_prio 子系统。 更多信息,参考the net_cls cgroup man page 和 the net_prio cgroup man page。

可以指定以下参数来设置控制器:

  • classID uint32, OPTIONAL - 网络类标识,cgroup网络包被与之关联标记

  • priorities array, OPTIONAL - 指定分配给来自组中进程并在各接口上出流量优先级的对象列表。

    每个优先级可指定的参数:

    • name string, REQUIRED - 网卡名字
    • priority uint32, REQUIRED - 应用在此网卡的优先级

示例:

"network": {
        "classID": 1048577,
        "priorities": [
            {
                "name": "eth0",
                "priority": 500
            },
            {
                "name": "eth1",
                "priority": 1000
            }
        ]
   }
PIDs

pids (object, OPTIONAL) 代表cgroup的pids子系统。 更多信息,参考the pids cgroup man page。

可以指定以下参数来设置控制器:

  • limit (int64, REQUIRED) - 指定cgroup下最大任务数量。

示例

"pids": {
        "limit": 32771
   }

Sysctl

sysctl object, OPTIONAL 允许为容器在运行时对内核参数进行设置,更多信息可以参考 sysctl(8)

示例

 "sysctl": {
        "net.ipv4.ip_forward": "1",
        "net.core.somaxconn": "256"
   }

Seccomp

Seccomp 在 linux 内核层为应用提供沙盒机制。seccomp配置允许配置对匹配的syscall执行的操作,并且还允许对作为参数传递给syscalls的值进行匹配,更多信息可以参考 Seccomp 内核文档。

seccomp object, OPTIONAL

可指定配置seccomp的参数如下:

  • defaultAction string, REQUIRED - seccomp执行的默认动作,可配置的值与一致 syscalls[].action
  • architectures array of strings, OPTIONAL - 系统调用所使用的架构
  • syscalls array of objects, OPTIONAL -在seccomp内匹配syscall

示例

  "seccomp": {
       "defaultAction": "SCMP_ACT_ALLOW",
       "architectures": [
           "SCMP_ARCH_X86"
       ],
       "syscalls": [
           {
               "name": "getcwd",
               "action": "SCMP_ACT_ERRNO"
           }
       ]
   }

Rootfs Mount Propagation

rootfsPropagation string, OPTIONAL 设置 rootfs 的挂载传播。 取值是 slave、privateshared。 有关于安装传播的更多信息,参考The kernel doc。

示例

"rootfsPropagation": "slave"

Masked Paths

maskedPaths (array of strings, OPTIONAL) 在容器内掩藏提供的路径,使它们无法读取。 这些路径在容器命名空间 必须是绝对路径。

示例

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

Readonly Paths

readonlyPaths array of strings, OPTIONAL 在容器内设置提供的路径为只读,这些路径在容器命名空间 是绝对路径。

示例

"readonlyPaths": [
        "/proc/sys"
]

Mount Label

mountLabel string, OPTIONAL 为容器挂载的设置 Selinux上下文。

示例

"mountLabel": "system_u:object_r:svirt_sandbox_file_t:s0:c715,c811"

Hooks

hooks object, OPTIONAL 用来配置容器生命周期事件的回调。 Liftcycle hooks允许对容器运行时的许多(逻辑)点自定义事件。 目前有Prestart,PoststartPoststop

  • Prestart 容器进程运行前被调用的一组钩子。

  • Poststart 容器进程运行后立即被调用的一组钩子。

  • Poststop 容器进程退出后被调用的一组钩子。

    钩子允许在容器的各种生命周期事件之前/之后运行代码。钩子 必须 按照列表顺序(声明顺序)被调用。容器的状态会通过stdin传入到钩子内,这样钩子(程序)就可以拿到它们工作需要的信息。

    钩子的路径是绝对路径,并且可以在runtime namespace中执行。

Prestart

pre-start钩子在容器进程产生后,用户提供的命令执行之前被调用。Linux下,他们在容器的namespaces创建以后被调用,因此提供了自定义容器的机会。举个例子, 在此钩子里可以配置network namespace。

如果钩子返回了非零的退出码(参考shell中的$?),则一个包含了退出码和stderr的错误被返回给调用者,同时容器被回收。

Poststart

post-start钩子在用户进程运行启动后被调用。举个例子,这个钩子可以通知用户真正产生的进程(的PID或其他balabala)。

如果钩子返回了非零的退出码(参考shell中的$?),记录下错误并继续执行剩下的钩子。

Poststop

post-stop钩子在容器进程停止后被调用。可以在此钩子中执行清理或调试工作。

如果钩子返回了非零的退出码(参考shell中的$?),记录下错误并继续执行剩下的钩子。

示例

"hooks": {
        "prestart": [
            {
                "path": "/usr/bin/fix-mounts",
                "args": ["fix-mounts", "arg1", "arg2"],
                "env":  [ "key1=value1"]
            },
            {
                "path": "/usr/bin/setup-network"
            }
        ],
        "poststart": [
            {
                "path": "/usr/bin/notify-start",
                "timeout": 5
            }
        ],
        "poststop": [
            {
                "path": "/usr/sbin/cleanup.sh",
                "args": ["cleanup.sh", "-f"]
            }
        ]
    }

Annotations

annotations object, OPTIONAL 包含了容器的任意元数据。 这些元数据信息 可能 是结构化的或非结构化的。 注解 必须 是键值对映射,而且键值 必须 是字符串。 值 必须 存在,但 可能 是空字符串。 键在映射中 必须 是唯一的,最好的办法就是使用命名空间。 键 应该 以反向域名的方式命名 —— 比如 com.example.myKeyorg.opencontainers 命名空间下的键是保留关键字,并且 一定不能 被后续的规范使用。 如果没有注解,此值 可能 不存在或者是空映射。 正在读取/处理配置文件的实现 一定不能 在遇到一个未知属性时报错。

示例

"annotations": {
    "com.example.gpu-cores": "2"
}

Extensibility

正在读取/处理配置文件的(runtime)实现 一定不能 在遇到一个未知属性时报错,而是 必须 忽略这些未知的属性。

config.json 完整的配置示例供参考:

{
    "ociVersion": "0.5.0-dev",
    "platform": {
        "os": "linux",
        "arch": "amd64"
    },
    "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": [
            "CAP_AUDIT_WRITE",
            "CAP_KILL",
            "CAP_NET_BIND_SERVICE"
        ],
        "rlimits": [
            {
                "type": "RLIMIT_CORE",
                "hard": 1024,
                "soft": 1024
            },
            {
                "type": "RLIMIT_NOFILE",
                "hard": 1024,
                "soft": 1024
            }
        ],
        "apparmorProfile": "acme_secure_profile",
        "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",
                "nodev"
            ]
        },
        {
            "destination": "/sys/fs/cgroup",
            "type": "cgroup",
            "source": "cgroup",
            "options": [
                "nosuid",
                "noexec",
                "nodev",
                "relatime",
                "ro"
            ]
        }
    ],
    "hooks": {
        "prestart": [
            {
                "path": "/usr/bin/fix-mounts",
                "args": [
                    "fix-mounts",
                    "arg1",
                    "arg2"
                ],
                "env": [
                    "key1=value1"
                ]
            },
            {
                "path": "/usr/bin/setup-network"
            }
        ],
        "poststart": [
            {
                "path": "/usr/bin/notify-start",
                "timeout": 5
            }
        ],
        "poststop": [
            {
                "path": "/usr/sbin/cleanup.sh",
                "args": [
                    "cleanup.sh",
                    "-f"
                ]
            }
        ]
    },
    "linux": {
        "devices": [
            {
                "path": "/dev/fuse",
                "type": "c",
                "major": 10,
                "minor": 229,
                "fileMode": 438,
                "uid": 0,
                "gid": 0
            },
            {
                "path": "/dev/sda",
                "type": "b",
                "major": 8,
                "minor": 0,
                "fileMode": 432,
                "uid": 0,
                "gid": 0
            }
        ],
        "uidMappings": [
            {
                "hostID": 1000,
                "containerID": 0,
                "size": 32000
            }
        ],
        "gidMappings": [
            {
                "hostID": 1000,
                "containerID": 0,
                "size": 32000
            }
        ],
        "sysctl": {
            "net.ipv4.ip_forward": "1",
            "net.core.somaxconn": "256"
        },
        "cgroupsPath": "/myRuntime/myContainer",
        "resources": {
            "network": {
                "classID": 1048577,
                "priorities": [
                    {
                        "name": "eth0",
                        "priority": 500
                    },
                    {
                        "name": "eth1",
                        "priority": 1000
                    }
                ]
            },
            "pids": {
                "limit": 32771
            },
            "hugepageLimits": [
                {
                    "pageSize": "2MB",
                    "limit": 9223372036854772000
                }
            ],
            "oomScoreAdj": 100,
            "memory": {
                "limit": 536870912,
                "reservation": 536870912,
                "swap": 536870912,
                "kernel": 0,
                "kernelTCP": 0,
                "swappiness": 0
            },
            "cpu": {
                "shares": 1024,
                "quota": 1000000,
                "period": 500000,
                "realtimeRuntime": 950000,
                "realtimePeriod": 1000000,
                "cpus": "2-3",
                "mems": "0-7"
            },
            "disableOOMKiller": false,
            "devices": [
                {
                    "allow": false,
                    "access": "rwm"
                },
                {
                    "allow": true,
                    "type": "c",
                    "major": 10,
                    "minor": 229,
                    "access": "rw"
                },
                {
                    "allow": true,
                    "type": "b",
                    "major": 8,
                    "minor": 0,
                    "access": "r"
                }
            ],
            "blockIO": {
                "blkioWeight": 10,
                "blkioLeafWeight": 10,
                "blkioWeightDevice": [
                    {
                        "major": 8,
                        "minor": 0,
                        "weight": 500,
                        "leafWeight": 300
                    },
                    {
                        "major": 8,
                        "minor": 16,
                        "weight": 500
                    }
                ],
                "blkioThrottleReadBpsDevice": [
                    {
                        "major": 8,
                        "minor": 0,
                        "rate": 600
                    }
                ],
                "blkioThrottleWriteIOPSDevice": [
                    {
                        "major": 8,
                        "minor": 16,
                        "rate": 300
                    }
                ]
            }
        },
        "rootfsPropagation": "slave",
        "seccomp": {
            "defaultAction": "SCMP_ACT_ALLOW",
            "architectures": [
                "SCMP_ARCH_X86"
            ],
            "syscalls": [
                {
                    "name": "getcwd",
                    "action": "SCMP_ACT_ERRNO"
                }
            ]
        },
        "namespaces": [
            {
                "type": "pid"
            },
            {
                "type": "network"
            },
            {
                "type": "ipc"
            },
            {
                "type": "uts"
            },
            {
                "type": "mount"
            },
            {
                "type": "user"
            },
            {
                "type": "cgroup"
            }
        ],
        "maskedPaths": [
            "/proc/kcore",
            "/proc/latency_stats",
            "/proc/timer_stats",
            "/proc/sched_debug"
        ],
        "readonlyPaths": [
            "/proc/asound",
            "/proc/bus",
            "/proc/fs",
            "/proc/irq",
            "/proc/sys",
            "/proc/sysrq-trigger"
        ],
        "mountLabel": "system_u:object_r:svirt_sandbox_file_t:s0:c715,c811"
    },
    "annotations": {
        "com.example.key1": "value1",
        "com.example.key2": "value2"
    }
}

~~ 本文 END ~~

你可能感兴趣的:(OCI Runtime spec 运行时规范)