设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客

从容器规范看Docker和Rocket

2015-1-19 12:16| 发布者: joejoe0332| 查看: 3159| 评论: 0|原作者: 王晓冉|来自: CSDN

摘要: CoreOS在发布Rocket时曾指出,有些人需要更“纯净”的容器。换句话说,Rocket是“App Container Specification”的标准实现。本文从“App Container Specification”入手,分析了Rocket和Docker在技术实现上的不同。 ...
  在“选择Docker还是Rocket做容器?为何不选择两个?”一文中,曾提到CoreOS的创始人Polvi和Docker的创始人Sonomon都认为,Rocket和Docker没有竞争性。Docker平台是一个产品,Rocket是一个组件。企业可以选择Docker替代Cloud Foundry,也可以使用Rocket构建Cloud Foundry。CoreOS在发布Rocket时就指出,Rocket的出现是因为有些人需要一个更“纯净”的容器。换句话说,Rocket算是“App Container Specification”的标准实现。本文作者从“App Container Specification”入手,分析了Rocket和Docker在技术实现上的不同。以下为原文:

DockerRocket,殊途同归

  首先,对于那些把DockerRocket放在一起比较的人,我想劝你们首先适当地调查一下。如果有这样两个软件:一个已经有1年多的历史,作为一个开源项目由全世界上千的开发者共同参与,并且已经或即将在实际的生产环境中被部署、测试;而另一个软件则是“新鲜出炉”的。如果这个较成熟的软件不是特别烂的话,那么很有可能它就是赢家。

  所以,将Docker0.1.1与最近预发行的Rocket拿来比较会更公平一些。此外, CoreOS的CTO Brandon Philips也多次强调,Docker的一些功能将不计划加入到Rocket中——不只是现在,也许永远不会。为什么?因为Rocket项目的重点,至少目前的情况——不是重新实现Docker。Rocket是 “App Container Specification”的实现,因此,想比较两者,最好比较“App Container Specification”和最初的Docker清单或者Docker实现的其它规范。


  以下的比较都将基于以上共识:


Systemd

  通常情况关于Rocket的讨论最多的话题是systemd-spawn或者是 systemd 。 CoreOS已将systemd作为他们Linux发行版的init系统。他们可以接着使用Init 脚本或者upstar,但是他们选择使用了将来会成为所有主流Linux版本标准的init系统。实话说我并没有关于systemd独到的见解,只是读过Lennart等人的一些文章。对于CoreOS来说,将systemd作为新的Linux发行版的init系统的是不明智的。另外,CoreOS已经获得了我的信任,我对此深信不疑。你可能会抛出 btrfs与我争论,但是, 那个会很快消失,我希望它会被修复,或者被其他可靠的方案替换。毕竟稳定性比功能更重要。

  好吧,让我们回到问题上来。其中systemd做的或者说能够做的事情多是进程管理。你可能会认为,systemd解决这个问题的方式,多少有些重叠了服务、进程管理的概念,并且将一些原本能在PID1之外很简单的任务复杂化了,但因为CoreOS是systemd的忠实用户,如果使用其它工具来实现反而显得奇怪。

  此外,据Brandon介绍Rocket的最初实现使用systemd-nspawn的原因是他们想用systemd,Systemd-naspawn 已经实现,而且正在做他们想做的东西,所以它有助于项目的开始。坦率地说,在0.1.1版本,我并不关心他们使用的技术,没准以后都会变的,因为Rocket的设计是可插拔的。如果你不喜欢systemd-nspawn,可以用你自己的stage1实现,Rocket已经提供了详细的命令行参数。

  另外需要指出的是,那些认为想使用Rocket,就必须运行systemd的人就完全错了。Rocket根本不需要systemd。它也能与其它init系统,如SysV或upstart配合工作。我在upstart上测试了Rocket,没有遇到任何问题。Rocket仅仅是“重用”了systemd和systemd-nspawn,处理stage1stage2


App Container

  有些人可能还没有准确地理解“App Container Specification”。他们一直在说systemd,并说Docker是如何好,不需要在容器中用systemd运行进程。Docker通过后台进程管理单进程的容器。Docker后台进程未被写成一个进程管理工具,当你的容器停止时,这种设计的弊端就会显现出来。你最终要通过主机或者容器中的进程管理工具来应付它。如果你还没有经历过这样的事,要么你可能是幸运的,又或者没有在环境中运行大量的容器。

  我们需要进程管理,或进程管理提供的某些功能。如果读过“App Container Specification”你会理解这点的。我将其中一部分摘录如下:

容器执行一个或多个应用程序,共享PID namespacenetwork namespacemount namespaceIPC namespace和UTS namespace。执行之前,每个应用程序将开始转为(比如chroot)自己特有的读写根文件系统。容器的定义是,包含一系列应该在一起启动的应用,以及应用与整个容器的隔离器。

  上面明确提到了几个进程共享Linux的命名空间。换言之,Kubernetes的Pod与以上对容器的定义很像,我不知道这是否与CoreOS正在积极参与Kubernetes的开发有什么关系。但Kubernetes Pod是一组容器,而不是容器中的一组进程。这让你能从多个Docker镜像组成一个Pod中获益。这是App Container Specification定义了 依赖关系的地方,所以你的容器可以依赖于其他容器,因此通过 Stage0创造的最终容器runtime可能是 这样的

  现在,你已经在容器中运行多个进程,其中一些可能是后台进程,并且可能需要被监督,你需要一个进程管理器。至今我用过最好的管理器是runit,但话说回来,当你已经积累了大量关于systemd的经验时,你为什么会想要写runit脚本或使用其他管理器?如果我是CoreOS,也会做出一样的决定——systemd。


Docker和命名空间

  现在,让我们回到Docker。Docker一直倡导一个容器运行一个进程。总的来说,我同意这一点,因为Linux容器主要是为了实现主机的进程隔离,而每个容器运行一个进程,会给你带来更多的灵活性和复合型,独立的更新、回滚等,操作更加简单。然而,当你创建一个新的Docker容器或事实上LXC容器,容器被重新分配一套由libcontainer提供的全新的Linux命名空间。实话说,我觉得这有点浪费。于Docker还挺有意义,因为你要在一个容器中运行一个单独的进程,并且如果你想提供更通用的进程环境,来覆盖大多数的用例,你可能需要libcontainer高效提供的大量可用命名空间。

  只为一个进程创建一组命名空间,增加了内核大量的额外管理工作。如果你的主机上运行了很多的容器,可能会出现内核某些方面的瓶颈。你可能会说开销很小,但是为什么非要过度占用内核呢?

  因此,为了节省开销,可以共享进程之间的命名空间。但是有个问题,如果你开始共享命名空间,并且创建它的容器已经终止,它会删除共享命名空间的所有的进程。Kubernetesde在设计Pod时,就考虑到这个问题了。 Kubernetes Pod中第一个被创建的容器,会被从internal/24 VLAN中分配一个IP地址,该IP地址也被Pod内共享一个network namespaces的容器共享。

  你可以看到这里微妙之处。每当“网络”创建的容器停止时,他会撤销Pod中所有的其它容器,因为没有可以共享的命名空间了,所以需要从头创建新的Pod,重新分配IP。更糟糕的是,你的连接也没了。所以,当你的容器停止后,不能自动重启它们。我相信通过观察Docker销毁容器的过程,可以找到解决办法,但是,那有些绕。所以,如果你想要在Docker容器中运行多个进程,你会需要一个进程管理工具。



酷毙

雷人

鲜花

鸡蛋

漂亮
  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部