您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 企业文化 > 利用Docker构建开发环境
利用Docker构建开发环境Postedbymakewonderon2014年4月2日Tweet48最近接触PAAS相关的知识,在研发过程中开始使用Docker搭建了自己完整的开发环境,感觉生活在PAAS时代的程序员真是幸福,本文会简要介绍下Docker是什么,如何利用Docker来搭建自己的开发环境(本文主要是面向MacOSX),以及期间所遇到的一些坑和解决方案。(本文会要求你对PAAS、LXC、CGroup、AUFS有一定的了解基础,请自行Google)大背景–虚拟化技术历史计算机虚拟化技术由来已久,从硬件仿真到全虚拟化,再到准虚拟化和操作系统虚拟化,各种技术粉墨登场,种类繁多,说实在的有点眼花缭乱和复杂;但用户的核心诉求一直是比较简单的,降低信息技术(IT)的运营成本,提高资源利用率,提高安全性和可靠性等等;虽说用户的核心诉求比较简单,但每个时代的需求场景却是不同的。在大型机时代,虚拟化技术被用来支持多个用户能够同时使用大型机,在x86架构时代,随着企业服务的大规模部署,虚拟化技术主要是用来提高企业资源的利用率,而现如今,随着云计算时代的到来,人们对应用的安全性、隔离性越来越高,对于部署的标准化以及虚拟机的性能要求越来越高。现如今,一种叫Linux容器的虚拟化技术逐渐得到广泛的应用,它的优点有许多,本文不一一赘述,有太多的文章可以参考。什么是Docker?docker的英文本意是码头工人,也就是搬运工,这种搬运工搬运的是集装箱(Container),集装箱里面装的可不是商品货物,而是任意类型的App,Docker把App(叫Payload)装在Container内,通过LinuxContainer技术的包装将App变成一种标准化的、可移植的、自管理的组件,这种组件可以在你的latop上开发、调试、运行,最终非常方便和一致地运行在production环境下。Docker的核心底层技术是LXC(LinuxContainer),Docker在其上面加了薄薄的一层,添加了许多有用的功能。这篇stackoverflow上的问题和答案很好地诠释了Docker和LXC的区别,能够让你更好的了解什么是Docker,简单翻译下就是以下几点:Docker提供了一种可移植的配置标准化机制,允许你一致性地在不同的机器上运行同一个Container;而LXC本身可能因为不同机器的不同配置而无法方便地移植运行;Docker以App为中心,为应用的部署做了很多优化,而LXC的帮助脚本主要是聚焦于如何机器启动地更快和耗更少的内存;Docker为App提供了一种自动化构建机制(Dockerfile),包括打包,基础设施依赖管理和安装等等;Docker提供了一种类似git的Container版本化的机制,允许你对你创建过的容器进行版本管理,依靠这种机制,你还可以下载别人创建的Container,甚至像git那样进行合并;DockerContainer是可重用的,依赖于版本化机制,你很容易重用别人的Container(叫Image),作为基础版本进行扩展;DockerContainer是可共享的,有点类似github一样,Docker有自己的INDEX,你可以创建自己的Docker用户并上传和下载DockerImage;Docker提供了很多的工具链,形成了一个生态系统;这些工具的目标是自动化、个性化和集成化,包括对PAAS平台的支持等;那么Docker有什么用呢?对于运维来说,Docker提供了一种可移植的标准化部署过程,使得规模化、自动化、异构化的部署成为可能甚至是轻松简单的事情;而对于开发者来说,Docker提供了一种开发环境的管理方法,包括映像、构建、共享等功能,而后者是本文的主题。Docker的安装和构成Docker官方本身提供了非常具体的安装教程,这里不说具体的安装过程,请参考Docker安装(Mac系统),重要的是描述下原理和安装完成后的结构,好对Docker更好的了解。由于LXC本身不支持Mac内核,因此需要跑一个VirtualBox虚拟机(TinyCoreLinux)来安装,幸好Docker社区提供了一个非常方便的工具boot2docker(其实就是一个VBoxManage的包装shell脚本),用于安装Mac下的整个Docker环境。具体的结构如下:如图所示,安装完成后,具体情况如下:在Mac的home目录~/.boot2docker下创建了虚拟机所需要的文件,其中boot2docker.iso是虚拟机映像,这是一个由CD-ROM引导的TinyCoreLinux系统;而boot2docker-vm.vmdk文件则是你的虚拟机磁盘,你所有的持久化数据都存放在这里,包括docker创建的lxc容器等文件。在Mac下,docker被分为客户端docker-client和服务端docker-daemon两部分,如果是在linux(比如ubuntu),实际上则是同一个可执行文件同时充当客户端和服务端。docker-daemon可以监听unixscoket,也可以在tcpsocket(默认端口为4234),docker-client会通过一个叫DOCKER_HOST的环境变量读取服务地址和端口,因此你应该在你的bash_profile文件里面添加这么一行:exportDOCKER_HOST=tcp://127.0.12exportDOCKER_HOST=tcp://127.0.0.1:4243docker-daemon跑在虚拟机上,这个程序实际上就是接收docker-client发送过来的消息命令,创建、启动和销毁lxc容器,以及docker本身的版本管理、映像存储等等运行你的第一个docker容器安装完成后,就差不多可以开始创建和运行docker容器了,在这之前,你首先得下载一个Image,什么是Image?我们先来了解docker的2个基础概念:Image和Container。Container和Image在Docker的世界里,Image是指一个只读的层(Layer),这里的层是AUFS里的概念,最直观的方式就是看一下docker官方给出的图:Docker使用了一种叫AUFS的文件系统,这种文件系统可以让你一层一层地叠加修改你的文件,最底下的文件系统是只读的,如果需要修改文件,AUFS会增加一个可写的层(Layer),这样有很多好处,例如不同的Container可以共享底层的只读文件系统(同一个Kernel),使得你可以跑N多个Container而不至于你的硬盘被挤爆了!这个只读的层就是Image!而如你所看到的,一个可写的层就是Container。那Image和Container的区别是什么?很简单,他们的区别仅仅是一个是只读的层,一个是可写的层,你可以使用dockercommit命令,将你的Container变成一个Image,也就是提交你所运行的Container的修改内容,变成一个新的只读的Image,这非常类似于gitcommit命令,感觉真棒!实际上这就是Docker对Container映像的版本管理基石,AUFS文件系统实在是太美妙了,更多细节可以参考DotCloud的这篇文章。运行和退出在了解了Image和Container的概念后,我们可以开始下载一个Image,Docker的好处就是提供了一个类似github的Image仓库管理,你可以非常方便pull别人的Image下来运行,例如,我们可以下载一个ubuntuImage:dockerpullubuntu:13.1012dockerpullubuntu:13.10这里的13.10是一个Tag,类似于git的tag,这里的tag可以为你制定一个ubuntu的版本。下载完成后,执行dockerimages命令可以列出你已经下载或者自己构建的image:(请允许我使用可爱的马赛克:))你可以看到ubuntu:13.10的大小为178MB,以及它的IMAGEID。现在我们开始运行一个Container,命令很简单,例如我们想运行一个执行Shell终端的Container:如你看到的,你已经进入到一个Shell里面,可以执行你想执行的任何命令,就和在ubuntu里面一样,进去后默认是在根目录/下,可以看到经典的unix/linux目录结构,以及你所运行的bash版本等信息。你可以给你的Container定一个名字,通过–name选项,例如这里命名了shell,日后你就可以直接用这个名字引用Contanier。退出一个Container也很简单,你直接exit就好了。其他更多的命令这里不做赘述,因为官方的文档已经非常全面,这里只是给一个直观的初步印象。下面进入主题。利用Docker搭建开发环境我们先看看程序员在搭建开发环境时遇到的一些问题:软件安装麻烦,比如很多公司都使用redhat,一般开发人员又不给root,安装一个nginx或者是mysql都得自己下载编译安装权限问题,没有root,一些软件无法运行,例如dnsmasq;没有root,无法修改hosts,无法netstat-nptl,无法tcpdump,无法iptable隔离性差,例如不同的开发人员如果在同一台主机环境下共享开发,虽然是用户隔离,但端口如果不规范可能会冲突;同一个Mysql如果权限管理不好很有可能误删别人的数据可移植性差,例如和生产环境不一致,开发人员之间也无法共享;更严重的情况是当有新人入职时,通常需要又折腾一遍开发环境,无法快速搭建这些问题可以通过在本地搭建虚拟机来解决,但虚拟机是一个很笨重的解决方案,Docker是一个非常轻量级的方案,而且还拥有虚拟机没有的一些功能,例如标准化Image,Image共享等,更重要的是,利用Docker,你可以运行非常多的容器,在你的Mac下搭建一个分布式的开发环境根本不是什么大的问题,而且对内存、磁盘和cpu的消耗相比传统的虚拟机要低许多,这些都要归功于AUFS和LXC这两大神奇的技术。构建基础Image想要搭建一个节省磁盘空间和扩展性良好的开发环境,最重要的第一步就是构建一个基础性的Image,比如你的主要开发语言是Ruby,那么你肯定需要一个已经安装好以下工具的基础Image:rubybundlergem然后在此基础上,你可以扩展这个基础的Image(下面叫base)为不同的开发环境,例如rails,或者是nats。当然,你的这个base也可以从别人的Image扩展而来,还记得我们刚刚pull下来的ubuntu:13.10这个Image吗?你可以从这个Image扩展开始构建你的base,如何做呢?Docker提供了一种标准化的DSL方式,你只需要编写一个Dockerfile,运行dockerbuild指令,就可以构建你自己的Image,这有点像Makefile和make命令一样,只是大家要构建的内容和构建语言不同。Dockerfile的语法请参考DockerfileReference,这里给出上面提到的Ruby开发的baseDockerfile示例:FROMubuntu:13.10RUNapt-getupdateRUNapt-getinstall-yrubyrubRUNgeminstallbundler12345FROMubuntu:13.10RUNapt-getupdateRUNapt-getinstall-yrubyruby-devgemRUNgeminstallbundler这里只用到了很简单的2个指令:FROM和RUN,FROM指定了我们要扩展的Image,RUN指定我们要运行的命令,这里是安装ruby,gem、bundler等软件。写好Dockerfile后,运行以下指令就可以创建你的baseimage了:dockerbuild--rm-tdev:base.12dockerbuild--rm-tdev:base.-t选项是你要构建的baseimage的tag,就好比ubuntu:13.10一样–rm选项是告诉Doc
本文标题:利用Docker构建开发环境
链接地址:https://www.777doc.com/doc-1816508 .html