RunC 简介
RunC 是什么?
RunC 是一個輕量級的工具,它是用來運行容器的,只用來做這一件事,并且這一件事要做好。我們可以認(rèn)為它就是個命令行小工具,可以不用通過 docker 引擎,直接運行容器。事實上,runC 是標(biāo)準(zhǔn)化的產(chǎn)物,它根據(jù) OCI 標(biāo)準(zhǔn)來創(chuàng)建和運行容器。而 OCI(Open Container Initiative)組織,旨在圍繞容器格式和運行時制定一個開放的工業(yè)化標(biāo)準(zhǔn)。
安裝 runC
RunC 是用 golang 創(chuàng)建的項目,因此編譯它之前需要在本地安裝 golang 的開發(fā)環(huán)境。Golang 的安裝請參考《打造 golang 開發(fā)環(huán)境》一文,這里不再贅述。
安裝 libseccomp-dev
RunC 默認(rèn)的編譯配置是支持 seccomp 的,所以我們需要先安裝 libseccomp-dev:
$ sudo apt install libseccomp-devseccomp 的全稱為 secure computing mode,即安全計算模型,這是 Linux 內(nèi)核提供的功能。我們可以通過它來限制容器中進程的行為。關(guān)于 seccomp 的更多內(nèi)容,請參考 Seccomp security profiles for Docker。
獲取 runC 的代碼
先創(chuàng)建 $GOPATH/src/github.com 目錄:
$ mkdir -p $HOME/go/src/github.com通過 go get 命令就可以從 github 上下載到 runC 的代碼,但是要保證事先安裝了 git:
$ go get github.com/opencontainers/runc然后進入 $HOME/go/src/github.com/opencontainers/runc 目錄,并 checkout 最新的穩(wěn)定狀態(tài)的代碼 tag v1.0.0-rc5:
$ cd $HOME/go/src/github.com/opencontainers/runc $ git checkout v1.0.0-rc5查看代碼當(dāng)前的狀態(tài):
$ git status
v1.0.0-rc5 是當(dāng)前最新的版本。
編譯并安裝
$ make $ sudo make install
如上圖所示,runC 被安裝在了 /usr/local/sbin/runc 目錄。
可以通過 -v 選項查看一下版本號:
至此,runC 就算是安裝成功了。
準(zhǔn)備 OCI bundle
RunC 是運行容器的運行時,它負(fù)責(zé)利用符合標(biāo)準(zhǔn)的文件等資源運行容器,但是它不包含 docker 那樣的鏡像管理功能。所以要用 runC 運行容器,我們先得準(zhǔn)備好容器的文件系統(tǒng)。所謂的 OCI bundle 就是指容器的文件系統(tǒng)和一個 config.json 文件。有了容器的文件系統(tǒng)后我們可以通過 runc spec 命令來生成 config.json 文件。使用 docker 可輕松的生成容器的文件系統(tǒng),因為 runC 本來就是 docker 貢獻給社區(qū)的嘛!
下面我們準(zhǔn)備一個運行 busybox 容器所需的文件系統(tǒng):
現(xiàn)在 rootfs 目錄下就是 busybox 鏡像的文件系統(tǒng),然后生成 config.json 文件:
$ runc spec
如果直接使用生成的 config.json,接下來的演示不會太流暢,所以簡單起見,我們稍微修改一下剛剛生成的 config.json 文件。就是把 "terminal": true 改為 false,把 "args": ["sh"] 改為 "args": ["sleep", "30"]:
理解容器狀態(tài)轉(zhuǎn)移
在運行 busybox 容器前讓我們先來看看 OCI 都定義了哪幾種容器狀態(tài),以及這些狀態(tài)是如何轉(zhuǎn)移的。先看容器的狀態(tài):
- creating:使用 create 命令創(chuàng)建容器,這個過程稱為創(chuàng)建中。
- created:容器已經(jīng)創(chuàng)建出來,但是還沒有運行,表示鏡像文件和配置沒有錯誤,容器能夠在當(dāng)前平臺上運行。
- running:容器里面的進程處于運行狀態(tài),正在執(zhí)行用戶設(shè)定的任務(wù)。
- stopped:容器運行完成,或者運行出錯,或者 stop 命令之后,容器處于暫停狀態(tài)。這個狀態(tài),容器還有很多信息保存在平臺中,并沒有完全被刪除。
- paused:暫停容器中的所有進程,可以使用 resume 命令恢復(fù)這些進程的執(zhí)行。
下圖則是對容器不同狀態(tài)間轉(zhuǎn)移的一個粗略描述:
RunC 命令
要想了解 runC 都能干什么,最好是通過它提供的命令來操作容器。下面是筆者整理的 runC 命令的主要使用場景。
查看幫助
$ runc -h查看子命令的幫助
$ runc help subcommand使用 create 命令創(chuàng)建容器
進入到 /tmp/mycontainer 目錄中:
然后創(chuàng)建名為 mybusybox 的容器:
$ sudo runc create mybusybox使用 list 命令查看當(dāng)前存在的容器
$ sudo runc list
使用 state 命令查看容器的狀態(tài)
$ sudo runc state mybusybox
注意圖中的 "status": "created",當(dāng)通過 create 成功創(chuàng)建了容器后,容器的狀態(tài)就是 "created"。
使用 ps 命令看看容器內(nèi)運行的進程
$ sudo runc ps mybusybox
此時 mybusybox 容器內(nèi)有一個名為 init 的進程在運行。
使用 start 命令執(zhí)行容器中定義的任務(wù)
$ sudo runc start使用 start 命令啟動容器后,讓我們再用 ps 命令看看容器內(nèi)運行了什么進程:
此時我們在 config.json 中定義的 sleep 進程在運行。再用 state 命令看看容器此時的狀態(tài),此時已經(jīng)變成了 running!
使用 exec 命令在容器中執(zhí)行命令
通過 exec 命令我們可以在處于 created 狀態(tài)和 running 狀態(tài)的容器中執(zhí)行命令:
當(dāng)容器中的用戶任務(wù)結(jié)束后,容器會變成 stopped 狀態(tài),這時就不能再通過 exec 執(zhí)行其它的命令了。
使用 delete 命令刪除容器
我們可以通過 delete 命令刪除容器,當(dāng)然,一般情況下是刪除 stopped 狀態(tài)的容器:
使用 run 命令創(chuàng)建并運行容器
就像 docker run 命令一樣,它會創(chuàng)建容器并運行容器中的命令:
當(dāng)容器中的命令退出后容器隨即被刪除。
使用 kill 命令停止容器中的任務(wù)
如果要停止一個容器中正在運行的任務(wù),可以使用 kill 命令:
默認(rèn)它會優(yōu)雅的結(jié)束容器中的進程,但是碰到特殊情況,你就得使用終極信號 9:
$ sudo runc kill mybusybox 9使用 pause 命令暫停容器中的所有進程
我們先啟動容器 mybusybox,然后用 pause 命令暫停它:
執(zhí)行 pause 命令后,容器的狀態(tài)由 running 變成了 paused。然后我們再通過 resume 命令恢復(fù)容器中進程的執(zhí)行:
$ sudo runc resume mybusybox
此時容器的狀態(tài)又恢復(fù)到了 running。
使用 events 命令獲取容器的資源使用情況
events 命令能夠向我們報告容器事件及其資源占用的統(tǒng)計信息:
rootless containers
前面我們運行的所有命令都是以 root 權(quán)限執(zhí)行的。能不能以普通用戶的權(quán)限運行容器呢?答案是可以的,并被稱為 rootless。要想以 rootless 的方式運行容器,需要我們在生成容器的配置文件時就為 spec 命令指定 rootless 參數(shù):
$ runc spec --rootless并且在運行容器時通過 --root 參數(shù)指定一個存放容器狀態(tài)的路徑:
$ runc --root /tmp/runc run mybusybox容器的熱遷移操作
RunC 支持容器的熱遷移操作,所謂熱遷移就是將一個容器進行 checkpoint 操作,并獲得一系列文件,使用這一系列文件可以在本機或者其他主機上進行容器的 restore 工作。這也是 checkpoint? 和 restore 兩個命令存在的原因。熱遷移屬于比較復(fù)雜的操作,目前 runC 使用了 CRIU 作為熱遷移的工具。RunC 主要是調(diào)用 CRIU(Checkpoint and Restore in Userspace)來完成熱遷移操作。CIRU 負(fù)責(zé)凍結(jié)進程,并將作為一系列文件存儲在硬盤上。并負(fù)責(zé)使用這些文件還原這個被凍結(jié)的進程。
總結(jié)
RunC 作為標(biāo)準(zhǔn)化容器運行時的一個實現(xiàn)目前已經(jīng)被 docker 內(nèi)置為默認(rèn)的容器運行時。相信隨著 runC 自身的成熟和完善會有越來越多的大廠把 runC 作為默認(rèn)的容器運行時。
參考:
Runc Github
OCI和runc容器標(biāo)準(zhǔn)化和docker
OCI標(biāo)準(zhǔn)和runC原理解讀
轉(zhuǎn)載于:https://www.cnblogs.com/sparkdev/p/9032209.html
總結(jié)
- 上一篇: 剑指offer解题思路锦集11-20题
- 下一篇: 树莓派3风扇安装方法