k8s生态
首发于k8s生态
runc 1.0-rc6 发布之际

runc 1.0-rc6 发布之际


如果你在用 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 的发布做了例子:


以这个发布记录来看的话,每三个月作为以此发布相对合适,也比较通用。

至于这次,runc 1.0-rc6 的发布,将作为特性冻结发布,直到下次发布前,重点都将放在 “符合规范” 上面,同时也给其他的运行时实现充足的时间,用于做好兼容之类的。

总结

以上就是本次关于 runc 1.0-rc6 发布时的一些碎碎念,对这种情况颇有感慨,“符合规范” 并没有那么好做,尤其是做基础支撑的时候。


可以通过下面二维码订阅我的文章公众号【MoeLove】


weixin.qq.com/r/ZjkaAhP (二维码自动识别)

发布于 2018-11-27

文章被以下专栏收录