如果你在用 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 進行隔離,並新增 user
和 group
的對映之類的便可以了。此處不做贅述。
為何有 runc 1.0-rc6
存在
我們知道,OCI
在 2015 年成立,在 2017 年 7 月的時候正式宣佈 OCI
v1.0.0 release 。其實在 2017 年的 11 月還 release 了 v1.0.1 版本。
前面已經提過 runc
是 OCI
的官方實現,那為何時過一年還未正式 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】