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 <container-id>

此操作在不提供容器 ID 時 必須 報錯。嘗試查詢一個不存在的容器 必須 報錯。此操作 必須 返回同狀態一節指定的容器的狀態(信息)。

Create 容器創建

create <container-id> <path-to-bundle>

此操作在不提供 bundle 文件的路徑和容器 ID 時 必須 報錯。如果提供了一個在 runtime(管理的)范圍內不唯一,或者無效的 ID,其底層實現 必須 報錯,且容易 一定不能 被創建。利用 config.json 文件里的數據,此操作 必須 創建一個新的容器,這意味著該容器相關的資源 必須 被創建,但是,用戶指定的代碼在此階段 一定不能 被執行。如果運行時不能依照如 config.md 指定的容器,則 必須 報錯,且新容器 一定不能 被創建。

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

運行時在創建容器前(步驟2),可以 根據此規范一般或相對于當前系統的能力驗證 config.json。 運行時的調用者如果感興趣 pre-create 校驗,可以在此操作(create)前調用 bundle-validation tools 。

成功執行完成此操作后,容器 必須 被創建好。

再此操作執行成功之后,任何針對config.json的修改都不會影響到(創建出來的)容器。

Start 容器運行

start <container-id>

此操作在不提供容器ID時 必須 報錯。嘗試啟動一個不存在的容器 必須 報錯。嘗試啟動一個已經運行的容器 必須 沒有任何效果,且 必須 報錯。此操作 必須進程運行用戶代碼。

成功執行完成此操作后,此容器的status屬性值 必須running。

Kill 容器停止

kill <container-id> <signal>

此操作在不提供容器ID時 必須 報錯。嘗試向一個非運行的容器發送信號量, 必須 沒有任何效果,并且 必須 報錯。此操作 必須 向容器內的進程發送指定的信號量。

當容器內的進程停止了,不管是kill操作還是其他原因導致的,這個容器的status屬性值 必須stopped

Delete 刪除容器

delete <container-id>

此操作在不提供容器 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 類似。

示例:

"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 指定終端的控制臺窗口大?。ㄈ绻B接了終端),包含以下屬性:
    • 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的系統,用戶結構有以下字段:

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 用于檢查進一步的平臺相關的配置。

示例:

{
    "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
        }
    ]

默認設備列表:

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 pagethe 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 ~~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,197評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,415評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,104評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,884評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,647評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,130評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,208評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,366評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,887評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,737評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,478評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,174評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,586評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,827評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,608評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,914評論 2 372

推薦閱讀更多精彩內容