自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

淺析Docker、Containerd、RunC分別是什么

開(kāi)源
Docker、Google、CoreOS 和其他供應(yīng)商創(chuàng)建了開(kāi)放容器計(jì)劃 (OCI),目前主要有兩個(gè)標(biāo)準(zhǔn)文檔:容器運(yùn)行時(shí)標(biāo)準(zhǔn) (runtime spec)和 容器鏡像標(biāo)準(zhǔn)(image spec)。

[[431465]]

什么是RunC

上一遍文章《真正運(yùn)行容器的工具:深入了解 runc 和 OCI 規(guī)范》已經(jīng)講清楚了Runc與OCI。這里再講解一下概念。

Docker、Google、CoreOS 和其他供應(yīng)商創(chuàng)建了開(kāi)放容器計(jì)劃 (OCI),目前主要有兩個(gè)標(biāo)準(zhǔn)文檔:容器運(yùn)行時(shí)標(biāo)準(zhǔn) (runtime spec)和 容器鏡像標(biāo)準(zhǔn)(image spec)。

OCI 對(duì)容器 runtime 的標(biāo)準(zhǔn)主要是指定容器的運(yùn)行狀態(tài),和 runtime 需要提供的命令。下圖可以是容器狀態(tài)轉(zhuǎn)換圖:

  • init 狀態(tài):這個(gè)是我自己添加的狀態(tài),并不在標(biāo)準(zhǔn)中,表示沒(méi)有容器存在的初始狀態(tài)
  • creating:使用 create 命令創(chuàng)建容器,這個(gè)過(guò)程稱為創(chuàng)建中
  • created:容器創(chuàng)建出來(lái),但是還沒(méi)有運(yùn)行,表示鏡像和配置沒(méi)有錯(cuò)誤,容器能夠運(yùn)行在當(dāng)前平臺(tái)
  • running:容器的運(yùn)行狀態(tài),里面的進(jìn)程處于 up 狀態(tài),正在執(zhí)行用戶設(shè)定的任務(wù)
  • stopped:容器運(yùn)行完成,或者運(yùn)行出錯(cuò),或者 stop 命令之后,容器處于暫停狀態(tài)。這個(gè)狀態(tài),容器還有很多信息保存在平臺(tái)中,并沒(méi)有完全被刪除

Runc的來(lái)歷

RunC 是從 Docker 的 libcontainer 中遷移而來(lái)的,實(shí)現(xiàn)了容器啟停、資源隔離等功能。Docker將RunC捐贈(zèng)給 OCI 作為OCI 容器運(yùn)行時(shí)標(biāo)準(zhǔn)的參考實(shí)現(xiàn)。Docker 默認(rèn)提供了 docker-runc 實(shí)現(xiàn)。事實(shí)上,通過(guò) containerd 的封裝,可以在 Docker Daemon 啟動(dòng)的時(shí)候指定 RunC的實(shí)現(xiàn)。最初,人們對(duì) Docker 對(duì) OCI 的貢獻(xiàn)感到困惑。他們貢獻(xiàn)的是一種“運(yùn)行”容器的標(biāo)準(zhǔn)方式,僅此而已。它們不包括鏡像格式或注冊(cè)表推/拉格式。當(dāng)你運(yùn)行一個(gè) Docker 容器時(shí),這些是 Docker 實(shí)際經(jīng)歷的步驟:

  • 下載鏡像
  • 將鏡像文件解開(kāi)為bundle文件,將一個(gè)文件系統(tǒng)拆分成多層
  • 從bundle文件運(yùn)行容器

Docker標(biāo)準(zhǔn)化的僅僅是第三步。在此之前,每個(gè)人都認(rèn)為容器運(yùn)行時(shí)支持Docker支持的所有功能。最終,Docker方面澄清:原始OCI規(guī)范指出,只有“運(yùn)行容器”的部分組成了runtime。這種“概念失聯(lián)”一直持續(xù)到今天,并使“容器運(yùn)行時(shí)”成為一個(gè)令人困惑的話題。希望我能證明雙方都不是完全錯(cuò)誤的,并且在本文中將廣泛使用該術(shù)語(yǔ)。RunC 就可以按照這個(gè) OCI 文檔來(lái)創(chuàng)建一個(gè)符合規(guī)范的容器,既然是標(biāo)準(zhǔn)肯定就有其他 OCI 實(shí)現(xiàn),比如 Kata、gVisor 這些容器運(yùn)行時(shí)都是符合 OCI 標(biāo)準(zhǔn)的。

怎么使用 runc

  1.  create the bundle 
  2. $ mkdir -p /mycontainer/rootfs 
  3.  
  4. # [ab]use Docker to copy a root fs into the bundle 
  5. $ docker export $(docker create busybox) | tar -C /mycontainer/rootfs -xvf - 
  6.  
  7. create the specification, by default sh will be the entrypoint of the container 
  8. $ cd /mycontainer 
  9. $ runc spec 
  10.  
  11. # launch the container 
  12. $ sudo -i 
  13. $ cd /mycontainer 
  14. $ runc run mycontainerid 
  15.  
  16. # list containers 
  17. $ runc list 
  18.  
  19. # stop the container 
  20. $ runc kill mycontainerid 
  21.  
  22. # cleanup 
  23. $ runc delete mycontainerid 

在命令行中使用 runc,我們可以根據(jù)需要啟動(dòng)任意數(shù)量的容器。但是,如果我們想自動(dòng)化這個(gè)過(guò)程,我們需要一個(gè)容器管理器。為什么這樣?想象一下,我們需要啟動(dòng)數(shù)十個(gè)容器來(lái)跟蹤它們的狀態(tài)。其中一些需要在失敗時(shí)重新啟動(dòng),需要在終止時(shí)釋放資源,必須從注冊(cè)表中提取圖像,需要配置容器間網(wǎng)絡(luò)等等。就需要有Low-Level和High-Level容器運(yùn)行時(shí),runc就是Low-Level實(shí)現(xiàn)的實(shí)現(xiàn)。

Low-Level和High-Level容器運(yùn)行時(shí)

當(dāng)人們想到容器運(yùn)行時(shí),可能會(huì)想到一系列示例;runc、lxc、lmctfy、Docker(容器)、rkt、cri-o。這些中的每一個(gè)都是為不同的情況而構(gòu)建的,并實(shí)現(xiàn)了不同的功能。有些,如 containerd 和 cri-o,實(shí)際上使用 runc 來(lái)運(yùn)行容器,在High-Level實(shí)現(xiàn)鏡像管理和 API。與 runc 的Low-Level實(shí)現(xiàn)相比,可以將這些功能(包括鏡像傳輸、鏡像管理、鏡像解包和 API)視為High-Level功能??紤]到這一點(diǎn),您可以看到容器運(yùn)行時(shí)空間相當(dāng)復(fù)雜。每個(gè)運(yùn)行時(shí)都涵蓋了這個(gè)Low-Level到High-Level頻譜的不同部分。這是一個(gè)非常主觀的圖表:

因此,從實(shí)際出發(fā),通常只專注于正在運(yùn)行的容器的runtime通常稱為“Low-Level容器運(yùn)行時(shí)”,支持更多高級(jí)功能(如鏡像管理和gRPC / Web API)的運(yùn)行時(shí)通常稱為“High-Level容器運(yùn)行時(shí)”,“High-Level容器運(yùn)行時(shí)”或通常僅稱為“容器運(yùn)行時(shí)”,我將它們稱為“High-Level容器運(yùn)行時(shí)”。值得注意的是,Low-Level容器運(yùn)行時(shí)和High-Level容器運(yùn)行時(shí)是解決不同問(wèn)題的、從根本上不同的事物。

  • Low-Level容器運(yùn)行時(shí):容器是通過(guò)Linux nanespace和Cgroups實(shí)現(xiàn)的,Namespace能讓你為每個(gè)容器提供虛擬化系統(tǒng)資源,像是文件系統(tǒng)和網(wǎng)絡(luò),Cgroups提供了限制每個(gè)容器所能使用的資源的如內(nèi)存和CPU使用量的方法。在最低級(jí)別的運(yùn)行時(shí)中,容器運(yùn)行時(shí)負(fù)責(zé)為容器建立namespaces和cgroups,然后在其中運(yùn)行命令,Low-Level容器運(yùn)行時(shí)支持在容器中使用這些操作系統(tǒng)特性。目前來(lái)看低級(jí)容器運(yùn)行時(shí)有:runc :我們最熟悉也是被廣泛使用的容器運(yùn)行時(shí),代表實(shí)現(xiàn)Docker。runv:runV 是一個(gè)基于虛擬機(jī)管理程序(OCI)的運(yùn)行時(shí)。它通過(guò)虛擬化 guest kernel,將容器和主機(jī)隔離開(kāi)來(lái),使得其邊界更加清晰,這種方式很容易就能幫助加強(qiáng)主機(jī)和容器的安全性。代表實(shí)現(xiàn)是kata和Firecracker。runsc:runsc = runc + safety ,典型實(shí)現(xiàn)就是谷歌的gvisor,通過(guò)攔截應(yīng)用程序的所有系統(tǒng)調(diào)用,提供安全隔離的輕量級(jí)容器運(yùn)行時(shí)沙箱。截止目前,貌似并不沒(méi)有生產(chǎn)環(huán)境使用案例。wasm : Wasm的沙箱機(jī)制帶來(lái)的隔離性和安全性,都比Docker做的更好。但是wasm 容器處于草案階段,距離生產(chǎn)環(huán)境尚有很長(zhǎng)的一段路。
  • High-Level容器運(yùn)行時(shí):通常情況下,開(kāi)發(fā)人員想要運(yùn)行一個(gè)容器不僅僅需要Low-Level容器運(yùn)行時(shí)提供的這些特性,同時(shí)也需要與鏡像格式、鏡像管理和共享鏡像相關(guān)的API接口和特性,而這些特性一般由High-Level容器運(yùn)行時(shí)提供。就日常使用來(lái)說(shuō),Low-Level容器運(yùn)行時(shí)提供的這些特性可能滿足不了日常所需,因?yàn)檫@個(gè)緣故,唯一會(huì)使用Low-Level容器運(yùn)行時(shí)的人是那些實(shí)現(xiàn)High-Level容器運(yùn)行時(shí)以及容器工具的開(kāi)發(fā)人員。那些實(shí)現(xiàn)Low-Level容器運(yùn)行時(shí)的開(kāi)發(fā)者會(huì)說(shuō)High-Level容器運(yùn)行時(shí)比如containerd和cri-o不像真正的容器運(yùn)行時(shí),因?yàn)閺乃麄兊慕嵌葋?lái)看,他們將容器運(yùn)行的實(shí)現(xiàn)外包給了runc。但是從用戶的角度來(lái)看,它們只是提供容器功能的單個(gè)組件,可以被另一個(gè)的實(shí)現(xiàn)替換,因此從這個(gè)角度將其稱為runtime仍然是有意義的。即使containerd和cri-o都使用runc,但是它們是截然不同的項(xiàng)目,支持的特性也是非常不同的。dockershim, containerd 和cri-o都是遵循CRI的容器運(yùn)行時(shí),我們稱他們?yōu)楦邔蛹?jí)運(yùn)行時(shí)(High-level Runtime)。

Kubernetes 只需支持 containerd 等high-level container runtime即可。由containerd 按照OCI 規(guī)范去對(duì)接不同的low-level container runtime,比如通用的runc,安全增強(qiáng)的gvisor,隔離性更好的runv。

containerd

與RunC_一樣_,我們又可以在這里看到一個(gè)docker公司的開(kāi)源產(chǎn)品containerd曾經(jīng)是開(kāi)源docker項(xiàng)目的一部分。盡管_containerd_是另一個(gè)自給自足的軟件。

  • 一方面,它稱自己為容器運(yùn)行時(shí),但是與運(yùn)行時(shí)__RunC_不同_。不僅_containerd_和_runc_的職責(zé)不同,組織形式也不同。顯然_runc_是只是一個(gè)命令行工具,_containerd_是一個(gè)長(zhǎng)期居住守護(hù)進(jìn)程。_runc_的實(shí)例不能超過(guò)底層容器進(jìn)程。通常它在create調(diào)用時(shí)開(kāi)始它的生命,然后只是在容器的 rootfs 中的指定文件去運(yùn)行。
  • 另一方面,_containerd _可以管理超過(guò)數(shù)千個(gè)_runc_容器。它更像是一個(gè)服務(wù)器,它偵聽(tīng)傳入請(qǐng)求以啟動(dòng)、停止或報(bào)告容器的狀態(tài)。在引擎蓋下_containerd_使用RunC。然而,_containerd_不僅僅是一個(gè)容器生命周期管理器。它還負(fù)責(zé)鏡像管理(從注冊(cè)中心拉取和推送鏡像,在本地存儲(chǔ)鏡像等)、跨容器網(wǎng)絡(luò)管理和其他一些功能。

containerd 是一個(gè)工業(yè)級(jí)標(biāo)準(zhǔn)的容器運(yùn)行時(shí),它強(qiáng)調(diào)簡(jiǎn)單性、健壯性和可移植性,containerd 可以負(fù)責(zé)干下面這些事情:

  • 管理容器的生命周期(從創(chuàng)建容器到銷毀容器)
  • 拉取/推送容器鏡像
  • 存儲(chǔ)管理(管理鏡像及容器數(shù)據(jù)的存儲(chǔ))
  • 調(diào)用 runc 運(yùn)行容器(與 runc 等容器運(yùn)行時(shí)交互)
  • 管理容器網(wǎng)絡(luò)接口及網(wǎng)絡(luò)

上圖是 Containerd 整體的架構(gòu)。由下往上,Containerd支持的操作系統(tǒng)和架構(gòu)有 Linux、Windows 以及像 ARM 的一些平臺(tái)。在這些底層的操作系統(tǒng)之上運(yùn)行的就是底層容器運(yùn)行時(shí),其中有上文提到的runc、gVisor 等。在底層容器運(yùn)行時(shí)之上的是Containerd 相關(guān)的組件,比如 Containerd 的 runtime、core、API、backend、store 還有metadata 等等。構(gòu)筑在 Containerd 組件之上以及跟這些組件做交互的都是 Containerd 的 client,Kubernetes 跟 Containerd 通過(guò) CRI 做交互時(shí),本身也作為 Containerd 的一個(gè) client。Containerd 本身有提供了一個(gè) CRI,叫 ctr,不過(guò)這個(gè)命令行工具并不是很好用。

在這些組件之上就是真正的平臺(tái),Google Cloud、Docker、IBM、阿里云、微軟云還有RANCHER等等都是,這些平臺(tái)目前都已經(jīng)支持 containerd, 并且有些已經(jīng)作為自己的默認(rèn)容器運(yùn)行時(shí)了。

從 k8s 的角度看,選擇 containerd作為運(yùn)行時(shí)的組件,它調(diào)用鏈更短,組件更少,更穩(wěn)定,占用節(jié)點(diǎn)資源更少。

Docker

Docker 于 2013 年發(fā)布,解決了開(kāi)發(fā)人員在端到端運(yùn)行容器時(shí)遇到的許多問(wèn)題。這里是他包含的所有東西:

  • 容器鏡像格式
  • 一種構(gòu)建容器鏡像的方法(Dockerfile/docker build);
  • 一種管理容器鏡像(docker image、docker rm等);
  • 一種管理容器實(shí)例的方法(docker ps, docker rm 等);
  • 一種共享容器鏡像的方法(docker push/pull);
  • 一種運(yùn)行容器的方式(docker run);

當(dāng)時(shí),Docker 是一個(gè)單體系統(tǒng)。但是,這些功能中沒(méi)有一個(gè)是真正相互依賴的。這些中的每一個(gè)都可以在可以一起使用的更小、更集中的工具中實(shí)現(xiàn)。每個(gè)工具都可以通過(guò)使用一種通用格式、一種容器標(biāo)準(zhǔn)來(lái)協(xié)同工作。從 Docker 1.11 之后,Docker Daemon 被分成了多個(gè)模塊以適應(yīng) OCI 標(biāo)準(zhǔn)。拆分之后,結(jié)構(gòu)分成了以下幾個(gè)部分。

其中,containerd 獨(dú)立負(fù)責(zé)容器運(yùn)行時(shí)和生命周期(如創(chuàng)建、啟動(dòng)、停止、中止、信號(hào)處理、刪除等),其他一些如鏡像構(gòu)建、卷管理、日志等由 Docker Daemon 的其他模塊處理。

Docker 的模塊塊擁抱了開(kāi)放標(biāo)準(zhǔn),希望通過(guò) OCI 的標(biāo)準(zhǔn)化,容器技術(shù)能夠有很快的發(fā)展。

現(xiàn)在創(chuàng)建一個(gè)docker容器的時(shí)候,Docker Daemon 并不能直接幫我們創(chuàng)建了,而是請(qǐng)求 containerd 來(lái)創(chuàng)建一個(gè)容器。當(dāng)containerd 收到請(qǐng)求后,也不會(huì)直接去操作容器,而是創(chuàng)建一個(gè)叫做 containerd-shim 的進(jìn)程。讓這個(gè)進(jìn)程去操作容器,我們指定容器進(jìn)程是需要一個(gè)父進(jìn)程來(lái)做狀態(tài)收集、維持 stdin 等 fd 打開(kāi)等工作的,假如這個(gè)父進(jìn)程就是 containerd,那如果 containerd 掛掉的話,整個(gè)宿主機(jī)上所有的容器都得退出了,而引入 containerd-shim 這個(gè)墊片就可以來(lái)規(guī)避這個(gè)問(wèn)題了,就是提供的live-restore的功能。這里需要注意systemd的 MountFlags=slave。

然后創(chuàng)建容器需要做一些 namespaces 和 cgroups 的配置,以及掛載 root 文件系統(tǒng)等操作。runc 就可以按照這個(gè) OCI 文檔來(lái)創(chuàng)建一個(gè)符合規(guī)范的容器。

真正啟動(dòng)容器是通過(guò) containerd-shim 去調(diào)用 runc 來(lái)啟動(dòng)容器的,runc 啟動(dòng)完容器后本身會(huì)直接退出,containerd-shim 則會(huì)成為容器進(jìn)程的父進(jìn)程, 負(fù)責(zé)收集容器進(jìn)程的狀態(tài), 上報(bào)給 containerd, 并在容器中 pid 為 1 的進(jìn)程退出后接管容器中的子進(jìn)程進(jìn)行清理, 確保不會(huì)出現(xiàn)僵尸進(jìn)程。containerd,containerd-shim和容器進(jìn)程(即容器主進(jìn)程)三個(gè)進(jìn)程,是有依賴關(guān)系的??梢詤⒖肌禼ontainerd,containerd-shim和runc的依存關(guān)系》[1],查看怎么保證live-restore的功能的。

reference

https://www.ianlewis.org/en/container-runtimes-part-1-introduction-container-r

https://iximiuz.com/en/posts/journey-from-containerization-to-orchestration-and-beyond/#container-management

https://github.com/moby/moby/issues/35873#issuecomment-386467562

[1]https://fankangbest.github.io/2017/11/24/containerd-containerd-shim%E5%92%8Crunc%E7%9A%84%E4%BE%9D%E5%AD%98%E5%85%B3%E7%B3%BB/

本文轉(zhuǎn)載自微信公眾號(hào)「運(yùn)維開(kāi)發(fā)故事」

 

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

2023-02-24 08:03:24

ChatGPT人臉識(shí)別分支

2021-12-30 10:30:12

RunC命令Linux

2021-12-09 22:47:44

區(qū)塊鏈加密貨幣比特幣

2022-10-19 12:00:32

CSS 偽類偽元素

2019-07-17 13:41:36

VueReactJSX

2022-10-26 15:10:46

CSS數(shù)據(jù)開(kāi)發(fā)

2021-07-02 16:30:01

CICDDevOps

2010-09-08 17:40:56

協(xié)議棧是什么

2021-08-13 05:50:01

ContainerdDockerKubernetes

2023-10-23 11:07:37

HTTPRPC

2022-11-15 10:03:34

2023-06-09 09:10:06

nftablesiptables

2021-03-15 14:00:56

PythonC語(yǔ)言編程語(yǔ)言

2016-03-21 10:40:53

RDDSpark SQL數(shù)據(jù)集

2017-11-21 22:49:10

2024-12-30 07:20:00

Redis數(shù)據(jù)庫(kù)MySQL

2020-09-06 22:04:48

Python運(yùn)算符開(kāi)發(fā)

2025-02-06 08:44:11

MySQLEXISTSIN

2018-05-21 21:26:59

Apache HiveHbaseSQL

2012-07-31 15:52:48

云計(jì)算網(wǎng)格計(jì)算
點(diǎn)贊
收藏

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