天天看點

CRI-O, Containerd, Docker, Postman等概念介紹

作者:散文随風想

參考:Docker,containerd,CRI,CRI-O,OCI,runc 分不清?看這一篇就夠了

Docker, containerd, CRI-O and runc之間的差別?

Docker、Podman、Containerd 誰才是真正王者?

CRI-O vs Podman vs Docker vs CRI-containerd

1 容器的主要标準:

  • Open Container Initiative (OCI) ,定義容器和鏡像的标準
  • Container Runtime Interface (CRI),它定義了Kubernetes和下面的容器運作時之間的API。
  • OCI:
    • OCI (Open Container Initiative),是一個輕量級,開放的治理結構(項目)。在 Linux 基金會的支援下成立,緻力于圍繞容器格式和運作時建立開放的行業标準。
    • OCI 項目由 Docker、CoreOS 和容器行業中的其它上司者在 2015 年 6 月的時候啟動,OCI 的技術委員會成員包括 Red Hat、Microsoft、Docker、Cruise、IBM、Google、Red Hat 和 SUSE 等。
  • CRI:
    • CRI(Container Runtime Interface)是 Kubernetes v1.5 引入的容器運作時接口,它将 Kubelet 與容器運作時解耦,将原來完全面向 Pod 級别的内部接口拆分成面向 Sandbox 和 Container 的 gRPC 接口,并将鏡像管理和容器管理分離到不同的服務。

2 CRI-O, Docker, Containerd三者差別

  1. CRI-O:
    1. 實作了容器運作時接口(CRI)的進階别容器運作時,實作了CRI規範。
    2. 可以使用 OCI(開放容器倡議)相容的運作時,是 containerd 的一個替代品。
    3. 是專門為Kubernetes建立的一個容器運作時,與 containerd 相同,提供了拉取、推送鏡像,管理網絡,存儲的能力,
    4. 通過直接調用底層的runc,實作啟動、停止和重新開機容器的管理.
    5. CRI-O 誕生于 RedHat、IBM、英特爾、SUSE、Hyper 等公司。
  2. Podman:
    1. Podman原來是CRI-O項目的一部分,後來被分離成了一個單獨的項目libpod。
  3. Docker:
    1. 需要先調用dockershim,然後調用docker,再調用containerd,最後調用底層的 runc.
  4. CRI-Containerd:
    1. 是CRI的實作,通過Containerd調用底層的runc.
  5. Containerd:
    1. Containerd是一個程序,是CRI-Containerd的實作,用來拉取、推送鏡像,管理網絡,存儲,調用底層runc來運作容器,并且管理容器的運作。
    2. containerd 是一個來自 Docker 的進階容器運作時,并實作了 CRI 規範。
    3. containerd從 Docker 項目中分離出來,使Docker更加子產品化,之後 containerd 被捐贈給雲原生計算基金會(CNCF)為容器社群提供建立新容器解決方案的基礎。
    4. Docker 内部使用 containerd,安裝 Docker 時也會安裝 containerd。
    5. containerd 通過其 CRI 插件實作了 Kubernetes 容器運作時接口(CRI),它可以管理容器的整個生命周期,包括從鏡像的傳輸、存儲到容器的執行、監控再到網絡。
  • runc:
    • 底層容器運作時,或者實際建立和運作容器的元件,它包括libcontainer,這是一個基于go的本地實作,用于建立、啟動、停止和重新開機容器的管理。
    • runc 是輕量級的通用運作時容器,它遵守 OCI 規範,是實作 OCI 接口的最低級别的元件,與核心互動建立并運作容器。
    • runc 為容器提供了所有的低級功能,與現有的低級 Linux 功能互動,如命名空間和控制組,它使用這些功能來建立和運作容器程序。
    • runc 是一個在 Linux 上運作容器的工具,是以這意味着它可以在 Linux 上、裸機上或虛拟機内運作。
    • runc 的幾個替代品:
      • crun [5]:一個用 C 語言編寫的容器運作時(相比之下,runc 是用Go編寫的。)來自 Katacontainers 項目的 kata-runtime [6] 它将 OCI 規範實作為單獨的輕量級虛拟機(硬體虛拟化)。
      • Google 的 gVisor [7],建立了擁有自己核心的容器,在其運作時中實作了 OCI,稱為 runsc。
  • dockershim:
    • Docker比Kubernetes更古老,沒有實作CRI。dockershim把Docker連接配接到Kubernetes上,或者是Kubernetes連接配接到Docker上。
    • dockershim支援将 Docker 被寫死到 Kubernetes 中。随着容器化成為行業标準,Kubernetes 項目增加了對額外運作時的支援,比如通過 Container Runtime Interface (CRI) 容器運作時接口來支援運作容器。是以 dockershim 成為了 Kubernetes 項目中的一個異類,對 Docker 和 dockershim 的依賴已經滲透到雲原生計算基金會(CNCF)生态系統中的各種工具和項目中,導緻代碼脆弱。
    • 2022 年 4 月 dockershim 将會從 Kubernetes 1.24 中完全移除。今後 Kubernetes 将取消對 Docker 的直接支援,而傾向于隻使用實作其容器運作時接口的容器運作時,這可能意味着使用 containerd 或 CRI-O。這并不意味着 Kubernetes 不能運作 Docker 格式的容器。
    • containerd 和 CRI-O 都可以運作 Docker 格式(實際上是 OCI 格式)的鏡像,它們隻是無需使用 docker 指令或 Docker 守護程式。
CRI-O, Containerd, Docker, Postman等概念介紹

3 Docker,k8s,CRI, OCI, containerd和runc關系圖

CRI-O, Containerd, Docker, Postman等概念介紹

4 Docker VS Podman

CRI-O, Containerd, Docker, Postman等概念介紹
Podman與Linux核心互動,通過runC容器運作時程序而不是Daemon來管理容器。Buildah實用程式用于替代Docker build作為容器鏡像建構工具,Docker push被Skopeo替代,用于在系統資料庫和容器引擎之間移動容器鏡像。

(1) 架構

Docker使用守護程序,一個正在背景運作的程式,來建立鏡像和運作容器。Podman是無守護程序的架構,這意味着它可以在啟動容器的使用者下運作容器。Docker有一個由守護程序引導的用戶端——伺服器邏輯架構;但Podman不需要此類守護程序。

(2) Root特權

由于Podman沒有守護程序來管理其活動,也無需為其容器配置設定Root特權。Docker最近在其守護程序配置中添加了Rootless模式,但Podman首先使用了這種方法,并将其作為基本特性進行了推廣。原因如下。

(3) 安全

Podman比Docker安全嗎?Podman允許容器使用Rootless特權。Rootless容器被認為比Root特權的容器更安全。在Docker中,守護程序擁有Root權限,這使得它們易成為攻擊者的首選入侵點。

Podman中的容器預設情況下不具有Root通路權限,這在Root級别和Rootless級别之間添加了一個自然屏障,提高了安全性。不過,Podman可以同時運作Root容器和Rootless容器。

(4) Systemd

如果沒有守護程序,Podman需要另一個工具來管理服務并支援背景運作的容器。Systemd為現有容器建立控制單元或用來生成新容器。Systemd還可以與Podman內建,允許它在預設情況下運作啟用了Systemd的容器,進而無需進行任何修改。

通過使用Systemd,供應商可以将他們的應用程式封裝為容器用來安裝、運作和管理,因為現在大多數應用程式都是通過這種方式打包和傳遞的。

(5) 建構鏡像

作為一款自給自足的工具,Docker可以自己建構容器鏡像。Podman則需要另一種名為Buildah的工具的輔助,該工具充分展現了它的特殊性:它是為建構鏡像而設計的,而不是為建構容器而生。

(6) Docker Swarm

Podman不支援Docker Swarm,這可能會在某些項目中被刨除在外,因為使用Docker Swarm指令會産生一個錯誤。然而,Podman最近增加了對Docker Compose的支援,使其與Swarm相容,進而克服了這個限制。當然,Docker由于其原生的特性,與Swarm當然融合得很好。

(7) All in one vs 子產品化

Docker是一個獨立的、強大的工具,在整個循環中處理所有的容器化任務,有優點也有缺點。Podman采用子產品化的方法,依靠專門的工具來完成特定的任務。

5 Docker容器運作架構圖

當用docker指令運作一個容器時,實際上是通過docker守護程序調用containerd,然後containerd調用runc運作容器。
  • docker:指令行工具,終端使用者使用這個指令來和docker進行互動
  • containerd,containerd是一個程序,用來拉取、推送鏡像,管理網絡,存儲,然後使用runc來運作容器,并且管理容器的運作
  • runc:這是底層容器運作時,或者實際建立和運作容器的元件)。它包括libcontainer,這是一個基于go的本地實作,用于建立容器
CRI-O, Containerd, Docker, Postman等概念介紹
CRI-O, Containerd, Docker, Postman等概念介紹

6 原始容器運作時Runc

最終使用者到實際的容器調用鍊示意圖:

CRI-O, Containerd, Docker, Postman等概念介紹
  • runc 是一個指令行用戶端,用于運作根據 Open Container Initiative (OCI) 格式打包的應用程式,并且是 Open Container Initiative 規範的相容實作。
  • runc 符合容器和管理容器映像的開放容器計劃(OCI) 和規範,也有其他符合 OCI 的運作時,甚至可以運作符合 OCI 标準的虛拟機,Kata Containers 與gVisor就是符合符合 OCI 标準的虛拟機。gVisor 為代表的使用者态 Kernel 方案是安全容器的未來,隻是現在還不夠完善。
  • runc 希望提供一個“ OCI 包”,它隻是一個根檔案系統和一個config.json 檔案。而不是Podman 或 Docker 那樣有“鏡像”概念,是以不能隻執行runc run nginx:latest這樣來啟動一個容器。
  • Runc 符合 OCI 規範(具體來說,是runtime-spec),可以使用 OCI 包并從中運作一個容器。值得重申的是,這些bundle并不是“容器鏡像”,它們要簡單得多。層、标簽、容器系統資料庫和存儲庫等功能 - 所有這些都不是 OCI 包甚至運作時規範的一部分。有一個單獨的 OCI-spec (image-spec )定義鏡像。