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