设为首页收藏本站

LUPA开源社区

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

Docker:分布式系统的软件工程革命(上)

2014-8-1 14:13| 发布者: joejoe0332| 查看: 7554| 评论: 0|原作者: 王益|来自: github

摘要: 为了使用Docker,需要了解不少工具及其设计思路;而这些工具的文档分布在不同的网站。为了方便大家学习,本文以开发一个极简的搜索引擎为例,展示Docker带来的革新。本文以技术教程为主线,穿插了一些关于Hadoop和Me ...
  为了使用Docker,需要了解不少工具及其设计思路;而这些工具的文档分布在不同的网站。为了方便大家学习,本文以开发一个极简的搜索引擎为例,展示Docker带来的革新。本文以技术教程为主线,穿插了一些关于Hadoop和Mesos等“模仿”项目的介绍,简要追溯它们勇敢而艰难的“邯郸学步”的历程。本文来自王益的个人博客。

以下为原文:


  Docker最近很火。Docker实现了“集装箱”——一种介于“软件包”和“虚拟机”之间的概念——并被寄予厚望,以期革新Internet服务以及其他大数据处理系统的开发、测试、和部署流程。


  为了使用Docker,需要了解不少工具及其设计思路;而这些工具的文档分布在不同的网站。为了方便大家学习,本文以开发一个极简的搜索引擎为例,展示Docker带来的革新。


  说是革新,其实是Google已经用了很多年的方式,只是最近才因为Docker开源项目而广为人知。最近这将近十年的时间里,各互联网公司和高校都在奋力模仿Google的计算技术。了解这一模仿的过程,可以帮助我们深入理解分布式系统(包括现在常说的“大数据系统”)中若干重要问题。为此,本文以技术教程为主线,穿插了一些关于Hadoop和Mesos等“模仿”项目的介绍,简要追溯它们勇敢而艰难的“邯郸学步”的历程。最后,本文会介绍Google最近公布的“正确答案”——Hubernetes——Google核心技术Borg的开源版本。


Docker

  Docker是一个软件系统,实现了一种称为“集装箱”的概念。集装箱类似Google机群管理系统Borg中的包(package)。


  通常我们说的“包”是软件包——比如Ubuntu/Debian Linux里常见的.deb文件——安装的时候,安装程序会把被依赖的包也装上。可是执行的时候呢?得根据具体情况配置,然后依次启动互相依赖的多个程序。比如,启动一个Web服务之前,要启动Apache和MySQL;而且他们仨都得有合理的配置,确保它们能一起工作,来实现这个Web服务。


  但是Docker集装箱以及Borg中的包更像虚拟机。虚拟机里包括程序和配置,所以可以被执行——也就是执行其中的程序。因为程序是配置好的,所以虚拟机可以被扔到各种环境上去执行——包括开发机、做演示用的笔记本电脑、用VirtualBox虚拟的机群、测试机群、预发布环境和产品环境。近几年随着“云计算”概念的普及,虚拟机被广泛使用,作为分布式计算的基础调度单元。


  Docker作为一个软件系统,可以用来创建“集装箱镜像”(container image)和执行这些镜像。就像VirtualBox是一个软件系统,可以用来创建和执行虚拟机。但是集装箱比虚拟机“轻”——一个虚拟机包括一组虚拟硬件、操作系统,用来执行用户程序;而集装箱里没有虚拟的硬件,也没有操作系统,它用主机(host)的硬件和操作系统来执行程序。


  那么在集装箱里跑程序和直接在主机上跑有什么区别呢?一个区别是,集装箱有一套网络端口空间(port space)。一个集装箱里的进程可以各自开端口,也可以连接对方的端口进行通信。但是这些端口是集装箱之外的进程看不到的。我们也可以让集装箱把某些内部端口号展示给外部,比如把集装箱内的端口5000映射到外部的8080。这样,当我们用主机上的程序(比如浏览器)访问本机(主机)的8080端口时,实际上访问的是集装箱里的5000端口。这项对外公开集装箱内部端口的技术,称为端口转发(port forwarding),和虚拟机的端口转发概念一样。另一个区别在于,集装箱里有虚拟的文件系统。这样我们可以把要执行的程序拷贝进集装箱。也可以把主机上的某些目录映射成集装箱虚拟文件系统的某些目录。


  集装箱这个想法已经在深刻地改变传统分布式系统的开发、测试和部署的流程了。传统的做法是,开发者写一个Makefile(或者其他描述,比如CMakeList、POM等)来说明如何把源码编译成二进制文件。随后,开发人员会在开发机上配置并且执行二进制文件,来作测试。测试人员会在测试机群上配置和执行,来作验证。而运维人员会在数据中心里的预发布环境和产品环境上配置和执行,这就是部署。因为开发机、测试机群、和产品环境里机器的数量和质量都不同,所以配置往往很不同。加上每个新版本的软件系统,配置方式难免有所差异,所以经常造成意外错误。以至于绝大部分团队都选择趁夜深人静、用户不活跃的时候,上线新版本,苦不堪言。


  而利用集装箱概念的开发流程里,开发者除了写Makefile,还要写一个Dockerfile,来描述如何把二进制文件安装进一个集装箱镜像(container image),并且做好配置。而一个镜像就像一台配置好的虚拟机,可以在机群上启动多个实例(instance),而每个实例通常称为一个集装箱(container)。在自测的时候,开发者在开发机上执行一个或者多个集装箱;在验证时,测试人员在测试机群上执行集装箱;在部署时,运维人员在产品环境执行集装箱。因为执行的都是同样地集装箱,所以不容易出错。


  这种流程更合理的划分了开发者和其他角色的工作边界,也大大简化了测试和部署工作。


boot2docker

  上节提到,Docker虚拟了网络地址空间和文件系统。实际上,它还虚拟了进程ID空间(pid space)等系统数据结构。这些功能是一个叫dockerd的daemon程序借助Linux内核中的control groups(又叫cgroups)功能实现的。


  dockerd负责执行集装箱;就像VirtualBox负责执行虚拟机一样。而cgroup是Google的两个工程师Paul Menage和Rohit Seth贡献给Linux社区的。从他们的工作记录看,主要工作集中在2008和2009年。据说,Google开发它就是为了方便在自己的机群上部署各种Internet应用和离线处理系统。具体一点儿的故事,请看这篇Information Week上的帖子。。


  因为cgroups功能只有Linux内核有,所以Docker目前只能运行在Linux上。可是,现在很多开发者都在用Mac。为了能让这些开发者方便的测试自己创作的集装箱镜像,Docker的开发者写了boot2docker——利用VirtualBox虚拟一个Linux主机,并且在上面安装dockerd。而命令行控制程序docker执行在Mac主机上,被配置成和虚拟Linux主机上的dockerd协作。


  boot2docker的安装方式很简单:照着这个流程,下载并执行一个安装包即可。因为boot2docker利用了VirtualBox,所以安装它之前需要先装VirtualBox。Homebrew也提供了安装boot2docker的选项,但是可能因为bug导致dockerd和docker版本不同,没法协同工作。


  在利用boot2docker在Mac上开始工作之前,还有几个注意事项。当我们在Linux主机上启动一个集装箱的时候,我们可以让Docker把主机的某些目录映射成集装箱内的目录。这样集装箱里的程序和主机上的程序共享数据,是一种方便的调试方式。但是在用boot2docker的时候,“主机”不是Mac,而是虚拟Linux主机。此时如果想把Mac上的目录映射到集装箱,先得将其通过VirtualBox映射到Linux主机。


  另一个注意事项和端口转发有关。当我们把集装箱内的某个端口映射为主机的某个端口时,只是映射到了虚拟Linux主机;如果想让Mac上的程序能访问,还得把虚拟机端口通过VirtualBox映射成Mac上的端口。这些注意事项,在下文中会有详细解释。



酷毙

雷人
1

鲜花

鸡蛋

漂亮

刚表态过的朋友 (1 人)

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

最新评论

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

返回顶部