摘要:容器的注釋,相當(dāng)于容器標(biāo)簽,來自于容器的配置文件,格式。執(zhí)行命令啟動(dòng)容器執(zhí)行中配置的鉤子執(zhí)行中指定的程序,這時(shí)容器狀態(tài)變成了執(zhí)行鉤子。容器由于某些原因退出,比如容器中的第一個(gè)進(jìn)程主動(dòng)退出,掛掉或者被掉等。
我們都知道runc是容器runtime的一個(gè)實(shí)現(xiàn),那到底什么是runtime?包含了哪些內(nèi)容?
容器的runtime和image一樣,也有標(biāo)準(zhǔn),也由OCI (Open Containers Initiative)負(fù)責(zé)維護(hù),地址為Runtime Specification,了解runtime標(biāo)準(zhǔn)有利于我們更好的理解docker和runc的關(guān)系,本文將對(duì)該標(biāo)準(zhǔn)做一個(gè)簡(jiǎn)單的解釋。
規(guī)范內(nèi)容在Linux平臺(tái)上,跟runtime有關(guān)的規(guī)范主要有四個(gè),分別是Runtime and Lifecycle (runtime.md)、Container Configuration file (config.md)、Linux Container Configuration (config-linux.md)和Linux Runtime (runtime-linux.md) .
除了這四個(gè)之外,還有一個(gè)Filesystem Bundle (bundle.md)。
下面分別介紹這些規(guī)范。
Filesystem Bundle在上一篇中,已經(jīng)用過bundle了,hello-world的bundle看起來是這個(gè)樣子的:
dev@debian:~/images$ tree hello-world-bundle hello-world-bundle ├── config.json └── rootfs └── hello 1 directory, 2 files
bundle中包含了運(yùn)行容器所需要的所有信息,有了這個(gè)bundle后,符合runtime標(biāo)準(zhǔn)的程序(比如runc)就可以根據(jù)bundle啟動(dòng)容器了。
bundle包含一個(gè)config.json文件和容器的根文件系統(tǒng)目錄,config.json就是后面要介紹的Container Configuration file,標(biāo)準(zhǔn)要求該配置文件必須叫這個(gè)名字,不過對(duì)容器的根文件系統(tǒng)目錄沒有要求,只要在config.json里面將路徑配置正確就可以了,不過一般約定俗成都叫rootfs。
實(shí)際使用過程中,根文件系統(tǒng)目錄可能在其它的地方,只要config.json里面配置正確的路徑就可以了,但如果bundle需要打包和其它人分享的話,必須將根文件系統(tǒng)和config.json打包在一起,并且不包含外層的文件夾。
Container Configuration file該規(guī)范定義了上面介紹的config.json里面應(yīng)該包含哪些內(nèi)容,字段很多,這里不一一詳細(xì)介紹,只簡(jiǎn)單說明一下,完整的示例請(qǐng)參考這里:
ociVersion(必須):對(duì)應(yīng)的OCI標(biāo)準(zhǔn)版本
root(必須):根文件系統(tǒng)的位置
mounts:需要掛載哪些目錄到容器里面。如果是Linux平臺(tái),這里面必須要包含/proc、/sys,/dev/pts,/dev/shm這四個(gè)目錄
process:容器啟動(dòng)后執(zhí)行什么命令
hostname:容器的主機(jī)名,相關(guān)原理可參考UTS namespace (CLONE_NEWUTS)
platform(必須):平臺(tái)信息,如 amd64 + Linux
linux:Linux平臺(tái)的特殊配置,這里包含下面要介紹的Linux Container Configuration里面的內(nèi)容
hooks:配置容器運(yùn)行生命周期中會(huì)調(diào)用的hooks,包括prestart、poststart和poststop,容器的生命周期見后面Runtime and Lifecycle介紹。
annotations:容器的注釋,相當(dāng)于容器標(biāo)簽,key:value格式
Linux Container Configuration該規(guī)范是Linux平臺(tái)上對(duì)Container Configuration file的擴(kuò)展,這部分的內(nèi)容也包含在上面的config.json文件中。
namespaces: namespace相關(guān)的配置,相關(guān)原理可參考Namespace概述及這些namespace(UTS、IPC、mount、pid、network、user 1、user 2)。
uidMappings,gidMappings:配置主機(jī)和容器用戶/組之間的對(duì)應(yīng)關(guān)系,原理可參考user namespace
devices:設(shè)置哪些設(shè)備可以在容器內(nèi)被訪問到。除了這里指定的設(shè)備外,/dev/null、/dev/zero、/dev/full、/dev/random、/dev/urandom、/dev/tty、/dev/console(如果在process的配置里面啟動(dòng)terminal的話)和/dev/ptmx這些設(shè)備默認(rèn)就能在容器內(nèi)訪問到,即runtime的實(shí)現(xiàn)需要默認(rèn)將這些設(shè)備bind到容器內(nèi),dev/tty和/dev/ptmx的原理可以參考TTY/PTS概述
cgroupsPath:cgroup的路徑,可參考Cgroup概述
resources:Cgroup中具體子項(xiàng)的配置,包括device whitelist, memory, cpu, blockIO, hugepageLimits, network(net_cls cgroup和net_prio cgroup), pids
intelRdt:和Intel Resource Director Technology有關(guān)
sysctl:調(diào)整容器運(yùn)行時(shí)的kernel參數(shù),主要是一些網(wǎng)絡(luò)參數(shù),因?yàn)槊總€(gè)network namespace都有自己的協(xié)議棧,所以可以修改自己協(xié)議棧的參數(shù)而不影響別人
seccomp:和安全相關(guān)的配置,見Seccomp
rootfsPropagation:設(shè)置Propagation類型。可以參考Shared subtrees
maskedPaths:設(shè)置容器內(nèi)的哪些目錄對(duì)用戶不可見
readonlyPaths:設(shè)置容器內(nèi)的哪些目錄是只讀的
mountLabel:和Selinux有關(guān)。
Runtime and Lifecycle該規(guī)范主要定義了跟容器運(yùn)行時(shí)相關(guān)的三部分內(nèi)容,容器的狀態(tài)、容器相關(guān)的操作以及容器的生命周期。
容器的狀態(tài)當(dāng)查詢?nèi)萜鞯臓顟B(tài)時(shí),返回的狀態(tài)里面至少包含如下信息:
{ "ociVersion": "0.2.0", "id": "oci-container1", "status": "running", "pid": 4422, "bundle": "/containers/redis", "annotations": { "myKey": "myValue" } }
ociVersion (必須): 創(chuàng)建該容器時(shí)使用的OCI runtime的版本
id (必須): 容器ID,本機(jī)全局唯一
status (必須): 容器的運(yùn)行時(shí)狀態(tài),包含如下狀態(tài):
creating: 創(chuàng)建中 created: 創(chuàng)建完成 running: 運(yùn)行中 stopped: 運(yùn)行結(jié)束 實(shí)現(xiàn)runtime時(shí)可以包含更多的狀態(tài),但不能改變這幾個(gè)狀態(tài)的含義
pid (容器是running狀態(tài)時(shí)必須): 容器內(nèi)第一個(gè)進(jìn)程在系統(tǒng)初始pid namespace中的pid,即在容器外面看到的pid
bundle (REQUIRED): bundle所在位置的絕對(duì)路徑。bundle里面包含了容器的配置文件和根文件系統(tǒng)。
annotations: 容器的注釋,相當(dāng)于容器標(biāo)簽,來自于容器的配置文件,key:value格式。
容器相關(guān)的操作該部分定義了一個(gè)符合runtime標(biāo)準(zhǔn)的實(shí)現(xiàn)(如runc)至少需要實(shí)現(xiàn)下面這些命令:
state: 返回容器的狀態(tài),包含上面介紹的那些內(nèi)容.
create: 創(chuàng)建容器,這一步執(zhí)行完成后,容器創(chuàng)建完成,修改bundle中的config.json將不再對(duì)已創(chuàng)建的容器產(chǎn)生影響
start: 啟動(dòng)容器,執(zhí)行config.json中process部分指定的進(jìn)程
kill: 通過給容器發(fā)送信號(hào)來停止容器,信號(hào)的內(nèi)容由kill命令的參數(shù)指定
delete: 刪除容器,如果容器正在運(yùn)行中,則刪除失敗。刪除操作會(huì)刪除掉create操作時(shí)創(chuàng)建的所有內(nèi)容。
容器的生命周期這里以runc為例,說明容器的生命周期
執(zhí)行命令runc create創(chuàng)建容器,參數(shù)中指定bundle的位置以及容器的ID,容器的狀態(tài)變?yōu)閏reating
runc根據(jù)bundle中的config.json,準(zhǔn)備好容器運(yùn)行時(shí)需要的環(huán)境和資源,但不運(yùn)行process中指定的進(jìn)程,這步執(zhí)行完成之后,表示容器創(chuàng)建成功,修改config.json將不再對(duì)創(chuàng)建的容器產(chǎn)生影響,這時(shí)容器的狀態(tài)變成created。
執(zhí)行命令runc start啟動(dòng)容器
runc執(zhí)行config.json中配置的prestart鉤子
runc執(zhí)行config.json中process指定的程序,這時(shí)容器狀態(tài)變成了running
runc執(zhí)行poststart鉤子。
容器由于某些原因退出,比如容器中的第一個(gè)進(jìn)程主動(dòng)退出,掛掉或者被kill掉等。這時(shí)容器狀態(tài)變成了stoped
執(zhí)行命令runc delete刪除容器,這時(shí)runc就會(huì)刪除掉上面第2步所做的所有工作。
runc執(zhí)行poststop鉤子
Linux Runtime該規(guī)范是Linux平臺(tái)上對(duì)Runtime and Lifecycle的補(bǔ)充,目前該規(guī)范很簡(jiǎn)單,只要求容器運(yùn)行起來后,里面必須建立下面這些軟連接:
# ls -l /dev/fd /dev/std* lrwxrwxrwx 1 root root 13 May 4 12:32 /dev/fd -> /proc/self/fd lrwxrwxrwx 1 root root 15 May 4 12:32 /dev/stderr -> /proc/self/fd/2 lrwxrwxrwx 1 root root 15 May 4 12:32 /dev/stdin -> /proc/self/fd/0 lrwxrwxrwx 1 root root 15 May 4 12:32 /dev/stdout -> /proc/self/fd/1結(jié)束語(yǔ)
簡(jiǎn)單點(diǎn)說,docker負(fù)責(zé)準(zhǔn)備runtime的bundle,而runc負(fù)責(zé)運(yùn)行該bundle,并管理容器的整個(gè)生命周期。
但對(duì)于docker來說,并不是只要準(zhǔn)備好根文件系統(tǒng)和配置文件就可以了,比如對(duì)于網(wǎng)絡(luò),runtime沒有做任何要求,只要在config.json中指定network namespace就行了(不指定就新建一個(gè)),而至于這個(gè)network namespace里面有哪些東西則完全由docker負(fù)責(zé),docker需要保證新network namespace里面有合適的設(shè)備來和外界通信。
參考Open Container Initiative Runtime Specification
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/26923.html
摘要:包含的內(nèi)容本系列主要介紹三個(gè)上的項(xiàng)目由于只介紹核心的東西,所以不會(huì)包含下面這些項(xiàng)目使用語(yǔ)言開發(fā),將多個(gè)相關(guān)的容器配置在一起,從而可以同時(shí)創(chuàng)建啟動(dòng)停止和監(jiān)控它們。由于本人時(shí)間安排發(fā)生變化,本系列停止更新,后面不確定是否會(huì)繼續(xù),非常抱歉。 本人docker初學(xué)者,邊學(xué)習(xí)邊總結(jié),一方面加深自己的理解,另一方面希望對(duì)其他想深入了解docker的同學(xué)有所幫助。 由于本人缺乏實(shí)戰(zhàn)經(jīng)驗(yàn),錯(cuò)誤在所難免...
摘要:相關(guān)工具本文將用到三個(gè)工具,分別是和。根據(jù)生成的的就是運(yùn)行容器時(shí)需要的東西的集合。使用運(yùn)行該有了后,就可以用來運(yùn)行該容器了這里直接用的代替命令,如果你自己編譯了的,那么用命令也是一樣的。 上一篇介紹了image的格式,這里我們就來用一下hello-world這個(gè)image,看怎么輸出和docker run hello-world同樣的內(nèi)容。 相關(guān)工具 本文將用到三個(gè)工具,分別是skop...
摘要:進(jìn)程啟動(dòng)后,就會(huì)按照的標(biāo)準(zhǔn)準(zhǔn)備好相關(guān)運(yùn)行時(shí)環(huán)境,然后啟動(dòng)進(jìn)程。涉及到標(biāo)準(zhǔn)輸入輸出重定向,這里不細(xì)說這里是它們之間的交互流程流程對(duì)應(yīng)的文字描述如下客戶端發(fā)送創(chuàng)建容器請(qǐng)求給,收到請(qǐng)求后,發(fā)現(xiàn)本地沒有相應(yīng)的額,于是返回失敗。 在程序員的世界里,hello world是個(gè)很特殊的存在,當(dāng)我們接觸一門新的語(yǔ)言、新的開發(fā)庫(kù)或者框架時(shí),第一時(shí)間想了解的一般都是怎么實(shí)現(xiàn)一個(gè)hello world,然后...
摘要:首先來看看收到客戶端的啟動(dòng)容器請(qǐng)求后,做了些什么。待上面的文件都準(zhǔn)備好了之后,通過的方式給發(fā)送請(qǐng)求,通知啟動(dòng)容器。主要功能是啟動(dòng)并管理運(yùn)行時(shí)的所有。包含容器中進(jìn)程相關(guān)的一些屬性信息,后續(xù)在這個(gè)容器上執(zhí)行命令時(shí)會(huì)用到這個(gè)文件。 在上一篇介紹過了docker create之后,這篇來看看docker start是怎么根據(jù)create之后的結(jié)果運(yùn)行容器的。 啟動(dòng)容器 在這里我們先啟動(dòng)上一篇中...
閱讀 1404·2023-04-26 03:04
閱讀 2349·2019-08-30 15:44
閱讀 3731·2019-08-30 14:15
閱讀 3528·2019-08-27 10:56
閱讀 2737·2019-08-26 13:53
閱讀 2619·2019-08-26 13:26
閱讀 3081·2019-08-26 12:11
閱讀 3613·2019-08-23 18:21