成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

真正運(yùn)行容器的工具:深入了解 Runc 和 OCI 規(guī)范

開(kāi)發(fā) 開(kāi)發(fā)工具
runc 是一個(gè)命令行客戶端,用于運(yùn)行根據(jù) Open Container Initiative (OCI) 格式打包的應(yīng)用程序,并且是 Open Container Initiative 規(guī)范的兼容實(shí)現(xiàn)。

[[430749]]

我們談?wù)勎挥?Docker、Podman、CRI-O 和 Containerd 核心的工具:runc。

原始容器運(yùn)行時(shí)

如果試圖將鏈從最終用戶繪制到實(shí)際的容器進(jìn)程,它可能如下所示:

runc 是一個(gè)命令行客戶端,用于運(yùn)行根據(jù) Open Container Initiative (OCI) 格式打包的應(yīng)用程序,并且是 Open Container Initiative 規(guī)范的兼容實(shí)現(xiàn)。

有一個(gè)關(guān)于如何運(yùn)行容器和管理容器映像的開(kāi)放容器計(jì)劃(OCI) 和規(guī)范。runc 符合此規(guī)范,但還有其他符合 OCI 的運(yùn)行時(shí)。甚至可以運(yùn)行符合 OCI 標(biāo)準(zhǔn)的虛擬機(jī),Kata Containers 與gVisor就是符合符合 OCI 標(biāo)準(zhǔn)的虛擬機(jī)。gVisor 為代表的用戶態(tài) Kernel 方案是安全容器的未來(lái),只是現(xiàn)在還不夠完善。

runc 希望提供一個(gè)“ OCI 包”,它只是一個(gè)根文件系統(tǒng)和一個(gè)config.json 文件。而不是Podman 或 Docker 那樣有“鏡像”概念,所以不能只執(zhí)行runc run nginx:latest這樣來(lái)啟動(dòng)一個(gè)容器。

Runc 符合 OCI 規(guī)范(具體來(lái)說(shuō),是runtime-spec),這意味著它可以使用 OCI 包并從中運(yùn)行一個(gè)容器。值得重申的是,這些bundle并不是“容器鏡像”,它們要簡(jiǎn)單得多。層、標(biāo)簽、容器注冊(cè)表和存儲(chǔ)庫(kù)等功能 - 所有這些都不是 OCI 包甚至運(yùn)行時(shí)規(guī)范的一部分。有一個(gè)單獨(dú)的 OCI-spec (image-spec )定義鏡像。

文件系統(tǒng)包是你下載容器鏡像并解壓后得到的。所以它是這樣的:

  1. OCI Image -> OCI Runtime Bundle -> OCI Runtime 

在我們的例子中,這意味著:

  1. Container image -> Root filesystem and config.json -> runc 

讓我們構(gòu)建一個(gè)應(yīng)用程序包。我們可以從 config.json 文件開(kāi)始,因?yàn)檫@部分非常簡(jiǎn)單:

  1. mkdir my-bundle 
  2. cd my-bundle 
  3. runc spec 

runc spec生成一個(gè)虛擬的 config.json。它已經(jīng)有一個(gè)“進(jìn)程”部分,用于指定在容器內(nèi)運(yùn)行哪個(gè)進(jìn)程 - 即使有幾個(gè)環(huán)境變量。

  1.         "ociVersion""1.0.1-dev"
  2.         "process": { 
  3.              "terminal"true
  4.                 "user": { 
  5.                         "uid": 0, 
  6.                         "gid": 0 
  7.                 }, 
  8.                 "args": [ 
  9.                         "sh" 
  10.                 ], 
  11.                 "env": [ 
  12.                         "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  13.                         "TERM=xterm" 
  14.                 ], 
  15.  
  16. ... 

它還定義了在哪里查找根文件系統(tǒng)...

  1. ... 
  2.  
  3.         "root": { 
  4.                 "path""rootfs"
  5.                 "readonly"true 
  6.  
  7.         }, 
  8. ... 

...以及其他許多內(nèi)容,包括容器內(nèi)的默認(rèn)掛載、功能、主機(jī)名等。如果檢查此文件,會(huì)注意到,許多部分與平臺(tái)無(wú)關(guān),并且特定于具體操作系統(tǒng)的部分嵌套在適當(dāng)?shù)膬?nèi)部部分。例如,會(huì)注意到有一個(gè)帶有 Linux 特定選項(xiàng)的“linux”部分。

如果我們嘗試運(yùn)行這個(gè)包,我們會(huì)得到一個(gè)錯(cuò)誤:

  1. # runc run test 
  2. rootfs (/root/my-bundle/rootfs) does not exist 

如果我們簡(jiǎn)單地創(chuàng)建文件夾,我們會(huì)得到另一個(gè)錯(cuò)誤:

  1. # mkdir rootfs 
  2. # runc run test 
  3. container_linux.go:345: starting container process caused "exec: \"sh\": executable file not found in $PATH" 

這完全有道理 - 空文件夾并不是真正有用的根文件系統(tǒng),我們的容器沒(méi)有機(jī)會(huì)做任何有用的事情。我們需要?jiǎng)?chuàng)建一個(gè)真正的 Linux 根文件系統(tǒng)。這里可以使用如下命令解壓rootfs:

  1. $ docker export $(docker create busybox) | tar -C /mycontainer/rootfs -xvf - 

這里我們使用skopeo 和 umoci 獲取 OCI 應(yīng)用程序包。

如何使用 skopeo 和 umoci 獲取 OCI 應(yīng)用程序包

從頭開(kāi)始創(chuàng)建 rootfilesystem 是一種相當(dāng)麻煩的事情,因此讓我們使用現(xiàn)有的最小映像之一 busybox。

要拉取鏡像,我們首先需要安裝skopeo。我們也可以使用 Buildah,但它的功能太多,無(wú)法滿足我們的需求。Buildah 專注于構(gòu)建鏡像,甚至具有運(yùn)行容器的基本功能。由于我們今天盡可能地低級(jí)別,我們將使用 skopeo:

  • skopeo 是一個(gè)命令行程序,可對(duì)容器鏡像和鏡像存儲(chǔ)庫(kù)執(zhí)行各種操作。
  • skopeo 可以在不同來(lái)源和目的地之間復(fù)制鏡像、檢查鏡像甚至刪除它們。
  • skopeo 無(wú)法構(gòu)建映像,它不知道如何處理 Containerfile。它非常適合自動(dòng)化容器鏡像升級(jí)的 CI/CD 管道。
  1. yum install skopeo -y 

然后復(fù)制busybox鏡像:

  1. skopeo copy docker://busybox:latest oci:busybox:latest 

沒(méi)有“拉取”——我們需要告訴 skopeo 鏡像的來(lái)源和目的地。skopeo 支持幾乎十幾種不同類型的來(lái)源和目的地。請(qǐng)注意,此命令將創(chuàng)建一個(gè)新busybox文件夾,將在其中找到所有 OCI 鏡像文件,具有不同的鏡像層、清單等。

不要混淆 Image manifest 和 Application runtime bundle manifest,它們是不一樣的。

我們復(fù)制的是一個(gè) OCI Image,但是我們已經(jīng)知道,runc 需要 OCI Runtime Bundle。我們需要一個(gè)將鏡像轉(zhuǎn)換為解壓包的工具。這個(gè)工具將是umoci - 一個(gè) openSUSE 實(shí)用程序,其唯一目的是操作 OCI 鏡像。要安裝它,請(qǐng)從 Github Releases獲取最新版本的PATH。在撰寫本文時(shí),最新版本是0.4.5. umoci unpack獲取 OCI 鏡像并從中制作一個(gè)包:

  1. umoci unpack --image busybox:latest bundle 

讓我們看看bundle文件夾里面有什么:

  1. # ls bundle 
  2. config.json 
  3. rootfs 
  4. sha256_73c6c5e21d7d3467437633012becf19e632b2589234d7c6d0560083e1c70cd23.mtree 
  5. umoci.json 

讓我們將rootfs目錄復(fù)制到之前創(chuàng)建的my-bundle目錄。如果你好奇,這是rootfs的內(nèi)容,如下:

  1. bin dev etc home root tmp usr var 

如果它看起來(lái)像一個(gè)基本的 Linux 根文件系統(tǒng),那么就是對(duì)的。

根據(jù) OCI Runtime 規(guī)范,Linux ABI 下的應(yīng)用程序會(huì)期望 Linux 環(huán)境提供以下特殊的文件系統(tǒng):

  • /proc 文件夾,掛載 proc 文件系統(tǒng)。
  • /sys 文件夾,掛載 sysfs 文件系統(tǒng)。
  • /dev/pts 文件夾,掛載 devpts 文件系統(tǒng)。
  • /dev/shm 文件夾,掛載 tmpfs 文件系統(tǒng)。

這幾個(gè)文件夾的作用這里略去,有興趣的讀者可以自行查閱 man7.org。runc 文檔中還額外要求提供:

  • /dev 文件夾,掛載 tmpfs 文件系統(tǒng)。
  • /dev/mqueue 文件夾,掛載 mqueue 文件系統(tǒng)。

runc 是 OCI Runtime 規(guī)范的參考實(shí)現(xiàn),規(guī)范為容器的創(chuàng)建提供了整潔的接口,只需要為 runc 提供一份 config.json [1]。

使用 runc 運(yùn)行 OCI 應(yīng)用程序包

我們準(zhǔn)備好將我們的應(yīng)用程序包作為名為 的容器運(yùn)行test:

  1. runc run test 

接下來(lái)發(fā)生的事情是我們最終進(jìn)入了一個(gè)新創(chuàng)建的容器內(nèi)的 shell!

  1. # runc run test 
  2. / # ls 
  3. bin   dev   etc   home  proc  root  sys   tmp   usr   var 

我們以默認(rèn)foreground模式運(yùn)行前一個(gè)容器。在這種模式下,每個(gè)容器進(jìn)程都成為一個(gè)長(zhǎng)時(shí)間運(yùn)行的runc進(jìn)程的子進(jìn)程:

  1. 6801   997  \_ sshd: root [priv] 
  2. 6805  6801      \_ sshd: root@pts/1 
  3. 6806  6805          \_ -bash 
  4. 6825  6806              \_ zsh 
  5. 7342  6825                  \_ runc run test 
  6. 7360  7342                  |   \_ runc run test 

如果我終止與該服務(wù)器的 ssh 會(huì)話,runc 進(jìn)程也會(huì)終止,最終殺死容器進(jìn)程。讓我們通過(guò)sleep infinite在 config.json 中替換 command并將終端選項(xiàng)設(shè)置為“false”來(lái)更仔細(xì)地檢查這個(gè)容器。

runc不提供大量的命令行參數(shù)。它有類似start,stop和 run的命令來(lái)做容器的生命周期管理,但是容器的配置總是來(lái)自文件,而不是來(lái)自命令行:

  1.         "ociVersion""1.0.1-dev"
  2.         "process": { 
  3.                 "terminal"false
  4.                 "user": { 
  5.                         "uid": 0, 
  6.                         "gid": 0 
  7.                 }, 
  8.                 "args": [ 
  9.                         "sleep"
  10.                         "infinite" 
  11.                 ] 
  12. ... 

這次讓我們以分離模式運(yùn)行容器:

  1. runc run test --detach 

我們可以看到正在運(yùn)行的容器runc list:

  1. ID          PID         STATUS      BUNDLE            CREATED                          OWNER 
  2. test        4258        running     /root/my-bundle   2020-04-23T20:29:39.371137097Z   root 

在 Docker 的情況下,有一個(gè)Docker Daemon守護(hù)進(jìn)程知道關(guān)于容器的一切。runc 如何找到我們的容器?事實(shí)證明,它只是在文件系統(tǒng)上保持狀態(tài),默認(rèn)情況下在里面/run/runc/CONTAINER_NAME/state.json:

  1. # cat /run/runc/test/state.json 
  2. {"id":"test","init_process_pid":4258,"init_process_start":9561183,"created":"2020-04-23T20:29:39.371137097Z","config":{"no_pivot_root":false,"parent_death_signal":0,"rootfs":"/root/my-bundle/rootfs","readonlyfs":true,"rootPropagation":0,"mounts".... 

當(dāng)我們?cè)诜蛛x模式下運(yùn)行時(shí),原始runc run命令(不再有這樣的進(jìn)程)和這個(gè)容器進(jìn)程之間沒(méi)有關(guān)系。如果我們查看進(jìn)程表,我們會(huì)看到容器的父進(jìn)程是PID 1:

  1. # ps axfo pid,ppid,command 
  2. 4258     1 sleep infinite 

Docker、containerd、CRI-O 等使用分離模式。它的目的是簡(jiǎn)化 runc 和全功能容器管理工具之間的集成。值得一提的是 runc 本身并不是某種類型的庫(kù)——它是一個(gè) CLI。當(dāng)其他工具使用 runc 時(shí),它們會(huì)調(diào)用我們剛剛在操作中看到的相同 runc 命令。

在runc 文檔中閱讀有關(guān)前臺(tái)模式和分離模式之間差異的更多信息。雖然容器進(jìn)程的PID是4258,但在容器內(nèi)部PID顯示為1:

  1. # runc exec test ps                      
  2. PID   USER     TIME  COMMAND 
  3.     1 root      0:00 sleep infinite 
  4.    13 root      0:00 ps 

這要?dú)w功于Linux 命名空間,它是真正的容器背后的基本技術(shù)之一。我們可以通過(guò)lsns在主機(jī)系統(tǒng)上執(zhí)行來(lái)列出所有當(dāng)前的命名空間 :

  1. # lsns 
  2. NS TYPE   NPROCS   PID USER COMMAND 
  3. 4026532219 mnt         1  4258 root sleep infinite 
  4. 4026532220 uts         1  4258 root sleep infinite 
  5. 4026532221 ipc         1  4258 root sleep infinite 
  6. 4026532222 pid         1  4258 root sleep infinite 
  7. 4026532224 net         1  4258 root sleep infinite 

runc 負(fù)責(zé)我們?nèi)萜鬟M(jìn)程的進(jìn)程、網(wǎng)絡(luò)、掛載和其他命名空間。

容器世界的影子統(tǒng)治者

Podman、Docker 和所有其他工具,包括在那里運(yùn)行的大多數(shù) Kubernetes 集群,都?xì)w結(jié)為runc啟動(dòng)容器進(jìn)程的二進(jìn)制文件。

在實(shí)際工作中,幾乎永遠(yuǎn)不會(huì)做我剛剛給你展示的事情 - 除非正在開(kāi)發(fā)或者調(diào)試自己的或現(xiàn)有的容器工具。不能從容器映像中組裝應(yīng)用程序包,并且使用 Podman 而不是直接使用 runc 會(huì)更好。

runc就是Low-Level實(shí)現(xiàn)的實(shí)現(xiàn),我們了解幕后發(fā)生的事情以及運(yùn)行容器真正涉及的內(nèi)容是非常有幫助的。最終用戶和最終容器過(guò)程之間仍然有很多層,但是如果了解最后一層,那么容器將不再是神奇的東西,有時(shí)也很奇怪。最后你會(huì)發(fā)現(xiàn)容器它只是 runc 在命名空間中生成一個(gè)進(jìn)程。當(dāng)然最后一層是Linux內(nèi)核,相比宇宙中有無(wú)數(shù)層。

runc 最重要的部分是它跟蹤 OCI運(yùn)行時(shí)規(guī)范。盡管幾乎每一個(gè)容器,這些天與runc催生,它不具有與runc催生。可以將其與遵循運(yùn)行時(shí)規(guī)范的任何其他容器運(yùn)行時(shí)交換,并且容器引擎(如 CRI-O)應(yīng)該以相同的方式工作。

High-Level容器運(yùn)行時(shí)可以不依賴于 runc 本身。它們依賴于一些遵循 OCI 規(guī)范的容器運(yùn)行時(shí)。這是當(dāng)今容器世界真正美麗的部分。

reference

[1]https://github.com/opencontainers/runtime-spec/blob/master/config.md

https://mkdev.me/en/posts/the-tool-that-really-runs-your-containers-deep-dive-into-runc-and-oci-specifications

https://github.com/opencontainers/runc/blob/master/docs/terminals.md

https://katacontainers.io/

https://polyverse.com/blog/skopeo-the-best-container-tool-you-need-to-know-about/ 

https://umo.ci/quick-start/workflow/

 

責(zé)任編輯:武曉燕 來(lái)源: 運(yùn)維開(kāi)發(fā)故事
相關(guān)推薦

2010-11-08 13:54:49

Sqlserver運(yùn)行

2017-05-23 16:11:40

紅帽PaaSOpenShift

2010-10-26 11:28:33

ORACLE運(yùn)行方式

2012-05-14 17:22:38

ibmdw

2010-06-23 20:31:54

2010-07-13 09:36:25

2010-11-19 16:22:14

Oracle事務(wù)

2022-08-26 13:48:40

EPUBLinux

2009-08-25 16:27:10

Mscomm控件

2020-09-21 09:53:04

FlexCSS開(kāi)發(fā)

2023-09-26 00:40:35

Docker容器操作命令

2020-07-20 06:35:55

BashLinux

2023-10-06 00:04:02

2019-08-02 08:59:21

Token認(rèn)證服務(wù)器

2019-11-29 16:21:22

Spring框架集成

2017-01-20 08:30:19

JavaScriptfor循環(huán)

2018-02-24 13:21:02

2018-09-04 16:20:46

MySQ索引數(shù)據(jù)結(jié)構(gòu)

2013-04-10 11:16:19

iPad的MouseE

2016-10-20 08:46:17

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 在线观看三级av | 女同久久另类99精品国产 | 草樱av| 亚洲精品视频二区 | 日韩一级不卡 | 中文字幕在线免费 | 羞羞色在线观看 | 欧美精品乱码久久久久久按摩 | 综合色播 | 亚洲综合无码一区二区 | 亚洲九九色 | 中文字幕第十一页 | 久草在线视频中文 | 国产激情视频在线观看 | 亚洲高清视频在线 | 日本a v在线播放 | 亚洲一区精品在线 | 在线一区 | 日韩视频在线一区二区 | 成人亚洲精品久久久久软件 | 在线观看亚洲专区 | 91视频久久 | 在线播放中文字幕 | 亚洲天堂中文字幕 | 午夜电影网 | 亚洲成网站 | 真人一级毛片 | 国产精品视频久久 | 天天干精品 | 伊人免费在线观看高清 | 欧美高清视频在线观看 | 亚洲成人精品一区 | 国产大学生情侣呻吟视频 | 久久精品日产第一区二区三区 | 国产精品久久久久久亚洲调教 | 日韩国产精品一区二区三区 | 成人性视频免费网站 | 欧美成人一级 | 激情欧美一区二区三区中文字幕 | 亚洲资源在线 | 精品国产一区二区国模嫣然 |