添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
唠叨的碗  ·  【 云原生 kubernetes 】- ...·  2 周前    · 
善良的四季豆  ·  The connection to the ...·  1 周前    · 
一身肌肉的麦片  ·  Wifi 6 光猫 Gpon ONU ...·  2 月前    · 
傲视众生的玉米  ·  报考多讲究 ...·  10 月前    · 
英勇无比的领带  ·  How to easily add CSS ...·  1 年前    · 

过完年休假回来的一天,刷到一条新闻,说 RUNC 有一个致命的漏洞: cve-2019-5736 ,需要及时更新 Docker 来解决,让我很诧异。Docker 不是直接构建在 Linux 之上的么?怎么还有这个叫作 RunC 的什么事?于是我就顺便找了找相关的信息,发现自己的知识有点落伍了,Docker 的发展完全可以跟大前端圈子匹敌了,都快学不动了!这其中得发现也是千丝万缕的联系,各种爱恨情仇,利益纠葛,完全都可以写一部小说了,名字就叫《鲸鱼奇遇记》,不过经过一年多的大浪淘沙之后,似乎也稳定下来了,Google 的 Kubernetes 力压群雄完成了这场容器变革。

背景

OK,我就先不准备扯这么远了,还是回来看看 RUNC 是什么东西,并且怎么应用在 Docker 中的吧。在当初我看《 自己动手写 Docker 》的时候,这里面的 Docker 实现还是比较老的版本,相对来说还是比较原始的基于 LXC 的实现,里面的 init 都还是自己通过调用系统调用来实现的,Docker 最初也许是这么实现的,但是随着 Docker 的流行,事情发生了一些转变,为啥呢?因为一个东西流行之后,必定会有很多相关的东西被实现,例如 Docker 自己收购的 Compose,还有现在流行的 Kubernetes 等等,那么只要有外围应用,那么对核心的东西就是一个强依赖,如果没有一些约束的话,就会受到核心的应用的制约,例如如果不制定一个规范对 Docker 进行规范化,那么其他应用就等于把自己的生命放在 Docker 公司的手里,哪天 Docker 东西不开心了,改动一下一两个接口,大家都得完蛋。

在这样的情景下,有识之士肯定都是不满的,第一个跳出来的就是 Docker 的昔日好机油 CoreOS,我们知道 CoreOS 也是一家技术公司,它自己有自己的 CoreOS 操作系统,并且还有我们熟悉的好几个开源项目,例如 Etcd 和 flannel,它为了防范 Docker 的竞争,因为 Docker 作为一个基础组件肯定是不怎么赚钱的,为了打入企业级市场,那么一个很明显的发展方向就是 Paas,所以这时 CoreOS 感到了威胁,于是乎投资培养了 rkt,另外一个容器引擎,在2014年底,CoreOS 的 CEO Alex Polvi 正式发布了 CoreOS 的开源容器引擎 Rocket(rkt)。如果只有 CoreOS 一家肯定是掀不起什么风浪的,但是,没想到的是,有此担心的还有 Google,这家软件巨擎,作为一个有着多年(据说几十年?)容器使用经验的老司机,Google 对于容器的理解和沉淀应该没有哪一家可以比拟的。Google 在它的杀手级应用 Kubernets(borg) 上宣称支持 rkt,并且在 2015 年 4 月领投 CoreOS 1200万美元,这无疑是对外暴露我支持 CoreOS 的意思。

毕竟容器是个好东西,大家都是认可的,这么一个好牌总不能就这么玩坏了吧,于是乎,2015 年 6 月,在 Linux 基金会的牵头之下,大家决定好好得处理这件事情,于是乎由 Docker 公司牵头成立了 OCI(Open Container initiative/ 开放容器倡议),OCI 主要做了两项重要的工作,其实就是定义了两份规范,分别是:

  • the Runtime Specification (runtime-spec)[ http://www.github.com/opencontainers/runtime-spec ]
  • the Image Specification (image-spec)[ http://www.github.com/opencontainers/image-spec ]
  • 然而,这规范不是随便定义的,既然 Docker 已经那么流行了,那么这两份规范大部分都是基于 Docker 来定义的。其中, OCI Image 规范定义了 Image 的规范,通过的这个规范,一个 OCI 的实现可以将符合规范的 Image 解压为一个 filesystem bundle ,而这个 filesystem bundler 是可以被 Runtime 规范所加载并执行,这个就是 OCI 的意义。

    虽然 OCI 是由 Docker 公司发起并且维护的,但是,可以从 OCI 的官网上看到,其实并没有怎么维护,因为我个人看来,这时其实 CoreOS 和 Google 等公司的计谋已经达到了,虽然 Docker 是事实上的容器规范,但是只要有 OCI 这么个规范在,我基于容器的企业级应用便后顾无忧了,毕竟 CoreOS 和 Google 都是在企业级上拥有比 Docker 强得多的实力和经验,所以 Docker 公司在维护 OCI 的规范上也是显得无力。于是乎,以 Google 公司为核心的一系列公司,又成立了一个新的基金会 CNCF ,以 Kubernetes 为核心打造企业级的容器生态,到现在可以发现,Docker 公司越来越边缘化,于是乎,在 2017 年初,Docker 公司将 Docker 项目改名为 moby,叫给社区维护,并创建了 docker-ce 和 docker-ee 项目,他们的区别是:

  • moby:社区维护的 docker 开源版本
  • docker-ce:Docker 公司维护的 docker 开源版本
  • docker-ee:Docker 公司维护的 docker 闭源版本
  • 但是,从代码提交了修改上可以发现,moby 项目似乎没有怎么维护,反而像是 docker-ce 项目的 pick 从项目;从这个举动我个人的看法是,Docker 公司放弃了容器的发展话语权,转而作为一家容器服务公司,其实对于一家这样的初创公司,未毕这不是一条除了被收购(Docker 曾经拒绝了微软的收购)之外的好选择。

    RunC

    那么前边扯了这么多背景之后,和 RunC 有什么关系呢?其实在 CoreOS 叛逃之前,Docker 就开发了一个组件 Libcontainer ,它试图定义一个核心的容器底层,然后让其他人可以根据 Libcontainer 来构建自己的容器引擎,但是,因为大家对 Libcontainer 的实现以及意见反馈充满了诸多意见,并逐渐演化出了后面的容器标准之争,于是当 OCI 成立之后,Docker 公司就将 Libcontainer 捐赠给了 OCI,并且重命名为 runc(run container?),后面的 Docker 就基于 RunC 进行实现,下面我就尝试以 RunC 为工具进行运行 Container 的示例:

    这里有必要解释一下其中有两行的意思,分别是:

  • Line 5:使用 Docker 自身的 busybox image 来创建我们 runC image 的 rootfs
  • Line 6:使用 runc 生成默认的 config.json
  • 至于什么是 rootfs,这个留待以后讲吧,需要明白的是,Docker Container 是一个进程,那么进程有一个运行时环境,而这个 rootfs 提供了这个运行时环境的独特依赖,除此之外还有共同依赖,那就是系统内核,这个也后续再说。

    当我们创建完这两样东西之后就可以使用 runc 运行了:

    如果此时你另开一个终端,并且查看 runc list ,你会发现居然可以看到运行中的 runc 容器:

    其实这也响应了 runc 封装了 Docker 运行时的大部分功能的描述,根据说明,runc 可以加载并运行符合 OCI Image 规范的容器。而 runc 的玄妙之处在你查看 config.json 配置之后你将明白了大半:

    OK,这里就先看到这吧,后续我会继续玩一下 runc,并且尝试查看一下 docker-ce 是如何和 runc 结合起来的。

    Reference

    1. A Brief History of Containers: From the 1970s to 2017