OCI Runtime Specification——Linux Configuration

OCI Runtime-Spec/config.json (linux spec)

Posted by PYQ on October 25, 2023

本篇主要是container configuration(config.json)中linux容器规范部分

Linux容器规范使用了各种内核特性,如namespaces、cgroups、capabilities、LSM 和文件系统隔离。

Default Filesystems

Linux ABI包括系统调用和几个特殊的文件路径,需要为Linux环境下运行的应用程序正确设置这些文件路径。在每个容器的文件系统中,应该提供以下文件系统:

Path Type Use
/proc proc 提供了有关运行中进程和系统状态的信息
/sys sysfs 提供了对内核和硬件设备的访问接口
/dev/pts devpts 用于处理终端设备的访问
/dev/shm tmpfs 用于在内存中创建共享内存段,使容器内的进程可以使用共享内存进行进程间通信(IPC)操作,如共享数据、信号量和互斥锁等

ABI是 “Application Binary Interface”(应用程序二进制接口)的缩写。ABI 定义了一个应用程序与操作系统或其他软件组件之间的接口规范,以便它们能够相互通信和交互。它规定了二进制程序的格式、函数调用约定、参数传递方式、系统调用接口、寄存器的使用方法等方面的规则和约定。

API 是 “Application Programming Interface”(应用程序编程接口)的缩写。API 定义了软件组件之间的接口规范和交互方式,以便应用程序可以与其他软件组件(如操作系统、库、服务等)进行通信和交互。API 提供了一组预定义的函数、协议、数据结构和工具,用于构建应用程序和组件之间的通信通道。开发人员可以使用 API 来访问和利用其他软件组件的功能,而无需了解其内部实现细节。

Namespaces

命名空间将全局系统资源抽象化,使命名空间内的进程看起来拥有自己的全局资源独立实例。作为命名空间成员的其他进程可以看到对全局资源的更改,但命名空间外的其他进程则看不到。每个容器都有单独的命名空间:

  • type (string, REQUIRED):命名空间类型,应支持以下命名空间
    • pid:容器内的进程只能看到同一容器内或同一pid命名空间内的其他进程
    • network:容器有自己的网络栈
    • mount:容器有独立的挂载表
    • ipc:容器内的进程只能通过系统级IPC与同一容器内的其他进程通信
    • uts:容器将能够拥有自己的主机名和域名
    • user:容器将能够把主机上的用户和组ID重新映射到容器内的本地用户和组
    • cgroup:容器有单独的cgroup层次
    • time:容器有自己的时间(clock)
  • path (string, OPTIONAL):与具体命名空间类型相关联的命名空间文件。该值必须是运行时挂载命名空间中的绝对路径,运行时必须将容器进程置于与该路径相关联的命名空间中。
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
"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"
    },
    {
        "type": "time"
    }
]

User namespace mappings

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

gidMappings (array of objects, OPTIONAL):描述了从主机到容器的用户命名空间的gid映射

上述两个对象都有如下元素:

  • containerID (uint32, REQUIRED) :容器中的起始uid/gid
  • hostID (uint32, REQUIRED) :映射到容器containerID的主机上的起始uid/gid
  • size (uint32, REQUIRED):映射的id数量

运行时不应为实现映射而修改引用文件系统的所有权,并且内核可能会限制映射条目的数量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
"uidMappings": [
    {
        "containerID": 0,
        "hostID": 1000,
        "size": 32000
    }
],
"gidMappings": [
    {
        "containerID": 0,
        "hostID": 1000,
        "size": 32000
    }
]

Offset for Time Namespace

timeOffsets (object, OPTIONAL) :标识时间命名空间中的偏移:

  • secs (int64, OPTIONAL) :容器中时钟的偏移量(以秒为单位)
  • nanosecs (uint32, OPTIONAL) :容器中时钟的偏移量(以纳秒为单位)

Devices

devices (array of objects, OPTIONAL):列出了容器中必须可用的设备,运行时需要提供这些设备的支持(例如使用mknod、从运行时命名空间绑定挂载或使用符号链接等):

  • type (string, REQUIRED) :设备类型
  • path (string, REQUIRED) :容器中设备的路径
  • major, minor (int64, REQUIRED unless type is p) :设备的major和minor值
  • fileMode (uint32, OPTIONAL) :设备的文件模式
  • uid (uint32, OPTIONAL):容器命名空间中设备拥有者的id
  • gid (uint32, OPTIONAL):容器命名空间中设备拥有者的组id

“major” 数字用于标识设备驱动程序,它指示了设备所属的驱动程序或设备类型。”minor” 数字用于标识设备在其所属驱动程序中的具体实例或编号。通过组合 “major” 和 “minor” 数字,可以唯一地标识一个设备。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
"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
    }
]

Default Devices

运行时必须支持如下设备:

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

Control groups (cgroups)

cgroups用于限制容器的 CPU、内存、IO、pids、网络和RDMA资源。

Cgroups Path

cgroupsPath (string, OPTIONAL):cgroups路径,可以用来控制容器的cgroups层次结构,也可用于在现有容器中运行新进程。

Cgroup ownership

1
2
3
4
5
6
7
8
9
10
11
12
13
"cgroupsPath": "/myRuntime/myContainer",
"resources": {
    "memory": {
    "limit": 100000,
    "reservation": 200000
    },
    "devices": [
        {
            "allow": false,
            "access": "rwm"
        }
    ]
}

Allowed Device list

devices (array of objects, OPTIONAL):

  • allow (boolean, REQUIRED) :设备是否被允许
  • type (string, OPTIONAL) :设备类型,a (all, default)、b (block)或c (char)
  • major, minor (int64, OPTIONAL)
  • access (string, OPTIONAL):设备的cgroup权限,r (read), w (write), and m (mknod)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
"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"
    }
]

Memory

memory (object, OPTIONAL):用于设置容器的内存限制,单位为字节,-1表示不做限制:

  • limit (int64, OPTIONAL):内存使用限制
  • swap (int64, OPTIONAL):内存和swap限制
  • kernel (int64, OPTIONAL, NOT RECOMMENDED) :为内核内存做强制限制
  • kernelTCP (int64, OPTIONAL, NOT RECOMMENDED):为内核tcp buffer内存做强制限制

其他的一些元素:

  • swappiness (uint64, OPTIONAL)
  • disableOOMKiller (bool, OPTIONAL)
  • useHierarchy (bool, OPTIONAL)
  • checkBeforeUpdate (bool, OPTIONAL)
1
2
3
4
5
6
7
8
9
"memory": {
    "limit": 536870912,
    "reservation": 536870912,
    "swap": 536870912,
    "kernel": -1,
    "kernelTCP": -1,
    "swappiness": 0,
    "disableOOMKiller": false
}

CPU

cpu (object, OPTIONAL):

  • shares (uint64, OPTIONAL):任务中可用的共享CPU时间
  • quota (int64, OPTIONAL)
  • burst (uint64, OPTIONAL)
  • period (uint64, OPTIONAL)
  • realtimeRuntime (int64, OPTIONAL)
  • realtimePeriod (uint64, OPTIONAL)
  • cpus (string, OPTIONAL)
  • mems (string, OPTIONAL)
  • idle (int64, OPTIONAL)
1
2
3
4
5
6
7
8
9
10
11
"cpu": {
    "shares": 1024,
    "quota": 1000000,
    "burst": 1000000,
    "period": 500000,
    "realtimeRuntime": 950000,
    "realtimePeriod": 1000000,
    "cpus": "2-3",
    "mems": "0-7",
    "idle": 0
}

Block IO

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
31
"blockIO": {
    "weight": 10,
    "leafWeight": 10,
    "weightDevice": [
        {
            "major": 8,
            "minor": 0,
            "weight": 500,
            "leafWeight": 300
        },
        {
            "major": 8,
            "minor": 16,
            "weight": 500
        }
    ],
    "throttleReadBpsDevice": [
        {
            "major": 8,
            "minor": 0,
            "rate": 600
        }
    ],
    "throttleWriteIOPSDevice": [
        {
            "major": 8,
            "minor": 16,
            "rate": 300
        }
    ]
}

Huge page limits

1
2
3
4
5
6
7
8
9
10
"hugepageLimits": [
    {
        "pageSize": "2MB",
        "limit": 209715200
    },
    {
        "pageSize": "64KB",
        "limit": 1000000
    }
]

Network

1
2
3
4
5
6
7
8
9
10
11
12
13
"network": {
    "classID": 1048577,
    "priorities": [
        {
            "name": "eth0",
            "priority": 500
        },
        {
            "name": "eth1",
            "priority": 1000
        }
    ]
}

PIDs

limit (int64, REQUIRED):指定任务的最大数量

1
2
3
"pids": {
    "limit": 32771
}

RDMA

1
2
3
4
5
6
7
8
9
10
11
12
"rdma": {
    "mlx5_1": {
        "hcaHandles": 3,
        "hcaObjects": 10000
    },
    "mlx4_0": {
        "hcaObjects": 1000
    },
    "rxe3": {
        "hcaObjects": 10000
    }
}

Unified

1
2
3
4
"unified": {
    "io.max": "259:0 rbps=2097152 wiops=120\n253:0 rbps=2097152 wiops=120",
    "hugetlb.1GB.max": "1073741824"
}

IntelRdt

intel相关的。

1
2
3
4
5
6
7
"linux": {
    "intelRdt": {
        "closID": "guaranteed_group",
        "l3CacheSchema": "L3:0=7f0;1=1f",
        "memBwSchema": "MB:0=20;1=70"
    }
}

Sysctl

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

Seccomp

Linux内核的沙箱应用机制相关。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
"seccomp": {
    "defaultAction": "SCMP_ACT_ALLOW",
    "architectures": [
        "SCMP_ARCH_X86",
        "SCMP_ARCH_X32"
    ],
    "syscalls": [
        {
            "names": [
                "getcwd",
                "chmod"
            ],
            "action": "SCMP_ACT_ERRNO"
        }
    ]
}

The Container Process State

容器运行时通过UNIX套接字发送的容器进程的状态:

  • ociVersion (string, REQUIRED)
  • fds (array, OPTIONAL):文件描述符名字
  • pid (int, REQUIRED):容器进程id
  • metadata (string, OPTIONAL)
  • state (state, REQUIRED)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
    "ociVersion": "1.0.2",
    "fds": [
        "seccompFd"
    ],
    "pid": 4422,
    "metadata": "MKNOD=/dev/null,/dev/net/tun;BPF_MAP_TYPES=hash,array",
    "state": {
        "ociVersion": "1.0.2",
        "id": "oci-container1",
        "status": "creating",
        "pid": 4422,
        "bundle": "/containers/redis",
        "annotations": {
            "myKey": "myValue"
        }
    }
}

Rootfs Mount Propagation

1
"rootfsPropagation": "slave",

Masked Paths

使路径(容器命名空间)不可读。

1
2
3
"maskedPaths": [
    "/proc/kcore"
]

Readonly Paths

使路径(容器命名空间)只读。

1
2
3
"readonlyPaths": [
    "/proc/sys"
]

Mount Label

selinux相关的内容。

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

Personality