Kubernetes 如何選擇合適的容器運行時

前 言

作為后臺支撐,Kubernetes優(yōu)勢明顯蝇完,具有自動化部署湃密、服務伸縮、故障自我修復四敞、負載均衡等特性泛源。咪付的藍牙過閘系統(tǒng)和全態(tài)識別AI系統(tǒng)的后臺支撐采用了Kubernetes,經(jīng)過線上的長期運行忿危,其狀態(tài)良好運行平穩(wěn)达箍。

藍牙過閘系統(tǒng)和全態(tài)識別AI系統(tǒng)有著不同的數(shù)據(jù)特性,對數(shù)據(jù)的安全要求及運行效率也各不一樣铺厨,因此如何選擇容器的運行時成為了一個重點考慮的因素缎玫。

本文將介紹Kubernetes支持哪些容器運行時以及如何選擇合適的容器運行時。

這篇文章包含以下內(nèi)容:

介紹CRI接口規(guī)范內(nèi)容

介紹不同OCI項目的技術(shù)特點

CRI是如何銜接Kubelet和OCI層及當前CRI格局

Kubernetes如何支持多種容器運行時

如何選擇合適的容器運行時

01

CRI的由來

CRI(Container Runtime Interface)是Kubernetes提出的容器運行時接口規(guī)范解滓。

image

在Kubernetes體系中赃磨,是由Kubelet組件負責與容器運行時交互的。Kubelet調(diào)用容器運行時的流程如上圖所示洼裤。CRI shim是實現(xiàn)CRI接口的gRPC server服務邻辉,負責連接Kubelet和Container runtime,Container runtime是容器運行時工具腮鞍,它為用戶進程隔離出一個獨立的運行環(huán)境值骇;具體的流程是Kubelet調(diào)用CRI shim接口,CRI shim響應請求移国,然后調(diào)用底層的Container runtime工具運行容器吱瘩。Kubelet、CRI shim和Container runtime都部署在一個Kubernetes worker節(jié)點上迹缀,前兩者是以獨立的守護進程的方式啟動的使碾,而Container runtime不是守護進程,它通常是一個命令行工具祝懂。

Kubernetes在v1.5版本之前是沒有CRI接口的票摇,那時Kubelet源碼內(nèi)部只集成了兩個容器運行時(Docker和rkt)的相關(guān)代碼。這兩種容器運行時并不能滿足所有用戶的使用需求嫂易,在某些業(yè)務場景兄朋,用戶對容器的安全隔離性有著更高的需求掐禁,用戶希望Kubernetes能支持更多種類的容器運行時怜械。因此颅和,Kubernetes在1.5版本推出了CRI接口,各個容器運行時只要實現(xiàn)了CRI接口規(guī)范缕允,就可以接入到Kubernetes平臺為用戶提供容器服務峡扩。

CRI接口帶來的好處,首先它很好的將Kubernetes和容器運行時解耦障本,容器運行時的每次更新迭代教届,都不必對Kubelet工程源碼進行編譯發(fā)布;其次解放了容器運行時更新迭代的步伐驾霜,也能保證Kubernetes的代碼質(zhì)量和平臺的穩(wěn)定案训。

02

OCI是什么

OCI規(guī)范(Open Container Initiative 開放容器標準),該規(guī)范包含兩部分內(nèi)容:容器運行時標準(runtime spec)粪糙、容器鏡像標準(image spec)强霎。其具體內(nèi)容的定義如下圖:

image

容器運行時標準

runtime spec包含配置文件、運行環(huán)境蓉冈、生命周期三部分內(nèi)容城舞。

- 配置文件 -

config.json,包含容器的配置信息(mounts寞酿、process家夺、hostname、hooks等)伐弹。

- 運行環(huán)境 -

定義運行環(huán)境拉馋,是為了確保應用程序在多個運行時之間,能具有一致的環(huán)境 惨好。

- 容器生命周期 -

定義了運行時的相關(guān)指令及其行為:state椅邓、create、start昧狮、kill景馁、delete、prestart hooks逗鸣、poststart hooks合住、poststop hooks。

容器鏡像標準

通常我們根據(jù)Dockerfile定義的內(nèi)容制作鏡像撒璧,目的是構(gòu)建一個符合OCI標準的鏡像文件透葛,那么OCI標準鏡像文件的內(nèi)容都有哪些呢?在OCI規(guī)范里的image spec對容器鏡像格式做了定義卿樱,它主要包括以下幾塊內(nèi)容:

- 文件系統(tǒng) -

描述了如何以layer的方式疊加成一個完整的文件系統(tǒng)僚害,以及如何用layer去表示對文件作出的改動(增加、刪除繁调、修改)萨蚕。

- config文件 -

保存了文件系統(tǒng)的層級信息(每個層級的 hash 值靶草、歷史信息),以及容器運行時需要的一些信息(比如環(huán)境變量岳遥、工作目錄奕翔、命令參數(shù)、mount 列表等)浩蓉。

- manifest文件 -

記錄鏡像元信息派继,包括Image Config和Image Layers。

- index文件 -

可選的文件捻艳,指向不同平臺的 manifest 文件驾窟,相當于整個鏡像的入口,從這個文件可以獲取整個鏡像依賴的所有文件信息认轨。

OCI項目

下表是兼容OCI規(guī)范的容器運行時項目:

image

容器運行時對比

按照底層容器運行環(huán)境依托的技術(shù)分類纫普,我們將容器運行時分為以下三類:

OSContainerRuntime(基于進程隔離技術(shù))

HyperRuntime(基于Hypervisor技術(shù))

UnikernelRuntime(基于unikernel)

通過下圖對比它們之間的區(qū)別:

image

OSContainerRuntime下的Linux Container共享Linux內(nèi)核,使用namespace好渠、cgroup等技術(shù)隔離進程資源昨稼。namespace只包含了六項隔離(UTS、IPC拳锚、PID假栓、Network、Mount霍掺、User)匾荆,并非所有Linux資源都可以通過這些機制控制,比如時間和Keyring杆烁,另外牙丽,容器內(nèi)的應用程序和常規(guī)應用程序使用相同的方式訪問系統(tǒng)資源,直接對主機內(nèi)核進行系統(tǒng)調(diào)用兔魂。因此即使有了很多限制烤芦,內(nèi)核仍然向惡意程序暴露過多的攻擊面。

HyperRuntime下的VM Container容器各自擁有獨立Linux內(nèi)核析校,資源隔離比Linux Container更徹底构罗。但并不是說使用VM容器用戶就可以高枕無憂,只是VM容器的攻擊面比Linux容器小了很多智玻,黑客要逃逸到宿主機就只剩下Hypervisor這個入口遂唧,所以說沒有絕對的安全,相對來說VM容器更安全吊奢。

另一方面盖彭,VM容器的性能比不上Linux容器,因為Hypervisor這一層帶來的性能損耗,在Linux容器這邊是不存在的召边。

UnikernelRuntime下的容器同VM Container一樣有著安全級別很高的運行環(huán)境铺呵,同樣是使用Hypervisor技術(shù)進行容器隔離。

簡單來說Unikernel是一個運行在Hypervisor之上的libOS系統(tǒng)掌实,而libOS是由應用程序和libraries一起構(gòu)建出的操作系統(tǒng)。

unikernel的特點如下:

性能好邦马,應用程序和內(nèi)核在同一地址空間贱鼻,消除了用戶態(tài)和內(nèi)核態(tài)轉(zhuǎn)換以及數(shù)據(jù)復制帶來的開銷。

更精簡的內(nèi)核滋将,去掉了多余的驅(qū)動邻悬、依賴包、服務等随闽,最終打包鏡像更小父丰,啟動速度更快。

完全不可調(diào)試掘宪,在生產(chǎn)環(huán)境中如果遇到問題蛾扇,只能依賴于收集到的日志進行排查,要不就是重啟容器魏滚,原先熟悉的Linux排查方法和工具完全派不上用場镀首。

03

Kubelet CRI架構(gòu)

Kubernetes在引入CRI之后,Kubelet的架構(gòu)如下圖所示:

image

每一個容器引擎只需要自己實現(xiàn)一個CRI shim鼠次,對CRI請求進行處理更哄,就可以接入Kubelet當中去。

我們所說的容器運行時腥寇,準確來說包含兩部分成翩,一部分是上層容器運行時CRI shim(即容器運行時管理程序,如Containerd赦役、CRI-O)麻敌,另一部分是下層容器運行時Container runtime(即容器運行時命令工具,如runc)掂摔。

04

CRI接口定義

CRI接口分為兩部分庸论,一個是容器運行時服務RuntimeService,負責管理pod和容器的生命周期棒呛;一個是鏡像服務ImageService聂示,負責管理鏡像的生命周期。

image
image

05

當前CRI格局

目前實現(xiàn)了CRI的主流項目有:docker簇秒、containerd鱼喉、CRI-O、Frakti、pouch扛禽,它們銜接Kubelet與運行時方式對比如下:

image

PS:由于rkt容器引擎目前未能完全兼容OCI規(guī)范锋边,所以圖中未將其包含進來。

- Docker -

Docker容器引擎安裝后包含有這些組件:dockerd编曼、Containerd豆巨、runc。

dockershim是內(nèi)置在Kubelet的CRI gRPC server服務掐场,它接收CRI請求后欢伏,通過unix本地套接字調(diào)用dockerd的API接口远豺,再由dockerd請求下游的運行時組件Containerd和runc蜗顽。調(diào)用的鏈路:dockershim => dockerd => Containerd => runc验懊。

在當前CRI的請求鏈路上,dockerd只是簡單接收CRI請求嚷堡,在轉(zhuǎn)換之后調(diào)用Containerd蝗罗,dockerd還集成有其他功能,如network蝌戒、swarm串塑、volume等在Kubernetes平臺下沒有用武之地,可以說在CRI場景下docker顯得笨重北苟。

- Containerd -

Containerd項目是從早期的docker源碼中提煉出來的拟赊,它使用CRI插件來向kubelet提供CRI接口服務。

CRI插件是一個獨立的項目粹淋,在Containerd編譯時吸祟,如果go build命令沒有顯示設(shè)置參數(shù)-tags=no_cri,那么CRI插件將自動編譯集成到Containerd的二進制文件中桃移,然后在配置文件/etc/containerd/config.toml中聲明啟用CRI插件屋匕,就可以在Containerd中啟動CRI shim服務了。

Containerd能支持多運行時借杰,目前它內(nèi)置了runc運行時过吻,其他運行時如果要接入Containerd,則需要實現(xiàn)Containerd shim v2 gRPC接口蔗衡,這樣Containerd就可以通過shim v2調(diào)用其他運行時纤虽。他們的調(diào)用關(guān)系如下:Containerd --> shim v2 --> runtimes

- CRI-O -

CRI-O完整實現(xiàn)CRI接口功能,并且嚴格兼容OCI標準绞惦,CRI-O比Containerd更專注逼纸,它只服務于Kubernetes(而Containerd除支持Kubernetes CRI,還可用于Docker Swarm)济蝉,從官網(wǎng)上我們可以了解到CRI-O項目的功能邊界:

  • 支持多種image格式

  • 支持多種image下載方式

  • 容器鏡像管理

  • 容器生命周期管理

  • 提供CRI要求的監(jiān)控杰刽、日志功能

  • 提供CRI要求的資源隔離功能

CRI-O通過命令行調(diào)用默認運行時runc菠发,所以runc二進制文件必須部署在目錄/usr/bin/runc。CRI-O和Containerd調(diào)用runtime的方式不同贺嫂,前者是通過linux命令調(diào)用滓鸠,后者是通過gRPC服務調(diào)用,所以只要符合OCI規(guī)范的runtime第喳,都能直接接入CRI-O提供運行時服務糜俗,而除runc外的其他運行時要接入Containerd,只能走shim v2接口曲饱,因此我們看到像kata-runtime這樣的運行時項目就是通過shim v2接口來適配Containerd的悠抹。

Frakti

Frakti是基于Hypervisor虛擬機管理程序的容器運行時,它相比其他的容器運行時具有如下這些功能特性:

image

- PouchContainer -

PouchContainer是阿里開源的容器引擎渔工,它內(nèi)部有一個CRI協(xié)議層和cri-manager模塊锌钮,用于實現(xiàn)CRI shim功能桥温。它的技術(shù)優(yōu)勢包括:

1. 強隔離引矩,包括的安全特性:基于Hypervisor的容器技術(shù)、lxcfs侵浸、目錄磁盤配額旺韭、補丁Linux內(nèi)核等。

2. 基于P2P鏡像分發(fā)掏觉,利用P2P技術(shù)在各節(jié)點間互傳鏡像区端,減小鏡像倉庫的下載壓力,加快鏡像下載速度澳腹。

3. 富容器技術(shù)织盼,PouchContainer的容器中除了運行業(yè)務應用本身之外,還有運維套件酱塔、系統(tǒng)服務沥邻、systemd進程管家等。

06

CRI命令工具

cri-tools是由kubernetes-sigs 開發(fā)維護的CRI命令工具(后簡稱crictl)羊娃,它是為了在Kubernetes node節(jié)點上管理鏡像唐全、管理pod/container、與容器進行交互而設(shè)計的蕊玷,crictl調(diào)用CRI接口獲取相關(guān)信息邮利、或者通過CRI的exec接口與容器交互。

crictl并不是docker cli的完全繼任者垃帅,它僅提供了在Kubernetes node節(jié)點上常用的一些運維功能延届,具備一個較小的功能子集,而docker cli的命令更強大贸诚,事實上很多docker命令在生產(chǎn)環(huán)境并沒有必要使用祷愉,所以crictl相對來說更安全窗宦,它避免運維人員在生產(chǎn)節(jié)點非法使用docker cli(rename、rm二鳄、rmi等子命令)造成一些人為的故障赴涵。所有實現(xiàn)了CRI接口的容器運行時,都可以通過crictl工具對其進行操作订讼。

07

Kubernetes支持多運行時

為什么要支持多運行時呢髓窜?舉個例子,有一個開放的云平臺向外部用戶提供容器服務欺殿,平臺上運行有兩種容器寄纵,一種是云平臺管理用的容器(可信的),一種是用戶部署的業(yè)務容器(不可信)脖苏。在這種場景下程拭,我們希望使用runc運行可信容器(弱隔離但性能好),用runv運行不可信容器(強隔離安全性好)棍潘。面對這種需求恃鞋,Kubernetes也給出了解決方案(使用API對象RuntimeClass支持多運行時)。

多運行時工作原理

image

Kubelet從apiserver接收到的Pod Spec亦歉,如果Pod Spec中使用runtimeClassName指定了容器運行時恤浪,則在調(diào)用CRI接口的RunPodSandbox()函數(shù)時,會將runtimeClassName信息傳遞給CRI shim肴楷,然后CRI shim根據(jù)runtimeClassName去調(diào)用對應的容器運行時水由,為Pod創(chuàng)建一個隔離的運行環(huán)境。

RuntimeClass配置

Kubernetes在v1.12中增加了RuntimeClass這個新API對象來支持多運行時(目的就是在一個woker節(jié)點上運行多種運行時)赛蔫。

在Kubernetes中啟用RuntimeClass時需要注意砂客,盡量保持當前Kubernetes集群中的節(jié)點在容器運行時方面的配置都是同構(gòu)的,如果是異構(gòu)的呵恢,那么需要借助node Affinity等功能來調(diào)度Pod到已部署有匹配容器運行時的節(jié)點鞠值。

接下來只需要三步配置就可以為pod指定運行時:

1. 在Kubernetes worker節(jié)點配置CRI shim;

2. 創(chuàng)建RuntimeClass資源對象瑰剃;

3. 在pod中指定RuntimeClass齿诉。

- 配置CRI shim -

例如CRI-O運行時的配置,需要在文件/etc/crio/crio.conf定義runtime的handler_name:

[crio.runtime.runtimes.${HANDLER_NAME}]
  runtime_path = "${PATH_TO_BINARY}"

- 創(chuàng)建RuntimeClass -

RuntimeClass yaml定義如下:

apiVersion: node.k8s.io/v1beta1  # RuntimeClass is defined in the node.k8s.io API group
kind: RuntimeClass
metadata:
  name: myclass  # The name the RuntimeClass will be referenced by
  # RuntimeClass is a non-namespaced resource
handler: myconfiguration  # The name of the corresponding CRI configuration

- 配置pod -

在pod yaml中指定RuntimeClassName:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  runtimeClassName: myclass
  # ...

08

如何選擇合適的容器運行時

在生產(chǎn)環(huán)境中晌姚,我們并不需要docker的鏡像打包粤剧、容器網(wǎng)絡(luò)、文件掛載挥唠、swarm等這些能力抵恋,只需要部署Containerd + runc就可以在node節(jié)點上運行pod。因此在生產(chǎn)環(huán)境中我們可以不安裝docker宝磨,而是安裝CRI shim組件和運行時工具來運行pod弧关。在多個CRI shim和OCI工具之間盅安,我們該如何選擇呢?

首先對比Containerd和CRI-O調(diào)用runc的方式世囊,runc代碼內(nèi)置在Containerd內(nèi)部别瞭,通過函數(shù)調(diào)用;CRI-O是通過linux命令方式調(diào)用runc二進制文件株憾,顯然前者屬于進程內(nèi)的函數(shù)調(diào)用蝙寨,在性能上Containerd更具優(yōu)勢。其次對比runc和runv嗤瞎,這是兩種完全不同的容器技術(shù)墙歪,runc創(chuàng)建的容器進程直接運行在宿主機內(nèi)核上,而runv是運行在由Hypervisor虛擬出來的虛擬機上贝奇,后者占用的資源更多虹菲、啟動速度慢,而且runv容器在調(diào)用底層硬件時(如CPU)掉瞳,中間多了一層虛擬硬件層毕源,計算效率上不如runc容器。

image

因此建議結(jié)合自身業(yè)務特點菠赚、以及使用場景選擇合適的容器運行時脑豹。在對用戶的隔離沒有很高訴求的情況下郑藏,可以優(yōu)先考慮使用性能更好更輕量的Containerd + runc衡查;在隔離性要求較高的業(yè)務場景下,推薦使用基于Hypervisor 的虛擬化容器運行時Frakti + runv必盖。

轉(zhuǎn)自 https://toutiao.io/posts/eod7r9/preview

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拌牲,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子歌粥,更是在濱河造成了極大的恐慌塌忽,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件失驶,死亡現(xiàn)場離奇詭異土居,居然都是意外死亡,警方通過查閱死者的電腦和手機嬉探,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門擦耀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人涩堤,你說我怎么就攤上這事眷蜓。” “怎么了胎围?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵吁系,是天一觀的道長德召。 經(jīng)常有香客問我,道長汽纤,這世上最難降的妖魔是什么上岗? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮蕴坪,結(jié)果婚禮上液茎,老公的妹妹穿的比我還像新娘。我一直安慰自己辞嗡,他們只是感情好捆等,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著续室,像睡著了一般栋烤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挺狰,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天明郭,我揣著相機與錄音,去河邊找鬼丰泊。 笑死薯定,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的瞳购。 我是一名探鬼主播话侄,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼学赛!你這毒婦竟也來了年堆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤盏浇,失蹤者是張志新(化名)和其女友劉穎变丧,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體绢掰,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡痒蓬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了滴劲。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片攻晒。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖哑芹,靈堂內(nèi)的尸體忽然破棺而出炎辨,到底是詐尸還是另有隱情,我是刑警寧澤聪姿,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布碴萧,位于F島的核電站乙嘀,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏破喻。R本人自食惡果不足惜虎谢,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望曹质。 院中可真熱鬧婴噩,春花似錦、人聲如沸羽德。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宅静。三九已至章蚣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間姨夹,已是汗流浹背纤垂。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留磷账,地道東北人峭沦。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像逃糟,于是被迫代替她去往敵國和親吼鱼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348