如果你正在使用Docker或者Kubernetes,你一定很熟悉容器运行时的概念。在Docker中,当你使用dockerinfo时,你可以查看当前使用的运行时。?~docker信息...服务器版本:18.06.1-ceStorage驱动程序:overlay2支持文件系统:extfs支持d_type:true本机覆盖差异:trueLogging驱动程序:json-fileCgroup驱动程序:cgroupfs...Swarm:inactiveRuntimes:nvidiaruncDefault运行时:runcInitBinary:docker-initcontainerdversion:468a545b9edcd5932818eb9de8e72413e616e86eruncversion:69663f0bd4b60df09991c08812a60108003fa340initversion:fec3683SecurityOptions:seccompProfile:default...同时,你还可以自己在/etc/docker/daemon.json中增加支持的runtime,以及在dockerrun的这时候配置--runtime参数使用的运行时。什么是runc简单来说就是OCI标准的一个实现。OCI标准包括运行时标准和镜像标准两部分,OCI组织由Docker、CoreOS等公司共同发起,旨在规范容器运行时和格式。即:任何符合这个标准的实现,无论是Docker还是rkt或者其他运行时实现,都可以通过标准镜像来启动容器。runc是Docker在OCI成立后贡献了自己的容器运行库libcontainer后改造而来的。而libcontainer也是在Docker0.9版本中加入的,我也是从这个版本开始使用的。当然,libcontainer的初衷不仅仅是为了取代当时的LXC依赖,而是作为一种规范(供其他项目使用)。最终,目标达到了。如何使用runcrunc的使用不是本文的重点,只是简单提一下。?~dockerexport-odebian.tar`dockercreatedebian`?~lsdebian.tar?~tar-Crootfs-xfdebian.tar?~lsdebian.tarrootfs?~tree-L1-arootfsrootfs├──bin├──boot├──dev├──.dockerenv├──etc├──home├──lib├──lib64├──media├──mnt├──opt├──proc├──root├────run├──sbin├──srv├──sys├──tmp├──usr└──var19directories,1file通过以上操作,得到了容器运行所需要的rootfs。当然,上面看到这个文件是通过docker获取的,但其实这只是为了方便,docker并不是必须的。?~runcspec?~lsconfig.jsondebian.tarrootfs通过以上操作会得到一个基本的config.json配置文件,里面包含了运行一个容器所需要的一些配置。它会包含一些信息如:"ociVersion":"1.0.1-dev",用来标识规范的版本号。接下来,稍微检查一下config.json文件,可以看到它并没有通过用户命名空间进行隔离,所以我们需要以root权限运行我们的容器。?~sudoruncrundebian#lsbinbootdevetchomelib64mediamntoptprocrootrunsbinsrvsystmpusrvar#hostnamerunc#cat/etc/os-releasePRETTY_NAME="DebianGNU/Linux9(stretch)"NAME="DebianGNU/Linux"VERSION_ID="9"VERSION="9(stretch)"ID=debianHOME_URL="https://www.debian.org/"SUPPORT_URL="https://www.debian.org/support"BUG_REPORT_URL="https://bugs.debian.org/"可以看到容器运行成功。当然,我们也可以在没有root权限的情况下运行容器,只要简单的通过用户Namespace进行隔离,加上用户和组的映射即可。这里我就不细说了。为什么会存在runc1.0-rc6?我们知道OCI成立于2015年,2017年7月正式宣布OCIv1.0.0版本发布,其实v1.0.1版本是2017年11月发布的。前面说了runc是OCI的官方实现,为什么一直没有时隔一年正式发布1.0?这里面的原因其实很复杂,这也是这篇文章要讲的。首先:我们要正式发布runc1.0吗?答案是肯定的。其实早在2017年8月,runc1.0-rc4就已经支持OCIv1.0.0。但当时并没有正式发布,三个月后,OCI略有更新。到2018年2月,发布了runc1.0-rc5——“TheFinalStretch”。这个版本的名字其实很清楚。TheFinalStretch已将此版本发布为正式版本之前的最后一个版本。然而,在写作之前发布了一个新版本的runc1.0-rc6——“ForRealThisTime”。这个版本实际上是为了按预期发布1.0。经过讨论,我们得出以下主要结论:不够规范。一方面,runc在不断迭代完善。另一方面,许多其他运行时实现的一些钩子依赖于当前的一些实现,而这些实现并不完全符合规范。一旦修复,这会导致其他运行时不稳定和错误。发布周期不明确。目前容器相关生态中比较核心的项目,估计runc的发布周期比较“佛系”,我们连一个明确的发布周期都没有。在这个总结中,我以Kubernetes的发布为例:KubernetesReleaseDateCadenceChristeningof1.010thJuly2015~一年从inceptionFrom1.0to1.19thNovember20155122daysFrom1.1to1.216thMarch2016128daysFrom1.2to1.30day1.321st1.426thSeptember201687从1.4到1.4到201677年12月1日至1.512日,从1.5到1.6283月1.6日至1.6至1.730,201794年6月1.7日至1.828日,201790年9月1.8日至1.915日至1.915日至1.915年12月1.9日至1.193月1.1028日。1.11to1.12ETA25thSeptember201884days从这个发布记录来看,每三个月发布一次是比较合适和普遍的。至于这一次,runc1.0-rc6的发布将作为功能冻结发布。直到下一次发布,重点将放在“符合规范”上,同时,也会给其他运行时实现做好足够的时间。兼容性等等。综上所述,以上是关于本次发布runc1.0-rc6的一些思考。我对这种情况很感慨。“符合规范”并不是那么容易做到的,尤其是在做基础支撑的时候。可以通过下方二维码订阅我的文章公众号【MoeLove】
