第一本Docker书(修订版)

978-7-115-41933-0
作者: 【澳】James Turnbull(詹姆斯•特恩布尔)
译者: 李兆海刘斌巨震
编辑: 杨海玲

图书目录:

详情

本书将指导读者完成安装、部署、管理和扩展Docker。首先介绍Docker及其组件的基础知识,然后使用Docker构建容器和服务来完成各种任务。本书将带领读者通过整个开发生命周期,从测试到生产,了解Docker符合什么场景。书中将利用Docker为新项目建立测试环境,演示如何使用持续集成的工作流集成Docker,如何构建应用程序服务和平台,如何使用Docker的API,如何扩展Docker等内容。

图书摘要

版权信息

书名:第一本Docker书(修订版)

ISBN:978-7-115-41933-0

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

• 著    [澳]James Turnbull

  译    李兆海 刘 斌 巨 震

  责任编辑  杨海玲

• 人民邮电出版社出版发行 北京市丰台区成寿寺路11号

  邮编 100164 电子邮件 315@ptpress.com.cn

  网址 http://www.ptpress.com.cn

• 读者服务热线:(010)81055410

  反盗版热线:(010)81055315


James Turnbull是一位技术作家,还是一名开源极客。他最近的大作是一本讲述流行开源日志工具的书——The LogStash Book。James还写了两本关于Puppet的书,一本是Pro Puppet,另一本是较早的Pulling Strings with Puppet: Configuration Management Made Easy。此外,James还写了Pro Linux System Administration、Pro Nagios 2.0Hardening Linux这三本书。

James是Kickstarter公司的CTO。之前,James曾担任Docker公司服务与支持副总裁、Venmo公司工程副总裁和Puppet Labs的技术运维副总裁。

本修订版聚集于Docker 1.9及更高版本。

李兆海 网名Googol Lee。使用Googol这个名字真的是因为“10的100次方”这个意思,和后来的Google公司没有一点儿关系。多年后端程序员,早期以C、C++为主,后来转向Python,现在以Go为生。曾写过《Golang初探》发表于2011年2月号《程序员》。Docker早期使用者。平时喜欢乱翻书,遇到感兴趣的都会研究一番。Twitter账户@googollee。

刘斌 具有10余年软件开发经验,关注后台开发技术和各种编程语言。做过电子商务、金融、企业系统以及Android手机开发;写过Delphi,也兼做系统管理员和DBA(现在都改叫DevOps了);既做后台应用,也要调用前台CSS和JavaScript,可还是不敢自称“全栈”(Full Stack);今又舶来“增长黑客”(Growth Hacker),我想我要做一个“增长工程师”(Growth Engineer)。个人主页http://liubin.org。

巨震 北京大学软件工程硕士,服务器端开发者。目前就职于创业公司,使用Node.js、Golang进行服务器端开发。2013年底开始研究Docker,是Docker中文社区的活跃贡献者,负责Docker技术文章和视频的翻译、校对工作。生活中喜欢美食、骑行,热衷于PC硬件,喜爱折腾,热爱一切计算机相关的技术,坚信技术改变世界。最崇拜的技术传奇人物是前id Software首席程序员、现Oculus VR首席技术官John Carmack。


Simplified Chinese translation copyright © 2015

by Posts and Telecommunications Press

Published by arrangement with James Turnbull


Docker是一个开源的应用容器引擎,开发者可以利用Docker打包自己的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。

本书由Docker公司前服务与支持副总裁James Turnbull编写,是权威的Docker开发指南。本书专注于Docker 1.9及以上版本,指导读者完成Docker的安装、部署、管理和扩展,带领读者经历从测试到生产的整个开发生命周期,让读者了解Docker适用于什么场景。书中先介绍Docker及其组件的基础知识,然后介绍用Docker构建容器和服务来完成各种任务:利用Docker为新项目建立测试环境,演示如何使用持续集成的工作流集成Docker,如何构建应用程序服务和平台,如何使用Docker的API,如何扩展Docker。

本书适合对Docker或容器开发感兴趣的系统管理员、运维人员和开发人员阅读。


Docker来了!突然发现曾经顶礼膜拜的Hypervisor虚拟化已处于被整个颠覆的悬崖边缘,Docker容器技术的直接虚拟化不仅在技术方面使CPU利用率得到显著提升,还因80:20法则可在业务上更大程度发挥CPU利用率,而恰恰后者才真正体现了虚拟化之精髓!这本书用了大量简短可操作的程序实例介绍Docker的工作原理,几乎页页都是满满的代码干货,程序员读者可跟着这些例子自己动手玩转Docker,这真是一部专为程序员写的好书!IT行业如此“昨怜破袄寒,今嫌紫莽长”,我们码农们呢?还等什么,赶紧开始知识更新吧,别让你的知识技能这一看家本领也被颠覆了!

——毛文波,道里云CEO,
曾创建EMC中国实验室并担任首席科学家,曾参与创建HP中国实验室

Docker是什么?它有什么用?为什么身边的程序员都在谈论这个新兴的开源项目?

Docker是轻量级容器管理引擎,它的出现为软件开发和云计算平台之间建立了桥梁。Docker将成为互联网应用开发领域最重要的平台级技术和标准。这本书由曾任职于Docker公司的资深工程师编写,由国内社区以最快的速度完成翻译,是学习Docker的最佳入门书籍。如果你是一位希望让自己的代码运行在云端的程序员,现在就开始学习Docker吧!

——喻勇,DaoCloud联合创始人

Docker的核心价值在于,它很有可能改变传统的软件“交付”方式和“运行”方式。传统的交付源码或交付软件包的方式的最大问题在于,软件运行期间所“依赖的环境”是无法控制、不能标准化的,IT人员常常需要耗费很多精力来解决因为“依赖的环境”而导致软件运行出现的各种问题。而Docker将软件与其“依赖的环境”打包在一起,以镜像的方式交付,让软件运行在“标准的环境”中,这非常符合云计算的要求。这种变革一旦为IT人员接受,可能会对产业链带来很大的冲击。我们熟悉的apt-getyum是否会逐渐被docker pull取代?

有了标准化的运行环境,加上对CPU、内存、网络等动态资源的限制,Docker构造了一个“轻量虚拟环境”,传统虚拟机的绝大多数使用场景可以被Docker取代,这将给IT基础设施带来一次更大的冲击;KVM、ZEN、VMWare将会何去何从?此外,Docker秒级创建/删除虚拟机及动态调整资源的能力,也非常契合云计算“实例水平扩展,资源动态调整”的需求,Docker很有可能成为云计算的基石。

正是因为Docker将对传统IT技术带来上述两种“革命性”的冲击,所以我们看到围绕Docker的创业项目如火如荼。IT从业人员应该及早拥抱Docker,拥抱变化。阅读本书就是最佳入门途径。

——陈轶飞,原百度PaaS平台负责人,国内最早大规模应用Docker的实践者

Docker今天已经算是明星技术了,各种技术大会都会有人谈论它,越来越多的人像我一样对这门技术着迷。我开始关注Docker是因为当时主要关注PaaS的一些技术进展,当时PaaS受到云计算三层模型的禁锢,诞生很多非常重型的解决方案。我并不喜欢这些方案,不仅是因为这些方案复杂,而且充满了重复造轮子的自以为是。但是Docker的诞生给我眼前一亮的感觉,Docker诞生时从技术上看貌似没有任何亮点:隔离和资源限定都是LXC做的,安全是用GRSec(那时候还没有SELinux支持),镜像文件依赖于AUFS。但是,就是因为Docker什么有技术含量的活儿都没做,才显得它非常干净,非常优雅。Docker提供了一种优雅的方式去使用上述技术,而不是自顾自地去实现这些已有的很好的技术,这样会使构建环境的成本极大降低,从而非常有效地减少运维的复杂性,这不就是PaaS的本质吗?

短短一年的时间过后,Docker在中国都有了专门的容器大会,甚至出现了一票难求的情况,可见这一技术不但在国外快速地被社区认同,在国内也得到广泛的应用。我坚信PaaS的构建应该是多种组件灵活搭配组合的,而不应该是包罗万象的全套方案,Docker的设计符合这种原则,这是我最为欣赏的。Docker的发展异常迅猛,整个社区生态蓬勃向上一片繁荣。希望阅读本书的读者也尽快加入充满乐趣的Docker大家庭中来。

——程显峰,MongoDB中文社区创始人,独立技术顾问

以Docker为代表的容器技术是目前非常流行的一类技术,对虚拟化、云计算乃至软件开发流程都有革命性的影响。本书系统而又深入浅出地介绍了与Docker部署和应用相关的各个方面,体现了Docker的最新进展,并附有大量详尽的实例。无论系统架构师、IT决策者,还是云端开发人员、系统管理员和运维人员,都能在本书中找到所需的关于Docker的内容。本书非常适合作为进入Docker领域的第一本书。

——商之狄,微软开放技术(中国)首席项目经理

我很高兴能看到第一本引进国内的Docker技术书。这本书对于迫切想了解Docker技术以及相关工具使用的技术爱好者来说,是一本值得阅读的入门书籍。

——肖德时,数人云CTO

阅读本书,就像参加一个Docker专家的面授课程,书中包含了很多非常实用的小型案例,让你能够循序渐进地照着学习,加深理解。好多示例代码都可以拿来直接在开发中使用。James Turnbull是个写书的高手,章节安排合理紧凑,由浅入深地慢慢引领你理解Docker的奥秘。Docker不仅仅是技术,更是一个生态系统,技术和新项目层出不穷,每一章最后都有介绍本章相关的互联网项目(都可能是下一个Google),这是最能体现作者技术功力的。无论你是哪个行业的程序员,这本Docker的书绝对会让你受益匪浅。

——蔡煜,爱立信软件开发高级专家

相比OpenStack这种厂商主导的开源项目,Docker的社区更具极客风格,更加活跃,也更具颠覆潜力。对Docker本身,已经不用我再多说,只希望大家都看看这本书,并能积极尝试Docker。纵观IT行业历史,大的技术变革从来不是诞生于大厂商口中的金蛋,而是一小撮儿爱好者的小玩意儿,而Docker正是这个路子。

——赵鹏,Hyper投资人

Go语言是近年来IT技术发展历程中最伟大的事情,而Docker的出现则是云计算发展的重要里程碑。作为Go语言的杀手级应用,Docker推动了Go语言社区的发展。技术的全球同步化在加速,但非英语母语一定程度制约了中国IT技术的发展。这是一本Docker团队成员撰写的书,是一份难得的学习Docker技术的权威教材。我很高兴见到中文翻译能够如此迅速地跟进,这是一件了不起的事情。我很期待更多人能够通过这本书,了解Docker,参与到Docker的生态中,共同推进中国IT产业的进步。

——许式伟,七牛云存储CEO,《Go语言编程》作者

我非常喜欢这本书,它弥补了开源项目通常缺失的文档部分。书中涉及从安装到入门到业务场景下的各种应用及开发。本书作者的权威性以及译者的专业态度也保证了这本书的严谨性。这本书非常适合广大的Docker爱好者阅读。

——杜玉杰,OpenStack基金会董事


听到《第一本Docker书》要根据原版更新出版修订版的消息,感慨国内计算机方面书籍的技术出版已经非常专业,在书籍选择和翻译上都很用心,感谢杨海玲编辑为这本书的出版所做的巨大努力,这本书为国内的Docker技术普及提供了莫大的帮助。

从本书的第一版发行到现在,容器社区出现了翻天覆地的变化。Docker虽然是目前容器社区的最大赢家,是很多用户使用容器的首选,但从1.9版本开始它逐渐移除了对其他容器解决方案的支持。以前进入容器社区时宣讲的容器引擎不复存在,随之而来的是更多商业因素掺杂的一个开源项目。如果Docker公司有幸成功,我们将有机会见证在云时代一个开源创业公司如何成为商业领域的成功者,也为国内的创业者指出了一条可行的路径。但如今这个时代,任何行业、任何形式的垄断不是被摧毁就是在被打破的过程中。容器生态中的每一个成员,都期待着在一个开放的体系中获取自己的位置,获取应得的利益。商业就是如此残酷的游戏,连OpenStack这样庞大的生态,都会对容器的快速发展带来的威胁不寒而栗。

在Linux基金会的运作下,OCI(Open Container Initiative)和CNCF(Cloud Native Computing Foundation)两个组织相继成立。他们负责的领域组成了以容器为核心的技术栈,在重新定义Linux容器各种标准的同时,通过Kubernetes这样的优秀项目为业界提供使用容器的最佳实践。很多从业者意识到,单一容器或单一服务器的一组容器都不再是关注的重点,如何通过云原生应用(Cloud Native Application)和微服务框架(Microservice Framework),把商业逻辑映射为容器集群,为商业成功奠定技术基础才是核心。Docker Swarm作为Google Kubernetes的唯一竞争对手,关于它的内容是本书读者最需要关注的,正确选择容器编排调度工具比选择容器引擎更为关键。容器相关标准不断发布,所有容器相关的各种工具都会根据标准修改自己的接口,生态环境会随之更加开放和健壮。

开源不再是以往自由软件(Free Software)的精神,而是如今商业社会的重要组成部分。在华为内部一个大型技术会议上的演讲,我用如下的论断作为结束语,也期待给本书的读者带来一点启示:

无开源,不生态。

无生态,不商业。

——马全一,资深架构师,开源技术专家


如果你是一位技术爱好者,时刻关心业界最新动态,那么最近一定没少听说Docker吧,这绝对是在技术圈线上线下都在谈论的一个热门话题。

说实话,Docker算不上是什么全新的技术,它基于LXC(LinuX Containers),使用AUFS,而这些都是已经存在很长时间并被广泛应用了的技术。但运营PaaS服务的dotCloud公司将这些技术整合到一起,提供了简单易用的跨平台、可移植的容器解决方案。Docker最初由dotCloud公司在2013年发布。自发布以来,其发展速度之快超乎了很多人的想象,一路高歌猛进,2014年6月终于发布了1.0稳定版,而dotCloud在2013年10月干脆连公司名字也改为了Docker, Inc.。

Docker也可以被称为轻量级虚拟化技术。与传统的VM相比,它更轻量,启动速度更快,单台硬件上可以同时跑成百上千个容器,所以非常适合在业务高峰期通过启动大量容器进行横向扩展。现在的云计算可能更多的是在使用类似EC2的云主机,以后也许应该更多地关注容器了。

Docker是可移植(或者说跨平台)的,可以在各种主流Linux发布版或者OS X以及Windows上(需要使用boot2docker或者虚拟机)使用。Java可以做到“一次编译,到处运行”,而Docker则可以称为“构建一次,在各平台上运行”(Build once,run anywhere)。

从这一点可以毫不夸张地说,Docker是革命性的,它重新定义了软件开发、测试、交付和部署的流程。我们交付的东西不再只是代码、配置文件、数据库定义等,而是整个应用程序运行环境:“OS+各种中间件、类库+应用程序代码”。

无论你是开发人员、测试人员还是运维人员,随着对Docker越来越深入的了解,你都会爱上它。我们只需要运行几条docker run就可以配置好开发环境,通过Dockerfile或者Docker Hub与他人分享我们的镜像,与其他服务集成,进行开发流程的自动化。

试想一下这种开发流程是不是很酷?除了工作流程的自动化之外,还能消除线上线下环境不一致导致的问题。以后“在我的机器上运行得好好的……”这种托词应该再也没人信了吧。

Docker是为Infrastructure as code而生的,通过Dockerfile,镜像创建过程变得自动且可重复,还能进行版本管理。

Docker是为不可变基础设施(Immutable Infrastructure)而生的,对无状态服务的升级、部署将会更轻便更简单:我们无须再对它们的配置进行修改,只需要销毁这个服务并重建一个就好了。

Docker也是为云计算而生的,Docker的出现离不开云计算的兴起,反过来更多的云计算服务提供商也都开始把Docker纳入自己的服务体系之中,比如最近一个大事件就是Google刚刚发布了Google Container Engine(alpha)服务,一个基于其开源Docker编配工具Kubernetes的“Cluster-as-a-Service”。容器技术在云计算时代的重要程度由此可见一斑。

这是一本带领读者进入Docker世界的入门书。阅读本书除了能帮助读者理解Docker的基本原理,熟练掌握Docker的各种常见的基本操作之外,还能帮助读者了解Docker的实际应用场景以及如何利用Docker进行开发等话题,比如,如何使用Docker和Jenkins进行测试,如何对应用程序进行Docker化,以及如何构建由Node.js和Redis组成的多容器应用栈。当然,书中也不会忘了最近比较火的Fig——一个Docker编配工具,开发此工具的公司是位于英国伦敦的Orchard Laboratories,前段时间该公司刚刚被Docker收购,继续Fig的开发。现代应用程序都离不开API,Docker当然也不例外。在第8章中,读者将学到如何使用API而不是Docker命令来对Docker镜像和容器进行管理。如果你也想为Docker贡献自己的力量,那么一定不能错过第9章的内容,这一章将会主要介绍如何给Docker提issue,如何完成Docker文档,以及如何构建Docker开发环境和提交Pull Request。

最后,我谨代表合译者李兆海和巨震,向在本书翻译过程中给予了很大帮助的一些人表示最诚挚的感谢。Fiona(冯钊)在本书编写过程中做了很多沟通和协调工作,也对很多术语翻译提出了建议。马全一是Docker中文社区的创始人,也是本书中文版翻译工作的发起人。此外还有人民邮电出版社的杨海玲等编辑老师,没有她们的认真工作,这本书也不会以完美的形式展现在各位读者面前。

——刘斌


本书适合希望实施Docker或基于容器的虚拟化技术的开发者、系统管理员和有意用DevOps的人员阅读。

要阅读本书,读者需要具备一定的Linux/Unix技能,并熟悉命令行、文件编辑、软件包安装、服务管理和基本的网络知识。

注意

本书专注于1.9或更高版本的Docker,该版本不与早期版本向下兼容。实际上,在生产环境中,也推荐使用1.9或更高版本。

本书中有3张配图是由Docker公司提供的。

DockerTM是Docker公司的注册商标。

Scott Collier是一位高级主任系统工程师,就职于Red Hat的系统设计及工程团队。该团队根据从销售、市场以及工程团队收集到的数据,甄别并提供高价值的解决方案,并为内外部用户开发参考架构。Scott是Red Hat认证构架师(RHCA),具有超过15年的IT从业经验,他现在专注于Docker、OpenShift以及Red Hat系列产品。

除了思考分布式构架之外,Scott喜欢跑步、登山、露营,还喜欢陪妻子和3个孩子在得克萨斯州的奥斯汀享受烧烤。他的技术文章以及相关信息可以在其个人博客上找到。

John是一位连续创业者,同时也是高可用性、可扩展性基础设备专家。John现在在自己创建的Bulletproof公司担任CTO,这是一家提供关键任务的云服务商,同时,John还兼任提供综合视频服务的Vquence公司的CTO。

在空闲时间,John投身自由及开源软件(Free and Open Source Soft,FOSS)社区。他是linux.conf.au 2007会议的联合发起人,也是2007年悉尼Linux用户委员会(Sydney Linux User Group,SLUG)的委员。他做过大量的开源项目,如Debian、Ubuntu、Puppet以及Annodex套件。读者可以在他的个人博客上查看他的文章。John拥有新南威尔士大学的工程学士荣誉学位(计算机科学类)。

Paul Nasrat就职于Google公司,是一位网站可靠性工程师,同时也是Docker的贡献者。他在系统工程领域做了大量的开源工具,包括启动加载器、包管理以及配置管理等。

Paul做过各种系统管理和软件开发的工作。他曾在Red Hat担任软件工程师,还在ThoughtWorks公司担任过基础设备专家级顾问。Paul在各种大会上做过演讲,既有DevOps活动早期在2009年敏捷大会上关于敏捷基础设备的演讲,也有在小型聚会和会议上的演讲。

Royce Gilbert是本书技术插图的作者,在他超过30年的从业经验中,他做过CAD设计、计算机支持、网络技术、项目管理,还曾为多家世界500强企业提供商务系统分析,包括安然(Enron)、康柏(Compaq)、科氏(Koch)和阿莫科(Amoco)集团。Royce在位于堪萨斯州曼哈顿的堪萨斯州立大学担任系统/业务分析员。他业余时间在自己的Royce艺术工作室进行创作,是一位独立艺术家和技术插画家。他和38岁的妻子在堪萨斯州的弗林特山上修复了一间有127年历史的石头老屋,并以此为居所,过着平静的生活。

Q女士在纽约地区长大,是一位高中教师、纸杯蛋糕冷冻师、业余科学家、法医人类学家,还是一名灾难应急专家。她现居旧金山,制作音乐,研究表演,整理ng-newsletter,并负责照顾Stripe公司的名流。

这是行内代码语句:inline code statement

下面是代码块:

代码清单0-1 示例代码块

This is a code block

过长的代码行会换行。

读者可以在http://www.dockerbook.com/code/index.html获取本书的代码和示例程序,也可以从GitHub(https://github.com/jamtur01/dockerbook-code)签出。

本书英文原版是用Markdown格式写的,同时也使用了大量的LaTeX格式的标记符号,然后用PanDoc转成PDF和其他格式(还使用了Backbone.js on Rails那帮好兄弟写的脚本)。

如果读者发现任何错误,请用电子邮件与我联系,我的邮箱是james+errata@ lovedthanlost.net。

本书是The Docker Book一书v1.9.1版的中文版。


在计算世界中,容器拥有一段漫长且传奇的历史。容器与管理程序虚拟化(hypervisor virtualization,HV)有所不同,管理程序虚拟化通过中间层将一台或多台独立的机器虚拟运行于物理硬件之上,而容器则是直接运行在操作系统内核之上的用户空间。因此,容器虚拟化也被称为“操作系统级虚拟化”,容器技术可以让多个独立的用户空间运行在同一台宿主机上。

由于“客居”于操作系统,容器只能运行与底层宿主机相同或相似的操作系统,这看起来并不是非常灵活。例如,可以在Ubuntu服务器中运行RedHat Enterprise Linux,但却无法在Ubuntu服务器上运行Microsoft Windows。

相对于彻底隔离的管理程序虚拟化,容器被认为是不安全的。而反对这一观点的人则认为,由于虚拟机所虚拟的是一个完整的操作系统,这无疑增大了攻击范围,而且还要考虑管理程序层潜在的暴露风险。

尽管有诸多局限性,容器还是被广泛部署于各种各样的应用场合。在超大规模的多租户服务部署、轻量级沙盒以及对安全要求不太高的隔离环境中,容器技术非常流行。最常见的一个例子就是“权限隔离监牢”(chroot jail),它创建一个隔离的目录环境来运行进程。如果权限隔离监牢中正在运行的进程被入侵者攻破,入侵者便会发现自己“身陷囹圄”,因为权限不足被困在容器创建的目录中,无法对宿主机进行进一步的破坏。

最新的容器技术引入了OpenVZ、Solaris Zones以及Linux容器(如lxc)。使用这些新技术,容器不再仅仅是一个单纯的运行环境。在自己的权限范围内,容器更像是一个完整的宿主机。对Docker来说,它得益于现代Linux内核特性,如控件组(control group)、命名空间(namespace)技术,容器和宿主机之间的隔离更加彻底,容器有独立的网络和存储栈,还拥有自己的资源管理能力,使得同一台宿主机中的多个容器可以友好地共存。

容器经常被认为是精益技术,因为容器需要的开销有限。和传统的虚拟化以及半虚拟化(paravirtualization)相比,容器运行不需要模拟层(emulation layer)和管理层(hypervisor layer),而是使用操作系统的系统调用接口。这降低了运行单个容器所需的开销,也使得宿主机中可以运行更多的容器。

尽管有着光辉的历史,容器仍未得到广泛的认可。一个很重要的原因就是容器技术的复杂性:容器本身就比较复杂,不易安装,管理和自动化也很困难。而Docker就是为改变这一切而生。

Docker是一个能够把开发的应用程序自动部署到容器的开源引擎。由Docker公司(www.docker.com,前dotCloud公司,PaaS市场中的老牌提供商)的团队编写,基于Apache 2.0开源授权协议发行。

注意

顺便披露一个小新闻:作者本人目前是Docker公司的顾问。

那么Docker有什么特别之处呢?Docker在虚拟化的容器执行环境中增加了一个应用程序部署引擎。该引擎的目标就是提供一个轻量、快速的环境,能够运行开发者的程序,并方便高效地将程序从开发者的笔记本部署到测试环境,然后再部署到生产环境。Docker极其简洁,它所需的全部环境只是一台仅仅安装了兼容版本的Linux内核和二进制文件最小限的宿主机。而Docker的目标就是要提供以下这些东西。

Docker上手非常快,用户只需要几分钟,就可以把自己的程序“Docker化”(Dockerize)。Docker依赖于“写时复制”(copy-on-write)模型,使修改应用程序也非常迅速,可以说达到了“随心所至,代码即改”的境界。

随后,就可以创建容器来运行应用程序了。大多数Docker容器只需不到1秒钟即可启动。由于去除了管理程序的开销,Docker容器拥有很高的性能,同时同一台宿主机中也可以运行更多的容器,使用户可以尽可能充分地利用系统资源。

使用Docker,开发人员只需要关心容器中运行的应用程序,而运维人员只需要关心如何管理容器。Docker设计的目的就是要加强开发人员写代码的开发环境与应用程序要部署的生产环境的一致性,从而降低那种“开发时一切都正常,肯定是运维的问题”的风险。

Docker的目标之一就是缩短代码从开发、测试到部署、上线运行的周期,让你的应用程序具备可移植性,易于构建,并易于协作。

Docker还鼓励面向服务的架构和微服务架构[1]。Docker推荐单个容器只运行一个应用程序或进程,这样就形成了一个分布式的应用程序模型,在这种模型下,应用程序或服务都可以表示为一系列内部互联的容器,从而使分布式部署应用程序,扩展或调试应用程序都变得非常简单,同时也提高了程序的内省性。

注意

如果你愿意,当然不必拘泥于这种模式,你可以轻松地在一个容器内运行多个进程的应用程序。

我们来看看Docker的核心组件:

Docker是一个客户端/服务器(C/S)架构的程序。Docker客户端只需向Docker服务器或守护进程发出请求,服务器或守护进程将完成所有工作并返回结果。Docker守护进程有时也称为Docker引擎。Docker提供了一个命令行工具docker以及一整套RESTful API[2]来与守护进程交互。用户可以在同一台宿主机上运行Docker守护进程和客户端,也可以从本地的Docker客户端连接到运行在另一台宿主机上的远程Docker守护进程。图1-1描绘了Docker的架构。

图1-1 Docker架构

镜像是构建Docker世界的基石。用户基于镜像来运行自己的容器。镜像也是Docker生命周期中的“构建”部分。镜像是基于联合(Union)文件系统的一种层式的结构,由一系列指令一步一步构建出来。例如:

也可以把镜像当作容器的“源代码”。镜像体积很小,非常“便携”,易于分享、存储和更新。在本书中,我们将会学习如何使用已有的镜像,同时也会尝试构建自己的镜像。

Docker用Registry来保存用户构建的镜像。Registry分为公共和私有两种。Docker公司运营的公共Registry叫作Docker Hub。用户可以在Docker Hub[3]注册账号[4],分享并保存自己的镜像。

根据最新统计,Docker Hub上有超过10 000注册用户构建和分享的镜像。需要Nginx Web服务器[5]的Docker镜像,或者Asterix开源PABX系统[6]的镜像,抑或是MySQL数据库[7]的镜像?这些镜像在Docker Hub上都有,而且具有多种版本。

用户也可以在Docker Hub上保存自己的私有镜像。例如,包含源代码或专利信息等需要保密的镜像,或者只在团队或组织内部可见的镜像。

用户甚至可以架设自己的私有Registry。具体方法会在第4章中讨论。私有Registry可以受到防火墙的保护,将镜像保存在防火墙后面,以满足一些组织的特殊需求。

Docker可以帮用户构建和部署容器,用户只需要把自己的应用程序或服务打包放进容器即可。我们刚刚提到,容器是基于镜像启动起来的,容器中可以运行一个或多个进程。我们可以认为,镜像是Docker生命周期中的构建或打包阶段,而容器则是启动或执行阶段。

总结起来,Docker容器就是:

Docker借鉴了标准集装箱的概念。标准集装箱将货物运往世界各地,Docker将这个模型运用到自己的设计哲学中,唯一不同的是:集装箱运输货物,而Docker运输软件。

每个容器都包含一个软件镜像,也就是容器的“货物”,而且与真正的货物一样,容器里的软件镜像可以进行一些操作。例如,镜像可以被创建、启动、关闭、重启以及销毁。

和集装箱一样,Docker在执行上述操作时,并不关心容器中到底塞进了什么,它不管里面是Web服务器,还是数据库,或者是应用程序服务器什么的。所有容器都按照相同的方式将内容“装载”进去。

Docker也不关心用户要把容器运到何方:用户可以在自己的笔记本中构建容器,上传到Registry,然后下载到一个物理的或者虚拟的服务器来测试,再把容器部署到Amazon EC2主机的集群中去。像标准集装箱一样,Docker容器方便替换,可以叠加,易于分发,并且尽量通用。

使用Docker,可以快速构建一个应用程序服务器、一个消息总线、一套实用工具、一个持续集成(continuous integration,CI)测试环境或者任意一种应用程序、服务或工具。可以在本地构建一个完整的测试环境,也可以为生产或开发快速复制一套复杂的应用程序栈。可以说,Docker的应用场景相当广泛。

那么,为什么要关注Docker或容器技术呢?前面已经简单地讨论了容器提供的隔离性,结论是,容器可以为各种测试提供很好的沙盒环境。并且,容器本身就具有“标准性”的特征,非常适合为服务创建构建块。Docker的一些应用场景如下。

本书为读者提供了一个基于和围绕Docker生态环境构建的早期项目列表,详情请查看 http://blog.docker.com/2013/07/docker-projects-from-the-docker-community/

从Docker项目公布以来,已经有大量关于“哪些配置管理工具适用于Docker”的讨论,如Puppet、Chef。Docker包含一套镜像构建和镜像管理的解决方案。现代配置管理工具的原动力之一就是“黄金镜像”模型。然而,使用黄金镜像的结果就是充斥了大量、无管理状态的镜像:已部署或未部署的复杂镜像数量庞大,版本状态混乱不堪。随着镜像的使用,不确定性飞速增长,环境中的混乱程度急剧膨胀。镜像本身也变得越来越笨重。最终不得不手动修正镜像中不符合设计和难以管理的配置层,因为底层的镜像缺乏适当的灵活性。

与传统的镜像模型相比,Docker就显得轻量多了:镜像是分层的,可以对其进行迅速的迭代。数据表明,Docker的这些特性确实能够减轻许多传统镜像管理中的麻烦。现在还难以确定Docker是否可以完全取代配置管理工具,但是从幂等性和内省性来看,Docker确实能够获得非常好的效果。Docker本身还是需要在主机上进行安装、管理和部署的。而主机也需要被管理起来。这样,Docker容器需要编配、管理和部署,也经常需要与外部服务和工具进行通信,而这些恰恰是配置管理工具所擅长的。

Docker一个显著的特点就是,对不同的宿主机、应用程序和服务,可能会表现出不同的特性与架构(或者确切地说,Docker本就是被设计成这样的):Docker可以是短生命周期的,但也可以用于恒定的环境,可以用一次即销毁,也可以提供持久的服务。这些行为并不会给Docker增加复杂性,也不会和配置管理工具的需求产生重合。基于这些行为,我们基本不需要担心管理状态的持久性,也不必太担心状态的复杂性,因为容器的生命周期往往比较短,而且重建容器状态的代价通常也比传统的状态修复要低。

然而,并非所有的基础设施都具备这样的“特性”。在未来的一段时间内,Docker这种理想化的工作负载可能会与传统的基础设备部署共存一段时间。长期运行的主机和物理设备上运行的主机在很多组织中仍具有不可替代的地位。由于多样化的管理需求,以及管理Docker自身的需求,在绝大多数组织中,Docker和配置管理工具可能都需要部署。

Docker可以运行于任何安装了现代Linux内核的x64主机上。推荐的内核版本是3.8或者更高。Docker的开销比较低,可以用于服务器、台式机或笔记本。它包括以下几个部分。

在本书中,我们将讲述如何安装、部署、管理Docker,并对其进行功能扩展。我们首先会介绍Docker的基础知识及其组件,然后用Docker构建容器和服务,来完成各种的任务。

我们还会体验从测试到生产环境的完整开发生命周期,并会探讨Docker适用于哪些领域,Docker是如何让我们的生活更加简单的。我们使用Docker为新项目构建测试环境,演示如何将Docker集成到持续集成工作流,如何构建程序应用的服务和平台。最后,我们会向大家介绍如何使用Docker的API,以及如何对Docker进行扩展。

我们将会教大家如何:

推荐读者按顺序阅读本书。每一章都会以前面章节的Docker知识为基础,并引入新的特性和功能。读完本书后,读者应该会对如何使用Docker构建标准容器,部署应用程序、测试环境和独立的服务有比较深刻的理解。

除这些资源之外,在第9章中会详细介绍去哪里以及如何获得Docker的帮助信息。

[1]  [http://martinfowler.com/articles/microservices.html](http://martinfowler.com/articles/microservices.html)

[2]  [http://docs.docker.com/reference/api/docker_remote_api/](http://docs.docker.com/reference/api/docker_remote_api/)

[3]  [http://hub.docker.com/](http://hub.docker.com/)

[4]  [https://hub.docker.com/account/signup/](https://hub.docker.com/account/signup/)

[5]  [https://hub.docker.com/search?q=nginx](https://hub.docker.com/search?q=nginx)

[6]  [https://hub.docker.com/search?q=Asterisk](https://hub.docker.com/search?q=Asterisk)

[7]  [https://hub.docker.com/search?q=mysql](https://hub.docker.com/search?q=mysql)

[8]  [http://lwn.net/Articles/531114/](http://lwn.net/Articles/531114/)

[9]  [http://en.wikipedia.org/wiki/Cgroups](http://en.wikipedia.org/wiki/Cgroups)

[10]  [http://en.wikipedia.org/wiki/Copy-on-write](http://en.wikipedia.org/wiki/Copy-on-write)


Docker的安装既快又简单。目前,Docker已经支持非常多的Linux平台,包括Ubuntu和RHEL(Red Hat Enterprise Linux,Red Hat企业版Linux)。除此之外,Docker还支持Debian、CentOS、Fedora、Oracle Linux等衍生系统和相关的发行版。如果使用虚拟环境,甚至也可以在OS X和Microsoft Windows中运行Docker。

目前来讲,Docker团队推荐在Ubuntu、Debian或者RHEL系列(CentOS、Fedora等)宿主机中部署Docker,这些发行版中直接提供了可安装的软件包。本章将介绍如何在4种各有所长的操作系统中安装Docker,包括:

提示

Docker Toolbox一个安装了运行Docker所需一切的组件的集合。它包含VirtualBox和一个极小的虚拟机,同时提供了一个包装脚本(wrapper script)对该虚拟机进行管理。该虚拟机运行一个守护进程,并在OS X或Microsoft Windows中提供一个本地的Docker守护进程。Docker的客户端工具docker作为这些平台的原生程序被安装,并连接到在Docker Toolbox虚拟机中运行的Docker守护进程。Docker Toolbox替代了Boot2Docker。

Docker也可以在很多其他Linux发行版中运行,包括Debian、SUSE[2]、Arch Linux[3]、CentOS和Gentoo[4]。Docker也支持一些云平台,包括Amazon EC2[5]、Rackspace Cloud[6]和Google Compute Engine[7]

提示

可以在Docker安装指南(https://docs.docker.com/engine/installation/)查到完整的Docker支持平台列表。

我们之所以选择对在这4种环境下Docker的安装方法进行介绍,主要是因为它们是Docker社区中最常用的几种环境。例如,开发人员使用OS X电脑,系统管理员使用Windows工作站,而测试、预演(staging)或生产环境运行的是Docker原生支持的其他平台。这样,开发人员和系统管理员就可以在自己的OS X或者Windows工作站中用Docker Toolbox构建Docker容器,然后把这些容器放到运行其他支持平台的测试、预演或者生产环境中。

建议读者至少使用Ubuntu或者RHEL完整地安装一遍Docker,以了解Docker安装需要哪些前提条件,也能够了解到底如何安装Docker。

提示

和所有安装过程一样,我也推荐读者了解一下如何使用Puppet[8]或Chef[9]这样的工具来安装Docker,而不是纯手动安装。例如,可以在网上找到安装Docker的Puppet模块[10]和Chef cookbook[11]

和安装其他软件一样,安装Docker也需要一些基本的前提条件。Docker要求的条件具体如下。

目前,官方支持在以下版本的Ubuntu和Debian中安装Docker:

注意

这并不意味着上面清单之外的Ubuntu(或Debian)版本就不能安装Docker。只要有适当的内核和Docker所必需的支持,其他版本的Ubuntu也是可以安装Docker的,只不过这些版本并没有得到官方支持,因此,遇到的bug可能无法得到官方的修复。

安装之前,还要先确认一下已经安装了Docker所需的前提条件。我创建了一个要安装Docker的全新Ubuntu 14.04 LTS 64位宿主机,称之为darknight.example.com

在Ubuntu宿主机中安装并运行Docker所需的前提条件并不多,下面一一列出。

1.内核

首先,确认已经安装了能满足要求的Linux内核。可以通过uname命令来检查内核版本信息,如代码清单2-1所示。

代码清单2-1 检查Ubuntu内核的版本

$ uname -a
Linux darknight.example.com 3.13.0-43-generic #72-Ubuntu SMP Mon Dec
8 19:35:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

可以看到,这里安装的是3.13.0 x86_64版本的内核。这是Ubuntu 14.04及更高版本默认的内核。

如果使用Ubuntu较早的发行版,可以有一个较早的内核。应该可以轻松地用apt-get把Ubuntu升级到最新的内核,如代码清单2-2所示。

代码清单2-2 在Ubuntu Precise中安装3.13内核

$ sudo apt-get update
$ sudo apt-get install linux-headers-3.13.0-43-generic
  linux-image-3.13.0-43-generic linux-headers-3.13.0-43

注意

本书中的所有操作都使用sudo来获取所需的root权限。

然后,就可以更新Grub启动加载器来加载新内核,如代码清单2-3所示。

代码清单2-3 更新Ubuntu Precise的启动加载器

$ sudo update-grub

安装完成后需要重启宿主机来启用新的3.8内核或者更新的内核,如代码清单2-4所示。

代码清单2-4 重启Ubuntu宿主机

$ sudo reboot

重启之后,可以再次使用uname –a来确认已经运行了正确版本的内核。

2.检查Device Mapper

这里将使用Device Mapper作为存储驱动。自2.6.9版本的Linux内核开始已经集成了Device Mapper,并且提供了一个将块设备映射到高级虚拟设备的方法。Device Mapper支持“自动精简配置”[18](thin-provisioning)的概念,可以在一种文件系统中存储多台虚拟设备(Docker镜像中的层)。因此,用Device Mapper作为Docker的存储驱动是再合适不过了。

任何Ubuntu 12.04或更高版本的宿主机应该都已经安装了Device Mapper,可以通过代码清单2-5所示的命令来确认是否已经安装。

代码清单2-5 检查Device Mapper

$ ls -l /sys/class/misc/device-mapper
lrwxrwxrwx 1 root root 0 Oct  5 18:50 /sys/class/misc/device-mapper
  -> ../../devices/virtual/misc/device-mapper

也可以在/proc/devices文件中检查是否有device-mapper条目,如代码清单2-6所示。

代码清单2-6 在Ubuntu的proc中检查Device Mapper

$ sudo grep device-mapper /proc/devices

如果没有出现device-mapper的相关信息,也可以尝试加载dm_mod模块,如代码清单2-7所示。

代码清单2-7 加载Device Mapper模块

$ sudo modprobe dm_mod

cgroup和命名空间自2.6版本开始已经集成在Linux内核中了。2.6.38以后的内核对cgroup和命名空间都提供了良好的支持,基本上也没有什么bug。

现在“万事俱备,只欠东风”。我们将使用Docker团队提供的DEB软件包来安装Docker。

首先,要添加Docker的APT仓库,如代码清单2-8所示。其间,可能会提示我们确认添加仓库并自动将仓库的GPG公钥添加到宿主机中。

代码清单2-8 添加Docker的ATP仓库

$ sudo sh -c "echo deb https://apt.dockerproject.org/repo ubuntu- 
  trusty main > /etc/apt/sources.list.d/docker.list"

应该将trusty替换为主机的Ubuntu发行版本。这可以通过运行lsb_release命令来实现,如代码清单2-9所示。

代码清单2-9 查主机Ubuntu发行版本

$ sudo lsb_release --codename | cut -f2
trusty

接下来,要添加Docker仓库的GPG密钥,如代码清单2-10所示。

代码清单2-10 添加Docker仓库的GPG密钥

$ sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net
:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

之后,需要更新APT源,如代码清单2-11所示。

代码清单2-11 更新APT源

$ sudo apt-get update

现在,就可以安装Docker软件包了,如代码清单2-12所示。

代码清单2-12 在Ubuntu中安装Docker

$ sudo apt-get install docker-engine

执行该命令后,系统会安装Docker软件包以及一些必需的软件包。

提示

自Docker 1.8.0开始,Docker的软件包名称已经从lxc-docker变为docker-engine

安装完毕,用docker info命令应该能够确认Docker是否已经正常安装并运行了,如代码清单2-13所示。

代码清单2-13 确认Docker已经安装在Ubuntu中

$ sudo docker info
Containers: 0
Images: 0
. . .

在Ubuntu中,如果使用UFW[19],即Uncomplicated Firewall,那么还需对其做一点儿改动才能让Docker工作。Docker使用一个网桥来管理容器中的网络。默认情况下,UFW会丢弃所有转发的数据包(也称分组)。因此,需要在UFW中启用数据包的转发,这样才能让Docker正常运行。我们只需要对/etc/default/ufw文件做一些改动即可。我们需要将这个文件中代码清单2-14所示的代码替换为代码清单2-15所示的代码。

代码清单2-14 原始的UFW转发策略

DEFAULT_FORWARD_POLICY="DROP"

代码清单2-15 新的UFW转发策略

DEFAULT_FORWARD_POLICY="ACCEPT"

保存修改内容并重新加载UFW即可,如代码清单2-16所示。

代码清单2-16 重新加载UFW防火墙

$ sudo ufw reload

在Red Hat企业版Linux(或者CentOS或Fedora)中,只有少数几个版本可以安装Docker,包括:

提示

在Red Hat企业版Linux 7及更高版本中,Docker已经成为系统自带的软件包了,并且,只有Red Hat企业版Linux 7是Red Hat官方支持Docker的发行版本。

在Red Hat和Red Hat系列的Linux发行版中,安装Docker所需的前提条件也并不多。

1.内核

可以使用代码清单2-17所示的uname命令来确认是否安装了3.8或更高的内核版本。

代码清单2-17 检查Red Hat或Fedora的内核

$ uname -a
Linux darknight.example.com 3.10.9-200.fc19.x86_64 #1 SMP Wed Aug
21 19:27:58 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

目前所有官方支持的Red Hat和Red Hat系列平台,应该都安装了支持Docker的内核。

2.检查Device Mapper

我们这里使用Device Mapper作为Docker的存储驱动,为Docker提供存储能力。在Red Hat企业版Linux、CentOS 6或Fedora 19及更高版本宿主机中,应该也都安装了Device Mapper,不过还是需要确认一下,如代码清单2-18所示。

代码清单2-18 检查Device Mapper

$ ls -l /sys/class/misc/device-mapper
lrwxrwxrwx 1 root root 0 Oct  5 18:50 /sys/class/misc/device-mapper
  -> ../../devices/virtual/misc/device-mapper

同样,也可以在/proc/devices文件中检查是否有device-mapper条目,如代码清单2-19所示。

代码清单2-19 在Red Hat的proc文件中检查Device Mapper

$ sudo grep device-mapper /proc/devices

如果没有检测到Device Mapper,也可以试着安装device-mapper软件包,如代码清单2-20所示。

代码清单2-20 安装Device Mapper软件包

$ sudo yum install -y device-mapper

提示

在新版本的Red Hat系列发行版本中, yum命令已经被dnf命令取代,它们的语法并没有什么变化。

安装完成后,还需要加载dm_mod内核模块,如代码清单2-21所示。

代码清单2-21 加载Device Mapper模块

$ sudo modprobe dm_mod

模块加载完毕,就应该可以找到/sys/class/misc/device-mapper条目了。

在不同版本的Red Hat中,安装过程略有不同。在RHEL 6或CentOS 6中,需要先添加EPEL软件包的仓库。而Fedora中则不需要启用EPEL仓库。在不同的平台和版本中,软件包命名也有细微的差别。

1.在RHEL 6和CentOS 6中安装Docker

对于Red Hat企业版Linux 6和CentOS 6,可以使用代码清单2-22所示的RPM软件包来安装EPEL。

代码清单2-22 在RHEL 6和CentOS 6中安装EPEL

$ sudo rpm –Uvh http://download.fedoraproject.org/pub/epel/6/i386
  /epel-release-6-8.noarch.rpm

安装完EPEL后,就可以安装Docker了,如代码清单2-23所示。

代码清单2-23 在RHEL 6和CentOS 6中安装Docker软件包

$ sudo yum -y install docker-io

2.在RHEL 7中安装Docker

RHEL 7或更高的版本可以按照代码清单2-24所示的指令来安装Docker。

代码清单2-24 在RHEL 7中安装Docker

$ sudo subscription-manager repos --enable=rhel-7-server-extras-rpms
$ sudo yum install -y docker

要想访问Red Hat的Docker软件包和文档,必须是Red Hat的客户,并拥有RHEL服务器订阅授权(RHEL Server subscription entitlement)。

3.在Fedora中安装Docker

在不同版本的Fedora中,有几个软件包的名称有所不同。在Fedora 19中,要安装docker-io这个软件包,如代码清单2-25所示。

提示

在新版本的Red Hat系列发行版本中,yum命令已经被dnf命令取代,它们的语法并没有什么变化。

代码清单2-25 在Fedora 19中安装Docker

$ sudo yum -y install docker-io

在Fedora 20或更高的版本中,软件包的名称已经改为docker,如代码清单2-26所示。

代码清单2-26 在Fedora 20或更高版本中安装Docker

$ sudo yum -y install docker

而在Fedora 21中,软件包的名称又回退到了docker-io,如代码清单2-27所示。

代码清单2-27 在Fedora 21上安装Docker

$ sudo yum -y install docker-io

最后,到了Fedora 22,软件包的名称则又变回了docker。同时,也是在Fedora 22,yum命令也不被推荐使用,被dnf命令取代了,如代码清单2-28所示。

代码清单2-28 在Fedora 22上安装Docker

$ sudo dnf install docker

提示

可以在官方网站(https://docs.docker.com/engine/installation/oracle/)找到如何在Oracle Linux上安装Docker的文档。

软件包安装完成后就可以启动Docker守护进程了。在RHEL 6或CentOS 6中,可以用代码清单2-29所示的命令启动守护进程。

代码清单2-29 在Red Hat 企业版Linux 6中启动Docker守护进程

$ sudo service docker start

想要在系统开机时自动启动Docker服务,还应该执行代码清单2-30所示的命令。

代码清单2-30 确保在RHEL 6中开机启动Docker

$ sudo service docker enable

在RHEL 7或Fedora中启动Docker服务,则需要执行代码清单2-31所示的命令。

代码清单2-31 在RHEL 7中启动Docker守护进程

$ sudo systemctl start docker

想要在系统开机自动启动Docker服务,还要执行代码清单2-32所示的命令。

代码清单2-32 确保在Red Hat企业版7中开机启动Docker

$ sudo systemctl enable docker

完成上述工作后,就可以用docker info命令来确认Docker是否已经正确安装并运行了,如代码清单2-33所示。

代码清单2-33 在Red Hat系列发行版中检查Docker是否正确安装

$ sudo docker info
Containers: 0
Images: 0
. . .

提示

也可以直接从Docker官方网站下载RHEL[20]、CentOS[21]和Fedora[22]用的最新版RPM包。

如果使用的是OS X系统,则可以使用Docker Toolbox[23]快速上手Docker。Docker Toolbox是一个Docker组件的集合,还包括一个极小的虚拟机,在OS X宿主机上会安装与之对应的命令行工具,并提供了一个Docker环境。

Docker Toolbox自带了很多组件,包括:

要在OS X中安装Docker Toolbox,需要去GitHub下载相应的安装程序,可以在https://www.docker.com/toolbox找到。

首先需要下载最新版本的Docker Toolbox,如代码清单2-34所示。

代码清单2-34 下载Docker Toolbox PKG文件

$ wget https://github.com/docker/toolbox/releases/
download/v1.9.1/DockerToolbox-1.9.1.pkg

运行下载的安装文件,并根据提示安装Docker Toolbox即可,如图2-1所示。

图2-1 在OS X中安装Docker Toolbox

现在,已经安装了Docker Toolbox及其必需的前提条件,可以开始对其进行配置和测试了。要想对它进行配置,需要运行Docker Toolbox应用。

我们可以进入OS X系统的Applications文件夹,单击Docker CLI图标来初始化并启动Docker Toolbox虚拟机,如图2-2所示。

图2-2 在OS X中运行oot2Docker

现在,就可以通过将本机的Docker客户端连接到虚拟机中运行的Docker守护进程,来测试Docker Toolbox安装程序是否正常运行,如代码清单2-35所示。

代码清单2-35 在OSX中测试Docker Toolbox

$ docker info
Containers: 0
Images: 0
Driver: aufs
  Root Dir: /mnt/sda1/var/lib/docker/aufs
  Dirs: 0
. . .
Kernel Version: 3.13.3-tinycore64

太棒了!我们已经可以在OS X宿主机运行Docker了!

如果使用的是Microsoft Windows系统,也可以使用Docker Toolbox工具快速上手Docker。Docker Toolbox是一个Docker组件的集合,还包括一个极小的虚拟机,在Windows宿主机上安装了一个支持命令行工具,并提供了一个Docker环境。

Docker Toolbox自带了很多组件,包括:

提示

也可以通过使用包管理器Chocolatey[24]来安装Docker客户端。

要在Windows中安装Docker Toolbox,需要从GitHub上下载相应的安装程序,可以在https://www.docker.com/toolbox找到。

首先也需要下载最新版本的Docker Toolbox,如代码清单2-36所示。

代码清单2-36 下载Docker Toolbox的. exe文件

$ wget https://github.com/docker/toolbox/releases/download/v1.9.1/
  DockerToolbox-1.9.1.exe

运行下载的安装文件,并根据提示安装Docker Toolbox,如图2-3所示。

图2-3 在Windows中安装Docker Toolbox

注意

只能在运行Windows 7.1、8/8.1或者更新版本上安装Docker Toolbox。

安装完Docker Toolbox后,就可以从桌面或者Applications文件夹运行Docker CLI应用,如图2-4所示。

图2-4 在Windows中运行Docker Toolbox

现在,就可以尝试使用将本机的Docker客户端连接虚拟机中运行的Docker守护进程,来测试Docker Toolbox是否已经正常安装,如代码清单2-37所示。

代码清单2-37 在Windows中测试Docker Toolbox

$ docker info
Containers: 0
Images: 0
Driver: aufs
 Root Dir: /mnt/sda1/var/lib/docker/aufs
 Dirs: 0
. . .
Kernel Version: 3.13.3-tinycore64

太棒了!现在,Windows宿主机也可以运行Docker了!

本书中的一些示例可能会要求通过网络接口或网络端口连接到某个容器,通常这个地址是Docker服务器的localhost或IP地址。因为Docker Toolbox创建了一个本地虚拟机,它拥有自己的网络接口和IP地址,所以我们需要连接的是Docker Toolbox的地址,而不是你的localhost或你的宿主机的IP地址。

要想得到Docker Toolbox的IP地址,可以查看DOCKER_HOST环境变量的值。当在OS X或者Windows上运行Docker CLI命令时,Docker Toolbox会设置这个变量的值。

此外,也可以运行docker-machine ip命令来查看Docker Toolbox的IP地址,如代码清单2-38所示。

代码清单2-38 获取Docker Toolbox的虚拟机的IP地址

$ docker-machine ip
The VM's Host only interface IP address is: 192.168.59.103

那么,来看一个要求连接localhost上容器的示例,比如使用curl命令,只需将localhost替换成相应的IP地址即可。

因此,代码清单2-39所示的curl命令就变成了代码清单2-40所示的形式。

代码清单2-39 初始curl命令

$ curl localhost:49155

代码清单2-40 更新后的curl命令

$ curl 192.168.59.103:49155

另外,很重要的一点是,任何使用卷或带有-v选项的docker run命令挂载到Docker容器的示例都不能在Windows上工作。用户无法将宿主机上的本地目录挂接到运行在Docker Toolbox虚拟机内的Docker宿主机上,因为它们无法共享文件系统。如果要使用任何带有卷的示例,如本书第5章和第6章中的示例,建议用户在基于Linux的宿主机上运行Docker。

还有另外一种方法,就是使用远程安装脚本在相应的宿主机上安装Docker。可以从get.docker.com网站获取这个安装脚本。

注意

该脚本目前只支持在Ubuntu、Fedora、Debian和Gentoo中安装Docker,不久的未来可能会支持更多的系统。

首先,需要确认curl命令已经安装,如代码清单2-41所示。

代码清单2-41 测试curl

$ whereis curl
curl: /usr/bin/curl /usr/bin/X11/curl /usr/share/man/man1/curl.1.gz

如有需要,可以通过apt-get命令来安装curl,如代码清单2-42所示。

代码清单2-42 在Ubuntu中安装curl

$ sudo apt-get -y install curl

在Fedora中,可以使用yum命令或者较新的dnf命令来安装curl,如代码清单2-43所示。

代码清单2-43 在Fedora中安装curl

$ sudo yum -y install curl

现在就可以利用脚本安装Docker了,如代码清单2-44所示。

代码清单2-44 使用安装脚本来安装Docker

$ curl https://get.docker.com/ | sudo sh

这个脚本会自动安装Docker所需的依赖,并且检查当前系统的内核版本是否满足要求,以及是否支持所需的存储驱动,最后会安装Docker并启动Docker守护进程。

如果不想用任何基于软件包的安装方法,也可以下载最新的Docker可执行程序,如代码清单2-45所示。

代码清单2-45 下载Docker可执行程序

$ wget http://get.docker.com/builds/Linux/x86_64/docker-latest.tgz

不过本人不推荐这种安装方式,因为这降低了Docker软件包的可维护性。使用软件包更简单,也更易于管理,特别是在使用自动化安装和配置管理工具的情况下。

安装完Docker后,需要确认Docker的守护进程是否运行。Docker以root权限运行它的守护进程,来处理普通用户无法完成的操作(如挂载文件系统)。docker程序是Docker守护进程的客户端程序,同样也需要以root身份运行。用户可以使用docker daemon命令控制Docker守护进程。

注意

在Docker 1.8之前,Docker守护进程是通过-d标志来控制的,而没有docker daemon子命令。

当Docker软件包安装完毕后,默认会立即启动Docker守护进程。守护进程监听/var /run/docker.sock这个Unix套接字文件,来获取来自客户端的Docker请求。如果系统中存在名为docker的用户组的话,Docker则会将该套接字文件的所有者设置为该用户组。这样,docker用户组的所有用户都可以直接运行Docker,而无须再使用sudo命令了。

警告

前面已经提到,尽管docker用户组方便了Docker的使用,但它毕竟是一个安全隐患。因为docker用户组对Docker具有与root用户相同的权限,所以docker用户组中应该只能添加那些确实需要使用Docker的用户和程序。

运行Docker守护进程时,可以用-H标志调整守护进程绑定监听接口的方式。

可以使用-H标志指定不同的网络接口和端口配置。例如,要想绑定到网络接口,命令如代码清单2-46所示。

代码清单2-46 修改Docker守护进程的网络

$ sudo docker daemon -H tcp://0.0.0.0:2375

这条命令会将Docker守护进程绑定到宿主机上的所有网络接口。Docker客户端不会自动监测到网络的变化,需要通过-H选项来指定服务器的地址。例如,如果把守护进程端口改成4200,那么运行客户端时就必须指定docker -H :4200。如果不想每次运行客户端时都加上-H标志,可以通过设置DOCKER_HOST环境变量来省略此步骤,如代码清单2-47所示。

代码清单2-47 使用DOCKER_HOST环境变量

$ export DOCKER_HOST="tcp://0.0.0.0:2375"

警告

默认情况下,Docker的客户端-服务器通信是不经认证的。这就意味着,如果把Docker绑定到对外公开的网络接口上,那么任何人都可以连接到该Docker守护进程。Docker 0.9及更高版本提供了TLS认证。在本书第8章介绍Docker API时读者会详细了解如何启用TLS认证。

也能通过-H标志指定一个Unix套接字路径,例如,指定unix://home/docker/ docker.socket,如代码清单2-48所示。

代码清单2-48 将Docker守护进程绑定到非默认套接字

$ sudo docker daemon -H unix://home/docker/docker.sock

当然,也可以同时指定多个绑定地址,如代码清单2-49所示。

代码清单2-49 将Docker守护进程绑定到多个地址

$ sudo docker daemon -H tcp://0.0.0.0:2375 -H unix://home/docker/
  docker.sock

提示

如果你的Docker运行在代理或者公司防火墙之后,也可以使用HTTPS_PROXYHTTP_ PROXYNO_PROXY选项来控制守护进程如何连接。

还可以使用-D标志来输出Docker守护进程的更详细的信息,如代码清单2-50所示。

代码清单2-50 开启Docker守护进程的调试模式

$ sudo docker daemon -D

要想让这些改动永久生效,需要编辑启动配置项。在Ubuntu中,需要编辑/etc /default/docker文件,并修改DOCKER_OPTS变量。

在Fedora和Red Hat发布版本中,则需要编辑/usr/lib/systemd/system/docker. service文件,并修改其中的ExecStart配置项。或者在之后的版本中编辑/etc/ sysconfig/docker文件。

注意

在其他平台中,可以通过适当的init系统来管理和更新Docker守护进程的启动配置。

在Ubuntu中,如果Docker是通过软件包安装的话,可以运行Upstart的status命令来检查Docker守护进程是否正在运行,如代码清单2-51所示。

代码清单2-51 检查Docker守护进程的状态

$ sudo status docker
docker start/running, process 18147

此外,还可以用Upstart的startstop命令来启动和停止Docker守护进程,如代码清单2-52所示。

代码清单2-52 用Upstart启动和停止Docker守护进程

$ sudo stop docker
docker stop/waiting
$ sudo start docker
docker start/running, process 18192

在Red Hat和Fedora中,只需要用service命令就可以完成同样的工作,如代码清单2-53所示。

代码清单2-53 在Red Hat和Fedora中启动和停止Docker

$ sudo service docker stop
Redirecting to /bin/systemctl stop  docker.service
$ sudo service docker start
Redirecting to /bin/systemctl start  docker.service

如果守护进程没有运行,执行docker客户端命令时就会出现类似代码清单2-54所示的错误。

代码清单2-54 Docker守护进程没有运行的错误

2014/05/18 20:08:32 Cannot connect to the Docker daemon. Is 'docker -d'
  running on this host?

注意

在Docker 0.4.0版本以前,docker客户端命令有“独立模式”(stand-alone),在“独立模式”下,客户端不需要运行Docker守护进程就可以独立运行。不过现在这种模式已经被废弃了。

Docker安装之后,也可以很容易地对其进行升级。如果是通过类似apt-getyum这样的原生软件包安装的Docker,也可以用同样的方法对Docker进行升级。

例如,可以运行apt-get update命令,然后安装新版本的Docker。我们使用apt-get install命令来升级Docker,这是因为docker-engine(即之前的lxc-docker)包一般都是固定的,如代码清单2-55所示。

代码清单2-55 升级Docker

$ sudo apt-get update
$ sudo apt-get install docker-engine

Docker安装之后,也可以用图形用户界面来进行管理。目前,有一些正在开发中的Docker用户界面和Web控制台,它们都处于不同的开发阶段,具体如下。

在本章向大家介绍了在各种平台上安装Docker的方法,还介绍了如何管理Docker守护进程。

在下一章中,我们将开始正式使用Docker。我们将从容器的基础知识开始,介绍基本的Docker操作。如果读者已经安装好了Docker,并做好了准备,那么请翻到第3章吧。

[1]  [https://www.docker.com/toolbox](https://www.docker.com/toolbox)

[2]  [http://docs.docker.com/installation/openSUSE/](http://docs.docker.com/installation/openSUSE/)

[3]  [http://docs.docker.com/installation/archlinux/](http://docs.docker.com/installation/archlinux/)

[4]  [http://docs.docker.com/installation/gentoolinux/](http://docs.docker.com/installation/gentoolinux/)

[5]  [http://docs.docker.com/installation/amazon/](http://docs.docker.com/installation/amazon/)

[6]  [http://docs.docker.com/installation/rackspace/](http://docs.docker.com/installation/rackspace/)

[7]  [http://docs.docker.com/installation/google/](http://docs.docker.com/installation/google/)

[8]  [http://www.puppetlabs.com](http://www.puppetlabs.com)

[9]  [http://www.opscode.com](http://www.opscode.com)

[10]  [http://docs.docker.com/use/puppet/](http://docs.docker.com/use/puppet/)

[11]  [http://community.opscode.com/cookbooks/docker](http://community.opscode.com/cookbooks/docker)

[12]  [http://en.wikipedia.org/wiki/Device_mapper](http://en.wikipedia.org/wiki/Device_mapper)

[13]  [http://en.wikipedia.org/wiki/Aufs](http://en.wikipedia.org/wiki/Aufs)

[14]  [http://en.wikipedia.org/wiki/Virtual_file_system](http://en.wikipedia.org/wiki/Virtual_file_system)

[15]  [http://en.wikipedia.org/wiki/Btrfs](http://en.wikipedia.org/wiki/Btrfs)

[16]  [http://en.wikipedia.org/wiki/Cgroups](http://en.wikipedia.org/wiki/Cgroups)

[17]  [http://blog.dotcloud.com/under-the-hood-linux-kernels-on-dotcloud-part](http://blog.dotcloud.com/under-the-hood-linux-kernels-on-dotcloud-part)

[18]  [https://github.com/torvalds/linux/blob/master/Documentation/device-mapper/thin-provisioning.txt](https://github.com/torvalds/linux/blob/master/Documentation/device-mapper/thin-provisioning.txt)

[19]  [https://help.ubuntu.com/community/UFW](https://help.ubuntu.com/community/UFW)

[20]  [https://docs.docker.com/engine/installation/rhel/](https://docs.docker.com/engine/installation/rhel/)

[21]  [https://docs.docker.com/engine/installation/centos/](https://docs.docker.com/engine/installation/centos/)

[22]  [https://docs.docker.com/engine/installation/fedora/](https://docs.docker.com/engine/installation/fedora/)

[23]  [https://www.docker.com/toolbox](https://www.docker.com/toolbox)

[24]  [https://chocolatey.org/packages/docker](https://chocolatey.org/packages/docker)

[25]  [http://shipyard-project.com/](http://shipyard-project.com/)

[26]  [https://github.com/crosbymichael/dockerui](https://github.com/crosbymichael/dockerui)


相关图书

云原生测试实战
云原生测试实战
Kubernetes快速入门(第2版)
Kubernetes快速入门(第2版)
Kubernetes零基础实战
Kubernetes零基础实战
深入浅出Windows API程序设计:核心编程篇
深入浅出Windows API程序设计:核心编程篇
深入浅出Windows API程序设计:编程基础篇
深入浅出Windows API程序设计:编程基础篇
云原生技术中台:从分布式到云平台设计
云原生技术中台:从分布式到云平台设计

相关文章

相关课程