寫(xiě)在前面
- 博文內(nèi)容整體結(jié)構(gòu)為結(jié)合
華為云云原生課程
整理而來(lái),部分內(nèi)容做了補(bǔ)充 - 課程是免費(fèi)的,有華為云賬戶就可以看,適合理論認(rèn)知,感覺(jué)很不錯(cuò)。
- 有需要的小伙伴可以看看,鏈接在文末
- 理解不足小伙伴幫忙指正
對(duì)每個(gè)人而言,真正的職責(zé)只有一個(gè):找到自我。然后在心中堅(jiān)守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是對(duì)大眾理想的懦弱回歸,是隨波逐流,是對(duì)內(nèi)心的恐懼 ——赫爾曼·黑塞《德米安》
為什么從 CRI
講起,因?yàn)?k8s 集群使用 kubelet
服務(wù)通過(guò) CRI
接口和對(duì)應(yīng)的 runtime(運(yùn)行時(shí))
交互,從而控制管理容器。
那 CRI
是什么? CRI 是一個(gè) Kubernetes API
,它定義了 Kubernetes
與不同容器運(yùn)行時(shí)
交互的方式。因?yàn)樗谝?guī)范中是標(biāo)準(zhǔn)化的,所以可以選擇要使用的 CRI
實(shí)現(xiàn)或編寫(xiě)自己的實(shí)現(xiàn)。
CRI
在 K8s
生態(tài)中通過(guò) CRI
接口來(lái)對(duì) 容器運(yùn)行時(shí)進(jìn)行管理,從而實(shí)現(xiàn)對(duì)容器鏡像的管理,具體一點(diǎn),通過(guò) kubelet
調(diào)用容器運(yùn)行時(shí)的 grpc
接口。
面向接口編程,類比在剛學(xué)編程時(shí), Java
中,操作數(shù)據(jù)庫(kù),使用 JDBC API
來(lái)連接不同的數(shù)據(jù)庫(kù)實(shí)現(xiàn) CRUD
,這里具體的數(shù)據(jù)操作通過(guò)不同數(shù)據(jù)庫(kù)的驅(qū)動(dòng)包
來(lái)實(shí)現(xiàn)。CRI
可以單純理解為JDBC
,CRI 實(shí)現(xiàn)類比不同的數(shù)據(jù)庫(kù)驅(qū)動(dòng)包
對(duì)于 CRI
接口,有下面的一些實(shí)現(xiàn)。
dockershim
: 由于 docker
沒(méi)有實(shí)現(xiàn) CRI 接口,所以 kubernetes
在最初對(duì)接 docker api
的時(shí)候提供了 CRI
接口適配器, 但是這是一種冗余的行為,k8s
只是需要 docker
中的 containerd
,完全可以直接使用 containerd
,所以在之后版本中刪除了這部分代碼, 在 kubernetes 1.21 版本已經(jīng)將其標(biāo)注為廢棄接口。在 1.24 版本中徹底移除了該部分代碼, 不過(guò) 如果任然想使用 docker ,可以使用開(kāi)源項(xiàng)目 cri-docker
來(lái)代替。在部署時(shí)需要單獨(dú)指定 socket
。
docker 的前置依賴,可以看到它依賴 containerd.service
┌──[root@vms100.liruilongs.github.io]-[~/ansible/openkruise]
└─$systemctl list-dependencies docker | head -n 3
docker.service
● ├─containerd.service
● ├─docker.socket
CRI-containerd
:基于 containerd 的 CRI 兼容插件,通過(guò) containerd
中的 CRI插件實(shí)現(xiàn)了CRI接口
,當(dāng)前使用最廣泛的 CRI接口接口實(shí)現(xiàn)
。性能好,功能全,適合需要利用 containerd 強(qiáng)大功能的場(chǎng)景。
CRI-O
:專注于在 kubernetes 運(yùn)行容器的輕量級(jí) CRl 接口實(shí)現(xiàn)(不關(guān)注開(kāi)發(fā)態(tài)),CRI-O 是基于 Open Container Initiative (OCI)
標(biāo)準(zhǔn)開(kāi)發(fā)的獨(dú)立容器管理引擎,獨(dú)立性好,適合注重兼容性和移植性的場(chǎng)景
CRI 接口由兩部分組成
CRI 接口由兩部分組成:
- 通過(guò)
RuntimeServiceServer
屬性來(lái)描述管理容器生命周期的相關(guān)行為,包括創(chuàng)建、刪除、啟動(dòng)、停止等容器操作, - 通過(guò)
ImageServiceServer
屬性來(lái)描述管理鏡像相關(guān)的行為,如拉取、推送鏡像等操作。
通過(guò)對(duì)這兩個(gè)行為接口委托
,實(shí)現(xiàn) CRI 接口,具體來(lái)說(shuō):
-
RuntimeServiceServer
定義了管理容器生命周期需要調(diào)用`的通用方法,如CreateContainer、StartContainer、StopContainer等。這些方法主要用于管理容器運(yùn)行時(shí)狀態(tài)。 -
ImageServiceServer
定義了鏡像管理需要調(diào)用的通用方法,如ListImages、PullImage、RemoveImage等。這些方法主要用于管理容器鏡像資源。
type grpcServices interface {
runtime.RuntimeServiceServer
runtime.ImageServiceServer
}
-
運(yùn)行時(shí)
:負(fù)責(zé)容器的生命周期管理
,包括容器創(chuàng)建,啟動(dòng)、停止、日志和性能采集等接口。 -
鏡像
:負(fù)責(zé)容器鏡像的管理
,包括顯示鏡像、拉取鏡像、刪除鏡像等接口。
在早期的CRI
實(shí)現(xiàn)中,Shimv1
是最常見(jiàn)的容器運(yùn)行時(shí)接口實(shí)現(xiàn)之一。它通過(guò)創(chuàng)建一個(gè)額外的代理進(jìn)程(Shim)來(lái)管理容器的生命周期,并與容器運(yùn)行時(shí)進(jìn)行通信。然而,Shimv1
存在一些性能和可靠性方面的限制。
為了改進(jìn)CRI的性能和穩(wěn)定性,Shimv2
被引入作為CRI
的改進(jìn)版本。
CRI Shimv2
Shimv2
使用了ttrpc(Tiny Transport Protocol RPC)作為通信協(xié)議
,通過(guò)與容器運(yùn)行時(shí)直接通信而無(wú)需創(chuàng)建額外的代理進(jìn)程。這種直接的通信方式可以提供更高效、更可靠的容器運(yùn)行時(shí)接口。
OCI
CRI 接口實(shí)現(xiàn)和容器運(yùn)行時(shí)交互,這里就要講到 OCI
OCI
組織:Linux基金會(huì)于2015年6月成立OCI(Open Container Initiative)
組織,旨在圍繞容器格式和運(yùn)行時(shí)
制定一個(gè)開(kāi)放的工業(yè)化標(biāo)準(zhǔn)
。
目前主要有兩個(gè)標(biāo)準(zhǔn)文檔:容器運(yùn)行時(shí)標(biāo)準(zhǔn)(runtime spec)
和容器鏡像標(biāo)準(zhǔn)(image spec)
Runtime spec
:容器運(yùn)行時(shí)標(biāo)準(zhǔn)
,定義了容器狀態(tài)和配置文件格式,容器生命周期管理命令格式和參數(shù)等。
image spec
:鏡像標(biāo)準(zhǔn)包
,定義了容器鏡像的文件系統(tǒng)、config 文件、manifest 文件、index 文件等。
容器標(biāo)準(zhǔn)中包含:
容器命令:容器生命周期管理命令、包括創(chuàng)建、啟動(dòng)、停止、刪除等。
#runc create <container id>
#runc start <container id>#runc state <container id>
#runc kill <container-id><signal>
#runc delete <container-id>
config.json
文件是OCI(Open Container Initiative)
規(guī)范定義的容器配置文件
,它定義了容器運(yùn)行時(shí)需要了解和使用的所有配置信息
。
-
rootfs
:容器內(nèi)部文件系統(tǒng)掛載點(diǎn)信息 -
mounts
:容器內(nèi)外部掛載的文件系統(tǒng)信息 -
process
:容器內(nèi)第一個(gè)進(jìn)程(pid=1)的設(shè)置,如cmd、args等 -
cgroups
:容器要加入的cgroup信息 -
namespaces
:容器所在的namespace,比如pid、network等 -
caps
:容器能使用的Linux capabilities -
annotations
等其它配置
主流的容器運(yùn)行時(shí):
這里需要說(shuō)明一下,我們常講的 容器運(yùn)行時(shí)
是一個(gè) 混合概念,包含低級(jí)別容器運(yùn)行時(shí),和高級(jí)別容器運(yùn)行時(shí),
低級(jí)容器運(yùn)行時(shí)
,比如runc、lxc、gVisor、Kata
容器等,它們主要負(fù)責(zé)真正與內(nèi)核進(jìn)行交互,創(chuàng)建和管理容器運(yùn)行時(shí)的內(nèi)核級(jí)別資源,如cgroups、namespaces
等。但無(wú)法直接管理鏡像。
高級(jí)容器運(yùn)行時(shí)
,比如Docker
引擎、Podman
、containerd
等,它們基于低級(jí)容器運(yùn)行時(shí)提供了更高層次的管理能力,可以管理容器生命周期并直接調(diào)用低級(jí)運(yùn)行時(shí),同時(shí)也內(nèi)置鏡像管理能力,能夠拉取、推送鏡像等。
兩者關(guān)系是,高級(jí)運(yùn)行時(shí)對(duì)低級(jí)運(yùn)行時(shí)進(jìn)行抽象,向上提供完整的容器管理接口。高級(jí)運(yùn)行時(shí)在內(nèi)部會(huì)調(diào)用對(duì)應(yīng)的低級(jí)運(yùn)行時(shí)來(lái)管理內(nèi)核級(jí)資源和運(yùn)行容器。
runc
runc: docker 捐獻(xiàn)給 OCI 社區(qū)的一個(gè) runtime spec
的參考實(shí)現(xiàn),docker 容器也是基于 runc 創(chuàng)建的。
利用 Linux 內(nèi)核特性,來(lái)隔離進(jìn)程:
-
Namespace
:資源和信息的可見(jiàn)性隔離,通過(guò)namespace隔離,容器中的應(yīng)用只能看到分配到該容器的資源、其他主機(jī)上的信息在容器中不可見(jiàn)。常用的namespace有PID(進(jìn)程號(hào))、MNT(掛載點(diǎn))、NET(網(wǎng)絡(luò))、UTS(主機(jī)名)和IPC(跨進(jìn)程通信)等 -
Cgroups
:資源使用量的隔離,通過(guò)cgroup、限制了容器使用的資源量,通過(guò)不同的子系統(tǒng),限制不同的資源。包括CPU、內(nèi)存、io帶寬、大頁(yè)、fd 數(shù)等等 - Capability:權(quán)限限制(最低特權(quán)原則),Capability是Linux系統(tǒng)設(shè)計(jì)的一種安全機(jī)制。它定義了一組
特權(quán)標(biāo)記
,可以細(xì)粒度控制進(jìn)程對(duì)系統(tǒng)資源的訪問(wèn)權(quán)限
,通過(guò)對(duì)進(jìn)程的capability定義,限制容器中的進(jìn)程調(diào)用某些系統(tǒng)調(diào)用,以達(dá)到容器進(jìn)程無(wú)法逃逸到主機(jī)
的目的,比如容器中的進(jìn)程是不具有以下capability
的: SYS ADMIN/MKNOD/SYS RESOURCE/SYS MODULES.…
容器主進(jìn)程
1 1898 1898 1034 ? -1 Sl 0 0:34 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 057fb
1898 1957 1957 1957 ? -1 Ss 65535 0:00 \_ /pause
1 2013 2013 1034 ? -1 Sl 0 2:58 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 7d167
2013 2080 2080 2080 ? -1 Ss 0 0:17 \_ haproxy -W -db -f /usr/local/etc/haproxy/haproxy.cfg
2080 2133 2080 2080 ? -1 Sl 0 48:48 \_ haproxy -W -db -f /usr/local/etc/haproxy/haproxy.c
Kata-runtime
Kata-runtime:一種基于 虛擬化
的安全隔離的 OCI runtime spec
的實(shí)現(xiàn)。
- 虛擬化隔離:每個(gè)pod都運(yùn)行在一個(gè)獨(dú)立的
虛擬機(jī)
中,提供虛擬化接口對(duì)接不同的虛擬化實(shí)現(xiàn),包括qemu、cloud hypervisor、firecracker 等等 - 輕量化:為了達(dá)到和容器近似的使用體驗(yàn),需要對(duì)各組件進(jìn)行裁剪,達(dá)到輕量化和啟動(dòng)加速的目的,對(duì)于hypervisor,去除通用虛擬化的各種不必要的設(shè)備、總線等。對(duì)于guestkernel,也裁剪了大量不需要的驅(qū)動(dòng)和文件系統(tǒng)模塊。而運(yùn)行在虛擬機(jī)中的1號(hào)進(jìn)程(一般為kata-agent),資源占用可小于1MB。
- 主機(jī)資源訪問(wèn):通過(guò)virtio、vfio等方式訪問(wèn)主機(jī)資源,如virtio-blk(塊設(shè)備)、virtio-fs(文件)、virtio-net(網(wǎng)絡(luò))、vfio(物理設(shè)備)、vhost-user(用戶態(tài)網(wǎng)絡(luò)或存儲(chǔ))
gVisor
gVisor
:是Google開(kāi)源的一款安全容器運(yùn)行時(shí),它使用了系統(tǒng)調(diào)用攔截(System call filtering)
這一技術(shù)來(lái)實(shí)現(xiàn)容器安全隔離。
- gVisor通過(guò)內(nèi)核模塊注入方式,在用戶空間和內(nèi)核空間之間插入一個(gè)中間層。
- 這個(gè)中間層對(duì)所有從容器發(fā)起的系統(tǒng)調(diào)用請(qǐng)求進(jìn)行攔截和filtering。
- 根據(jù)預(yù)先定義的安全策略,選擇性通過(guò)或拒絕這些系統(tǒng)調(diào)用請(qǐng)求,限制容器對(duì)內(nèi)核資源的訪問(wèn)。
通過(guò)這種方式:
- gVisor無(wú)需真正
virtualize
內(nèi)核功能,性能開(kāi)銷(xiāo)小。 - 但能實(shí)現(xiàn)豐富的安全隔離,如文件系統(tǒng)讀寫(xiě)限制、網(wǎng)絡(luò)隔離等。
所以總體來(lái)說(shuō),gVisor采用輕量級(jí)的系統(tǒng)調(diào)用過(guò)濾技術(shù),在不影響性能的情況下,有效地隔離和限制容器對(duì)系統(tǒng)資源的訪問(wèn),從而有效提升容器安全性。
- 虛擬內(nèi)核:設(shè)置進(jìn)程的4種模式,HRO、HR3、GRO、GR3,通過(guò)攔截系統(tǒng)調(diào)用,實(shí)現(xiàn)了一個(gè)虛擬內(nèi)核,用戶進(jìn)程與host kernel不直接交互
- 攔截系統(tǒng)調(diào)用的方式:ptrace、kvm
- 優(yōu)點(diǎn):額外內(nèi)存消耗小,容器啟動(dòng)速度快
- 缺點(diǎn):系統(tǒng)調(diào)用慢,導(dǎo)致I0、網(wǎng)絡(luò)等性能差,由于是模擬內(nèi)核,有POSIX兼容性問(wèn)題
知道了CRI,OCI,可能會(huì)有這樣一個(gè)疑問(wèn),容器運(yùn)行時(shí)(runtime)是如何和 Pod 關(guān)聯(lián)起來(lái)的? 這里就要講到 RuntimeClass
RuntimeClass
RuntimeClass
是 Kubernetes 中的一個(gè)對(duì)象類型
,用于定義集群中的特定運(yùn)行時(shí)``。RuntimeClass
允許您通過(guò)指定 overhead(開(kāi)銷(xiāo))
和 nodeSelector(節(jié)點(diǎn)選擇器)
來(lái)自定義特定運(yùn)行時(shí)的資源和調(diào)度行為
。
RuntimeClass
的主要作用是將容器運(yùn)行時(shí)與 Pod 關(guān)聯(lián)起來(lái)。它定義了一組屬性,包括運(yùn)行時(shí)名稱、調(diào)度器名稱、節(jié)點(diǎn)選擇器和資源限制。通過(guò)將 Pod
的 RuntimeClassName
字段設(shè)置為特定的 RuntimeClass
名稱,可以指定該 Pod 使用特定的容器運(yùn)行時(shí)。
使用 RuntimeClass,可以針對(duì)不同的運(yùn)行時(shí)場(chǎng)景進(jìn)行資源和調(diào)度的優(yōu)化。例如,您可以定義一個(gè) RuntimeClass,針對(duì) CPU 密集型任務(wù)使用資源更多的容器運(yùn)行時(shí),并通過(guò)節(jié)點(diǎn)選擇器將該 RuntimeClass 的 Pod 調(diào)度到具備較高 CPU 資源的節(jié)點(diǎn)上。
Runtime Plugin
:containerd中的runtime插件配置,定義了runtime名稱、二進(jìn)制路徑、傳遞的annotation、特權(quán)容器模式等等。
關(guān)于容器引擎和運(yùn)行時(shí)機(jī)制原理認(rèn)知就和小伙伴們分享到這里
博文部分內(nèi)容參考
文中涉及參考鏈接內(nèi)容版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)告知 ??
https://connect.huaweicloud.com/courses/learn/learning/sp:cloudEdu_?courseNo=course-v1:HuaweiX+CBUCNXI041+Self-paced&courseType=1&source=1文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-698639.html
? 2018-2023 liruilonger@gmail.com, All rights reserved. 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-698639.html
到了這里,關(guān)于K8s:一文認(rèn)知 CRI,OCI,容器運(yùn)行時(shí),Pod 之間的關(guān)系的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!