runc 1.0-rc6 釋出之際

TaoBeier發表於2019-03-01

如果你在用 Docker 或者 Kubernetes 想必你對 容器執行時 這個概念應該不會太陌生。

Docker 中,當你使用 docker info 即可檢視當前所使用的 runtime。

➜  ~ docker info
...
Server Version: 18.06.1-ce
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
...
Swarm: inactive
Runtimes: nvidia runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 468a545b9edcd5932818eb9de8e72413e616e86e
runc version: 69663f0bd4b60df09991c08812a60108003fa340
init version: fec3683
Security Options:
 seccomp
  Profile: default
...
複製程式碼

同時,你還可以自己在 /etc/docker/daemon.json 中增加支援的 runtime , 以及在 docker run 的時候,通過 --runtime 引數配置所使用的 runtime 。

什麼是 runc

簡單來說,它是 OCI 標準的一種實現。 OCI 標準包含 執行時標準映象標準 兩個部分,而 OCI 這個組織則是由 Docker, CoreOS 和其他的一些公司共同發起建立的,致力於將容器執行時和格式標準化。

即:凡是遵守此標準的實現,無論是 Docker 還是 rkt 或者其他的執行時實現,均可以通過標準的映象啟動容器。

runc 則是在 OCI 成立後,Docker 將其容器執行時 libcontainer 貢獻出來後,並加以改造而成的。而 libcontainer 也是在 Docker 0.9 版本開始加入,我也是從這個版本開始使用它。

當然 libcontainer 出現的本意不僅是替換當時的 LXC 依賴,同時也希望能以此作為規範(讓其他的專案使用)最終,目標達成。

runc 如何使用

runc 的使用本不是本篇的重點,稍微帶過。

➜  ~ docker export -o debian.tar  `docker create debian`
➜  ~ ls
debian.tar
➜  ~ tar -C rootfs -xf debian.tar
➜  ~ ls
debian.tar   rootfs
➜  ~ tree -L 1 -a rootfs
rootfs
├── bin
├── boot
├── dev
├── .dockerenv
├── etc
├── home
├── lib
├── lib64
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin
├── srv
├── sys
├── tmp
├── usr
└── var

19 directories, 1 file

複製程式碼

通過以上操作,得到了執行一個容器所必須的 rootfs,當然,上面看到我是通過 docker 來獲得這個檔案的,但其實這只是為了方便罷了,docker 並不是必須的。

➜  ~ runc spec
➜  ~ ls
config.json  debian.tar  rootfs
複製程式碼

通過上面的操作,會得到一個基本的 config.json 的配置檔案,這裡麵包含著執行一個容器所需要的一些配置。其中會包含著一些例如:

"ociVersion": "1.0.1-dev"
複製程式碼

這種用於標識規範版本號的資訊。

接下來稍微對 config.json 檔案進行檢視,便可以看到未通過 user Namespace 進行隔離,所以我們需要以 root 許可權執行我們的容器。

➜  ~ sudo runc run debian
# ls                                      
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
# hostname    
runc               
# cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
複製程式碼

可以看到容器已經執行成功。當然,我們也可以不通過 root 許可權執行容器,只要簡單的通過 user Namespace 進行隔離,並新增 usergroup 的對映之類的便可以了。此處不做贅述。

為何有 runc 1.0-rc6 存在

我們知道,OCI 在 2015 年成立,在 2017 年 7 月的時候正式宣佈 OCI v1.0.0 release 。其實在 2017 年的 11 月還 release 了 v1.0.1 版本。

前面已經提過 runcOCI 的官方實現,那為何時過一年還未正式 release 1.0 呢?這裡面原因其實說來也複雜,這也是這篇文章想聊的部分。

首先:runc 1.0 我們想正式 relase 麼? 答案是 想。其實早在 2017 年 8 月份的時候 runc 1.0-rc4 就已經支援 OCI v1.0.0 了。但當時並沒有進行正式版釋出,轉而三個月後, OCI 稍做了更新。

到 2018 年 2 月份的時候,釋出了 runc 1.0-rc5 -- "The Final Stretch" 這個版本取名其實已經很明確了 The Final Stretch 已經將這個版本作為正式版本前的最後一個版本進行釋出了。

但是,提筆前又發了新版本 runc 1.0-rc6 -- "For Real This Time" ,這個版本在預期中其實是想釋出 1.0 的。我們討論後總結的結論主要有以下幾個:

  • 不夠規範。一方面是 runc 在持續的迭代改進,另一方面是目前很多其他的執行時實現的一些 hooks 依賴於當前的一些實現,而這些實現,並不完全符合規範。這就造成了一旦修正了這些 “錯誤” 勢必造成其他執行時的不穩定和錯誤。

  • 釋出週期不明確。目前容器相關生態中較為核心的專案,估計就 runc 的釋出週期比較 “佛系” 了,我們甚至沒有一個明確的釋出週期。這次的總結中,我以 Kubernetes 的釋出做了例子:

Kubernetes Release Date Cadence
Christening of 1.0 10th July 2015 ~one year from inception
From 1.0 to 1.1 9th November 2015 122 days
From 1.1 to 1.2 16th March 2016 128 days
From 1.2 to 1.3 1st July 2016 107 days
From 1.3 to 1.4 26th September 2016 87 days
From 1.4 to 1.5 12th December 2016 77 days
From 1.5 to 1.6 28th March 2017 106 days
From 1.6 to 1.7 30th June 2017 94 days
From 1.7 to 1.8 28th September 2017 90 days
From 1.8 to 1.9 15th December 2017 78 days
From 1.9 to 1.10 28th March 2018 103 days
From 1.10 to 1.11 3rd July 2018 97 days
From 1.11 to 1.12 ETA 25th September 2018 84 days

以這個釋出記錄來看的話,每三個月作為以此釋出相對合適,也比較通用。

至於這次,runc 1.0-rc6 的釋出,將作為特性凍結髮布,直到下次釋出前,重點都將放在 “符合規範” 上面,同時也給其他的執行時實現充足的時間,用於做好相容之類的。

總結

以上就是本次關於 runc 1.0-rc6 釋出時的一些碎碎念,對這種情況頗有感慨,“符合規範” 並沒有那麼好做,尤其是做基礎支撐的時候。


可以通過下面二維碼訂閱我的文章公眾號【MoeLove】

TheMoeLove

相關文章