Docker开发指南(txt+pdf+epub+mobi电子书下载)


发布时间:2020-06-16 15:31:03

点击下载

作者:阿德里安·莫阿特 (Adrian Mouat)

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Docker开发指南

Docker开发指南试读:

前言

容器是轻量且可移植的仓库,包含应用程序及其依赖的组件。

诚然,这个描述有点枯燥乏味。不过,若使用恰当,容器对开发流程的改进将会是革命性的。容器使新的软件架构和工作流程成为现实,这股吸引力难以抵挡,仿佛所有大型 IT 公司在一年里都从对 Docker 或容器闻所未闻转为积极研究,甚至已经付诸实践。

Docker 的兴起实在令人惊讶,我印象中没有任何一种技术像它那样,对 IT 产业产生了这么迅速而又深远的影响。我尝试用这本书来帮助你了解容器为什么重要、采用容器技术的好处是什么,以及最重要的是怎样着手使用它。目标读者

本书试图全面地讲解 Docker,解释使用 Docker 的原因,示范使用方法,以及如何与软件开发流程相结合。本书的内容包括开发、生产以至维护的整个软件生命周期。

本书假设读者只具备 Linux 和软件开发的基础知识,主要的目标读者为软件开发者、运维工程师以及系统管理员(尤其是考虑往 DevOps 方向发展的管理员),而技术型管理者和技术爱好者也能从中受益。写作目的

Docker 刚迅速兴起的时候,我就有幸知道它,并开始使用。当有机会写作这本书时,我毫不犹豫地抓住了它。假如拙作可以让部分读者了解这场容器化革命并好好地利用它,这将超越我在多年软件开发生涯里所获得的成就。

我真诚希望你会喜欢这本书,希望它能帮助你在公司或组织里使用 Docker。本书结构

本书大体由以下几部分组成。

第一部分首先讲解什么是容器,以及为什么应该关注它。之后将示范 Docker 的基本操作。最后会用较长篇幅来讲解 Docker 的基本概念和技术,其中包括 Docker 命令的概览。

第二部分讲解如何将 Docker 应用于软件开发的生命周期。首先讲解如何配置开发环境,然后构建一个简单的 Web 应用,这个 Web 应用的例子将用于整个第二部分。这一部分还会涵盖开发、测试、集成,以及如何部署容器,如何有效地监控和记录生产环境的日志。

第三部分的内容更为深入,其中包括在多主机集群环境中,有哪些工具及技巧能使 Docker 容器既安全又可靠地运行。这部分适合已经使用 Docker,并需要了解如何扩展或解决网络和安全问题的读者。排版约定

本书使用了下述排版约定。

楷体

表示新术语。

等宽字体(constant width)

表示程序片段,以及正文中出现的变量、函数名、数据库、数据类型、环境变量、语句和关键字等。

加粗等宽字体(constant width bold)

表示应该由用户输入的命令或其他文本。

斜体等宽字体(Constant width italic)

表示应该替换成用户提供的值,或者由上下文决定的值。该图标表示一般性说明。该图标表示提示、建议或一般注释。该图标表示警告或警示。使用代码示例

补充材料(代码示例、练习等)可以从 https://github.com/using-docker/> 下载。

本书是要帮你完成工作的。一般来说,如果本书提供了示例代码,你可以把它用在你的程序或文档中。除非你使用了很大一部分代码,否则无需联系我们获得许可。比如,用本书的几个代码片段写一个程序就无需获得许可,销售或分发 O'Reilly 图书的示例光盘则需要获得许可;引用本书中的示例代码回答问题无需获得许可,将书中大量的代码放到你的产品文档中则需要获得许可。

我们很希望但并不强制要求你在引用本书内容时加上引用说明。引用说明一般包括书名、作者、出版社和 ISBN。比如:“Using Docker by Adrian Mouat (O'Reilly). Copyright 2016 Adrian Mouat, 978-1-491-91576-9.”

如果你觉得自己对示例代码的用法超出了上述许可的范围,欢迎你通过 permissions@oreilly.com 与我们联系。®Safari Books Online

Safari Books Online(http://www.safaribooksonline.com>)是应运而生的数字图书馆。它同时以图书和视频的形式出版世界顶级技术和商务作家的专业作品。技术专家、软件开发人员、Web 设计师、商务人士和创意专家等,在开展调研、解决问题、学习和认证培训时,都将 Safari Books Online 视作获取资料的首选渠道。

对于组织团体、政府机构和个人,Safari Books Online 提供各种产品组合和灵活的定价策略。用户可通过一个功能完备的数据库检索系统访问 O'Reilly Media、Prentice Hall Professional、Addison-Wesley Professional、Microsoft Press、Sams、Que、Peachpit Press、Focal Press、Cisco Press、John Wiley & Sons、Syngress、Morgan Kaufmann、IBM Redbooks、Packt、Adobe Press、FT Press、Apress、Manning、New Riders、McGraw-Hill、Jones & Bartlett、Course Technology 以及其他几十家出版社的上千种图书、培训视频和正式出版之前的书稿。要了解 Safari Books Online 的更多信息,我们网上见。联系我们

请把对本书的评价和问题发给出版社。

美国:

O'Reilly Media, Inc.

1005 Gravenstein Highway North

Sebastopol, CA 95472

中国:

北京市西城区西直门南大街 2 号成铭大厦 C 座 807 室(100035)

奥莱利技术咨询(北京)有限公司

O'Reilly 的每一本书都有专属网页,你可以在那儿找到本书的相关信息,包括勘误表、示例代码以及其他信息。本书的网站地址是:

http://shop.oreilly.com/product/0636920035671.do>

对于本书的评论和技术性问题,请发送电子邮件到:

bookquestions@oreilly.com

要了解更多 O'Reilly 图书、培训课程、会议和新闻的信息,请访问以下网站:

http://www.oreilly.com>

我们在 Facebook 的地址如下:http://facebook.com/oreilly>

请关注我们的 Twitter 动态:http://twitter.com/oreillymedia>

我们的 YouTube 视频地址如下:http://www.youtube.com/oreillymedia>致谢

我很感激在我写作这本书的时候,大家给予我的一切帮助、建议和批评。如果下面遗漏了你的名字,请原谅我的疏忽。即便我没有完全按照你们的建议行事,我还是非常感谢你们为我所做的一切。

我要感谢 Ally Hume、Tom Sugden、Lukasz Guminski、Tilaye Alemu、Sebastien Goasguen、Maxim Belooussov、Michael Boelen、Ksenia Burlachenko、Carlos Sanchez、Daniel Bryant、Christoffer Holmstedt、Mike Rathbun、Fabrizio Soppelsa、Yung-Jin Hu、Jouni Miikki 和 Dale Bewley,感谢你们对本书毫无保留的反馈。

针对技术交流和书中一些具体技术的意见,我要感谢 Andrew Kennedy、Peter White、Alex Pollitt、Fintan Ryan、Shaun Crampton、Spike Curtis、Alexis Richardson、Ilya Dmitrichenko、Casey Bisson、Thijs Schnitger、Sheng Liang、Timo Derstappen、Puja Abbassi、Alexander Larsson 和 Kelsey Hightower。同时,还要感谢 Kevin Gaudin 允许我复用 monsterid.js。

感谢 O'Reilly 出版社的工作人员所给予的一切帮助,特别是本书编辑 Brian Anderson 和 Meghan Blanchette。在你们的帮助下,本书的出版工作才得以启动。

还有 Diogo Mónica 和 Mark Coleman,感谢你们在最后关头向我伸出援手。

在此我要特别鸣谢两家公司:Container Solutions 和 CloudSoft。Jamie Dobson 和 Container Solutions 给予我很多发表博客文章和在不同活动中演讲的机会,并向我介绍了几位对本书影响深刻的人。CloudSoft 慷慨地让我在写作本书时使用他们的办公室,并主办了爱丁堡 Docker 聚会,这两件事对我而言非常重要。

感谢我的所有朋友和家人,你们容忍我只顾埋头写作,并因为这本书向你们发牢骚。如果你明白我的意思,你应该知道我说的是谁(不过你们不太可能看到这番话)。

最后,感谢 BBC 6 Music 的电台 DJ 提供了原声配乐,包括 Lauren Laverne、Radcliffe and Maconie(Mark Radcliffe 和 Stuart Maconie)、Shaun Keaveny 和 Iggy Pop。电子书

扫描如下二维码,即可购买本书电子版。第一部分背景与基础本书第一部分首先介绍容器是什么,以及它为什么会变得如此流行;然后介绍 Docker 以及为充分利用容器所需了解的关键概念。第1章何谓容器,为何需要它

容器从根本上改变了人们开发、发布以及运行软件的方式。软件开发者可以在本地构建软件,因为他们知道软件能够在任何主机环境下运行,无论是 IT 部门的机房、用户的笔记本电脑,还是云端集群,而且运行时并无差异。运维工程师只需专注于维护网络和资源,保证正常运行时间,减少了花在配置环境及解决系统依赖关系上的时间。从规模很小的创业公司,到规模庞大的企业,容器的使用率和理解程度正以惊人的速度提升。可以预见,在未来几年,开发者和运维工程师将以不同形式广泛使用容器技术。

容器是对应用程序及其依赖关系的封装。乍一看容器只是个轻量级的虚拟机,它和虚拟机一样拥有一个被隔离的操作系统实例,用来运行应用程序。

但容器拥有一些优点,使它能实现一些传统虚拟机很难实现甚至无法实现的用例。

容器能与主机的操作系统共享资源,因而它的效率高出一个数量级。启动和停止容器均只需一瞬间。相比在主机上直接运行程序,容器的性能损耗非常低,甚至是零损耗。

容器具有可移植性,这极有可能彻底解决由于运行环境的些许改变而导致的问题,甚至有可能彻底终止开发者的抱怨:“可是程序在我的计算机上能正常工作!”

容器是轻量的,这意味着开发者能同时运行数十个容器,并能模拟分布式系统在真实运行环境下的情况。运维工程师在一台主机上能运行的容器数量,远远超过仅使用虚拟机时。

对于最终用户及开发者而言,容器的优势不仅仅体现在云端部署。用户可以下载并执行复杂的应用程序,而无需花费大量时间在配置和安装的问题上,也无需担心对系统本身的改动。另一方面,应用程序的开发者不用再操心用户环境的差异,以及依赖关系是否满足。

更重要的是,虚拟机和容器的根本目标不尽相同。虚拟机的目的是要完整地模拟另一个环境,而容器的目的则是使应用程序能够移植,并把所有依赖关系包含进去。1.1 容器与虚拟机的比较

虽然容器和虚拟机乍一看很相似,但它们之间有着重大的差异,用图就能轻松解释这些差异。

图1-1 中有三个应用程序,分别运行在主机的不同虚拟机上。这里需要一个虚拟机管理程序(hypervisor)来创建及运行虚拟机,控制访问底层操作系统及硬件的权限,以及在必要时解析系统调用接口。每个虚拟机需要一个完整的操作系统、用来运行的应用程序以及所需的程序库。图1-1:运行在同一台主机上的 3 个虚拟机

相比之下,图 1-2 展示了上述三个应用程序在容器化系统中运行的情况。与虚拟机不同,主机的内核与容器共享,这意味着容器只能运行与主机一样的内核。应用程序 Y 和 Z 使用相同的程序库,该程序库可以被不同的应用程序同时使用,只需一份,不用复制。容器引擎(container engine)负责启动及停止容器,与虚拟机管理程序差不多。但是,容器中执行的进程与主机自身的进程是等价的,因此没有类似虚拟机管理程序执行所带来的损耗。图1-2:运行在同一台主机上的 3 个容器

虚拟机与容器都可以把主机上的应用程序隔离开来。虚拟技术中的虚拟机管理程序能带来更高一级的隔离性能,是已被公认且千锤百炼的技术。容器技术相对较新,很多公司在取得充分可靠的运行记录前,无法完全信任容器的隔离性能。因此,不难发现有些系统同时采用这两种技术,将容器运行在虚拟机内,这样就能鱼与熊掌兼得。1.2 Docker 与容器

容器并不是新概念。几十年来,UNIX 系统一直以 chroot 命令来提供简单的文件系统隔离。自 1998 年起,FreeBSD 有了 jail 命令,它把 chroot 的沙盒机制扩展至进程。2001 年左右,Solaris Zones 提供了一个相对完整的容器化技术,但它只能用于 Solaris 操作系统。同样在 2001 年,Parallels 公司(当时称为 SWsoft)推出用于 Linux 的商业容器技术,名为 Virtuozzo,并于 2005 年把核心技术开源,称其为 OpenVZ。然后,谷歌开始为 Linux 内核开发 CGroups 机制,并开始将它的基础设施容器化。2008 年,Linux 容器(Linux Containers,LXC)项目启动,它把 CGroups、内核命名空间以及 chroot 等技术融合,提供了一套完整的容器方案。最后,Docker 于 2013 年补充了当时容器化技术的不足,将容器技术带入主流。

Docker 利用现有的 Linux 容器技术,以不同方式将其封装及扩展——主要是通过提供可移植的镜像,以及一个用户友好的接口——来创建一套完整的容器创建及发布方案。Docker 平台拥有两个不同部分:负责创建与运行容器的 Docker 引擎,以及用来发布容器的云服务 Docker Hub。

Docker 引擎提供了一个快速且便捷的接口用来运行容器。在此之前,使用如 LXC 等技术运行容器需要相当多的专业知识以及手动操作。Docker Hub 提供大量的公共容器镜像以供下载,方便用户快速上手,并且避免了重复劳动。Docker 还进一步开发了更多的工具,如集群管理工具 Swarm、用于处理容器的图形用户界面 Kitematic,以及部署 Docker 主机的命令行工具 Machine。

由于 Docker 引擎是开源的,这使得 Docker 社区日益壮大,并能借助大家的帮助来修正问题及改进。Docker 的迅速崛起,使它成为事实上的业界标准,由此业界不得不为容器运行环境及格式发展出一套独立于任何组织的正式标准。2015 年,开放容器促进会(Open Container Initiative,OCI)终于成立,它是一个由 Docker、微软、CoreOS 以及多个重要团体组成的管理架构,目标就是要发展出这一标准。Docker 的容器格式以及运行环境组成了这一工作的基石。

容器技术的兴起很大一部分是由开发者所驱动的,也是他们首次使用了能真正发挥容器潜力的工具。对实施快速迭代开发模式的开发者来说,Docker 容器能迅速启动至关重要,因为他们可以很快看到代码变更后的结果。容器能保障的可移植性及隔离特性,使得开发与运维部门之间更容易协作,因为开发者知道他们的代码在不同环境下都能工作,而运维部门只需专注于容器的托管及服务编排,而无需担心任何关于代码的事。

Docker 为软件开发带来了翻天覆地的变化。假如没有 Docker,在很长一段时间内容器将仍是一种鲜为人知的技术。

航运的比喻

Docker 的哲学经常用航运集装箱的比喻来解释,这或许能解释 Docker 名字的由来。这个比喻大概是这样的。

运输货物时,要用到多种不同的运输工具,可能包括货车、叉车、起重机、火车和轮船。这意味着这些工具必须能够处理大小不一、运输需求各异的货物(例如袋装的咖啡、桶装的有毒化学品、盒装的电子产品、成队的豪华轿车、冷冻羊排)。以往这是一道复杂且成本高昂的工序,需要付出大量人力物力。如图 1-3 所示,码头工人在每个中转站手动装卸货物。图1-3:码头工人在英国布里斯托市工作,摄于 1940 年(来自英国信息部图片处摄影师)

联运集装箱的诞生为运输产业带来了一场革命。集装箱的大小有了统一标准,并且设计的出发点是能以最少的人力在不同的运输方式之间搬运。所有的运输机械,无论是叉车和起重机,还是货车、火车和轮船,都为搬运这些集装箱而设计。运输对温度敏感的货物(如食品和药物)时,可以使用具有冷冻及保温功能的集装箱。标准化的好处甚至延伸到其他支撑体系,如集装箱的标签及铅封方式。因此,运输产业只需专注于处理集装箱本身的搬运以及储存的问题,而集装箱内的东西则完全由货物生产商负责。

Docker 的目标是把集装箱的标准化流程运用到 IT 行业中去。近年来,软件系统的多样性激增。在单一机器中运行 LAMP组合的日子已一去不复返。如今典型的系统可能包含 JavaScript 框架、NoSQL 数据库、消息队列、REST API,以及由各种不同编程语言所写的后端。而这个组合的全部或部分都需要能够在各种不同的硬件上运行——从开发者的笔记本电脑,到公司内部的测试集群,再到云端的生产环境。每个环境都存在差异,它们在不一样的硬件上运行着不一样的操作系统和不同版本的程序库。简而言之,我们的问题与当时运输产业遇到的极为相似——我们正不断付出巨大人力,在不同环境之间移动程序。Docker 容器简化了移动应用程序的工作,好比联运集装箱简化了货物运输一样。开发者只需专注于程序开发,再也不用担心测试与正式发布时环境及依赖关系的差异所带来的问题。运维部门则只需专心处理与运行容器相关的核心问题,例如分配资源、启动和停止容器,以及在服务器间的迁移工作。1.3 Docker的历史

2008 年,Solomon Hykes 为了建立一个与编程语言无关的平台即服务(Platform-as-a-Service,PaaS)产品,创立了 dotCloud 公司。编程语言无关这个特性是 dotCloud 独一无二的卖点,因为当时的 PaaS 都必定与某些语言绑定(例如 Heroku 支持 Ruby,Google App Engine 支持 Java 和 Python)。2010 年,dotCloud 参与了 Y Combinator 的加速器计划,认识了一些新的合作伙伴,并开始吸引到一些真正的投资。主要的转机出现在 2013 年 3 月,那时候 dotCloud 将其核心组件 Docker 开源。很多公司都害怕这样做会失去自己那只会下金蛋的鹅,但 dotCloud 则认为把 Docker 转化成一个社区运作的项目会令其受益良多。

Docker 早期的版本只是在简单封装 LXC 以及联合文件系统(union filesystem)之上多加了点东西,但往后无论是发展还是被接受的速度都快得惊人。6 个月内 Docker 就在 GitHub 上获得了 6700 多颗星,以及 175 名非公司员工的贡献者。这导致 dotCloud 把公司名称改为 Docker,并将公司的商业模式重新定位。0.1 版本发布 15 个月后,Docker 1.0 于 2014 年 6 月发布。Docker 1.0 代表着稳定性与可靠性的飞跃——它声称已经“生产就绪”,虽然在这之前就已经有一些公司(如 Spotify 和百度)正式投入使用。同时,Docker 推出了一个名为 Docker Hub 的公共容器仓库,这标志着 Docker 从一个单纯的容器引擎开始转变为一个完整的平台。

其他公司很快就发现了 Docker 的潜力。红帽于 2013 年 9 月成为了它的主要合作伙伴,利用 Docker 来驱动它的 OpenShift 云业务。谷歌、亚马逊和 DigitalOcean 也迅速地在其云服务平台提供 Docker 的支持。有几家创业公司也开始了专门从事 Docker 托管的业务,例如 StackDock。2014 年 10 月,微软公布未来的 Windows Server 将会支持 Docker,这代表着这家让人自然联想到臃肿企业软件的公司,在定位上也作出了重大改变。

在 2014 年 12 月举行的 DockerConEU 上,Docker Swarm 与 Docker Machine 同时面世。 Docker Swarm 是一个 Docker 集群管理工具,而 Docker Machine 是个部署 Docker 主机的命令行工具。这表明 Docker 的意图不仅仅是提供 Docker 引擎,而是提供一个完整且综合的容器运行方案。

在同一个月里,CoreOS 宣布开发自家的容器运行环境 rkt 以及 appc 容器规范。2015 年 6 月,DockerCon 在旧金山举行,来自 Docker 的 Solomon Hykes 与来自 CoreOS 的 Alex Polvi 宣布开放容器促进会(当时称为开放容器计划,Open Container Project)正式成立,目的是要发展出一套通用的容器格式与运行环境的标准。

同样是 2015 年 6 月,FreeBSD 项目宣布支持 Docker 利用 ZFS 和 Linux 兼容层来运行。2015 年 8 月,Docker 与微软推出专为 Windows server 开发的 Docker Engine“技术预览”版。

Docker 1.8 版本引入了“内容信任”(content trust)特性,能够核实 Docker 镜像的完整性和发布者身份。对于建立基于 Docker 仓库镜像的可信工作流程,“内容信任”是个很重要的构成部分。1.4 插件与基础设施

Docker 公司一直勇于承认它的成功有赖于生态系统。当 Docker 公司正全心全意地建造一个稳定且生产就绪的容器引擎时,其他公司(如 CoreOS、WeaveWorks 和 ClusterHQ)则在其他相关领域发展,譬如容器的服务编排和网络连接。但不久之后,显然 Docker 公司正在准备提供一套完整的开箱即用平台,其功能包括联网、储存以及服务编排。为了鼓励生态系统的持续发展,并确保用户能取得各式各样用例的解决方案,Docker 公司宣布将会为 Docker 建立一套模块化且可扩展的框架,原有的组件可以替换为第三方组件,或者加入第三方提供的扩展功能。Docker 公司称这一功能为“包含电池,却可更换”(Batteries Included, But Replaceable),意思是它会提供一套完整的方案,但其中部分可以随意更换。

撰写本书时,插件框架已经可用,但仍在起步阶段。目前已有数个插件用于通过网络来连接容器和数据管理。

另外,Docker 还遵守一份自己制订的宣言,称为“基础设施构建宣言”(Infrastructure Plumbing Manifesto)。该宣言承诺尽可能重用和改进现有的基础设施组件,并且在社区需要新工具的时候,将可以重复使用的组件回馈给社区。这促使用于运行容器的底层代码被拆分出来,成为 runC 项目,并由 OCI 监管,从而任何人都可以重复利用来搭建其他的容器平台。1.5 64位Linux

撰写本书时,64 位 Linux 是唯一一个能稳定运行 Docker 且适合用于生产环境的平台。这就意味着,你的计算机必须运行 64 位的 Linux 发行版,而所有的容器也必须是 64 位 Linux。如果你使用的是 Windows 或 Mac OS,你可以在虚拟机里运行 Docker。

其他平台,如 BSD、Solaris 及 Windows Server 的原生支持还处于开发中的不同阶段。由于 Docker 并非使用虚拟化技术,容器必须与主机的内核一致——Windows Server 的容器只能在 Windows Server 的主机上运行,64 位 Linux 的容器只能在 64 位 Linux 的主机上运行。

微服务和单一架构

微服务是容器最主要的用例,也是容器技术兴起的最大推动力。

微服务是一种软件系统开发和构成形式,由小而独立的组件组成,这些组件通过网络互相连接沟通。这与传统的单一架构(monolith)软件开发模式相反,后者只有一个庞大的程序,一般由 C++ 或 Java 实现。

当需要扩展一个单一架构的软件时,纵向扩展(scale up)往往是唯一选择,也就是说,需要把机器升级,增加内存和使用更强大的 CPU,才能应付更多的负载。相反,微服务则设计成横向扩展(scale out),为了满足增长的需求,只需部署多台机器摊分负载即可。微服务架构还可以针对系统中的瓶颈,只扩展某个特定服务所需的资源。但对于单一架构而言,要么扩展所有东西,要么不扩展,而这会造成资源浪费。

就系统复杂度而言,微服务是把双刃剑。每个单独的微服务都应该易于理解和修改,但是,在一个拥有几十到几百个这类服务的系统中,组件之间的交互会导致整体的复杂度增加。

容器与生俱来的轻量级特性及速度,意味着它尤其适合用于微服务架构。与虚拟机相比,容器的体积小很多,并且能快速部署,这使得微服务架构能使用最少的资源,又能迅速应对需求的变化。

更多关于微服务的信息,参见 Sam Newman 的著作《微服务设计》,以及 Martin Fowler 的“微服务资源指南”(Microservice Resource Guide,http://martinfowler.com/microservices/)。第2章安装

本章概述安装 Docker 的步骤。根据你所用的操作系统,安装时或许会遇到一些小问题;不过运气好的话,安装过程应该是简单和轻松的。如果你已安装 Docker 的最新版本(1.8 或之后),可以直接跳到下一章。2.1 在 Linux上安装Docker

目前为止,在 Linux 上安装 Docker 最好的方法就是使用 Docker 提供的安装脚本。虽然大部分主流 Linux 发行版都有自己的软件包,但很多时候这些软件包的版本都落后于 Docker 的发布版本。鉴于 Docker 开发的步伐较快,因此绝不能忽略这个问题的严重性。Docker 的系统要求

Docker 对系统并没有太多要求,不过你需要一个较新的内核(编写本书时是 3.10 或以上版本)。可以通过执行 uname -r 来检查你的内核版本。如果你使用的发行版是 RHEL 或 CentOS,便需要 7 或之后的版本。

还需要注意,系统架构必须是 64 位。系统架构可以通过执行 uname -m 查询,结果应为 x86_64。

你可以通过 https://get.docker.com 提供的脚本来自动安装 Docker。按照官方的说明,只需执行 curl -sSL | sh 或 wget -qO- | sh 就可以了,但建议在执行脚本前先检查一下它的内容,确保你接受它对你的系统所作的改动:$ curl https://get.docker.com > /tmp/install.sh$ cat /tmp/install.sh...$ chmod +x /tmp/install.sh$ /tmp/install.sh...

这个脚本会先做数个检查,然后用适合你的系统的包安装 Docker。如果它发现系统缺少了一些安全和文件系统功能所需要的依赖关系,还会把它们一并安装。

如果你完全不想使用安装程序,或者希望使用一个安装程序未提供的 Docker 版本,你也可以在 Docker 网站下载二进制文件。这样做的缺点是它不会检查依赖关系,并且以后需要手动安装更新。有关二进制文件的更多信息和下载链接,参见 Docker Binary 网页(https://docs.docker.com/engine/installation/binaries/)。已通过 Docker 1.8 验证

撰写本书时,Docker 的版本为 1.8。所有命令皆已通过该版本验证。2.1.1 将SELinux置于宽容模式下运行

如果你正在运行基于红帽的发行版,包括 RHEL、CentOS 和 Fedora,那么很有可能已经安装了 SELinux 安全模块。

刚开始使用 Docker 时,建议以宽容(permissive)模式运行 SELinux,这样 SELinux 将只把错误写进日志,而非强制执行。如果以强制(enforcing)模式运行 SELinux,那么很有可能在执行书中的范例时,会遇到各种莫名其妙的“权限不足”(Permission Denied)错误。

要查看你的 SELinux 处于什么模式,可以通过执行 sestatus 命令的结果得知。例如:$ sestatusSELinux status: enabledSELinuxfs mount: /sys/fs/selinuxSELinux root directory: /etc/selinuxLoaded policy name: targetedCurrent mode: enforcing ➊Mode from config file: error (Success)Policy MLS status: enabledPolicy deny_unknown status: allowedMax kernel policy version: 28

➊ 如果这里显示“enforcing”,代表 SELinux 已生效并会强制执行规则。

要将 SELinux 设为宽容模式,只需执行 sudo setenforce 0。

更多关于 SELinux 的信息,以及为什么在对 Docker 足够有把握后才应打开 SELinux,参见 13.9.1 节。2.1.2 不使用sudo命令执行Docker

因为 Docker 运行时需要特殊权限,所以默认执行命令时都必须在前面加上 sudo。但这样做确实使人厌烦,一个可行的解决方法是把用户放进 docker 用户组里。在 Ubuntu 下你可以输入:$ sudo usermod -aG docker $USER

如果 docker 用户组不存在,这个命令会创建它,并且把当前的用户添加到组里。然后,你需要先注销并再登入系统。其他 Linux 发行版的做法应该大同小异。

你还需要重启 Docker 服务,不同发行版的操作方法也不一样。Ubuntu 下的操作方法如下:$ sudo service docker restart

为简洁起见,书中所有关于 Docker 的命令都会把 sudo 省略。将用户加入 docker 用户组等同于赋予他 root 权限。因此,你应了解它所带来的安全隐患,如果你的机器是共享的,那么尤其要注意。更多这方面的信息,请参见 Docker security 网页(https://docs.docker.com/engine/security/security/)。2.2 在Mac OS及Windows上安装Docker

如果你使用的操作系统是 Windows 或 Mac OS,那么你需要某种虚拟化技术才能使用 Docker。你可以下载整套的虚拟机并按照 Linux 的说明来安装 Docker,或选择安装 Docker Toolbox 工具箱(https://www.docker.com/toolbox)。Docker Toolbox 包含一个极小的 boot2docker 虚拟机,以及本书中将会使用的一些 Docker 工具,例如 Compose 和 Swarm。如果使用 Homebrew 在 Mac 下安装应用,你会发现 boot2docker 的 brew recipe;不过一般我会建议使用官方的 Toolbox 来安装,以免遇到问题。

Toolbox 成功安装后,便可以打开 Docker 的 quickstart 终端使用 Docker。除此以外,也可以通过以下命令来配置当前的终端:$ docker-machine start defaultStarting VM...Started machines may have new IP addresses. You may need to rerun the`docker-machine env` command.$ eval $(docker-machine env default)

把你的环境设置妥当,然后就能够访问虚拟机里的 Docker Engine 了。

使用 Docker Toolbox 时务必注意以下事项。

本书的范例假设 Docker 运行在主机上。如果你使用 Docker Toolbox,这个假设就不成立了,你需要把提到 localhost 的地方一概换成虚拟机的 IP 地址。例如:$ curl localhost:5000

需要换成类似下面的例子:$ curl 192.168.59.103:5000

虚拟机的 IP 地址可以通过 docker-machine ip default 这个命令获得,因此我们还可以稍微做点自动化:$ curl $(docker-machine ip default):5000

本地操作系统与 Docker 容器之间的映射数据卷必须同时挂载于虚拟机上。Docker Toolbox 在一定程度上可以自动化这个工作,但如果在使用 Docker 数据卷时遇到问题,你得记住这一点。

如果你有任何特殊要求,可能需要修改虚拟机的配置,boot2docker 虚拟机里的 /var/lib/boot2docker/profile 文件包含各种不同设定,包括 Docker Engine 的配置。通过修改 /var/lib/boot2docker/bootlocal.sh 文件,你还可以使虚拟机初始化之后执行你自己的脚本。更多详情参见 boot2docker GitHub 仓库(https://github.com/boot2docker/boot2docker)。

如果你跟不上书中的例子,可以执行 docker-machine ssh default 来直接登入虚拟机,然后在虚拟机里执行范例的命令。Docker 的试验性版本

除了常用的稳定版本,Docker 还维护一个试验性版本(experimental build),它包含最新的为测试而设的功能。由于这些功能仍在讨论和开发阶段,在进入稳定版之前它们还有可能会大幅度更改。试验版应只用于正式发布前对新功能的研究,绝不能用于真正的使用环境。

Linux 下可以用这个脚本来安装试验版:$ curl -sSL https://experimental.docker.com/ | sh

你也可以从 Docker 网站下载二进制文件。请注意,试验版每天晚上都会更新,网站提供验证码以便确认下载文件是否正确。2.3 快速确认

可以通过执行 docker version 命令得知一切是否已正确安装并且可用。你应该会看到类似下面的输出结果:$ docker versionClient: Version: 1.8.1 API version: 1.20 Go version: go1.4.2 Git commit: d12ea79 Built: Thu Aug 13 02:35:49 UTC 2015 OS/Arch: linux/amd64Server: Version: 1.8.1 API version: 1.20 Go version: go1.4.2 Git commit: d12ea79 Built: Thu Aug 13 02:35:49 UTC 2015 OS/Arch: linux/amd64

如果结果相符,这代表你已经准备就绪,可以进入下一章了。但如果你的结果像下面这样:$ docker versionClient: Version: 1.8.1 API version: 1.20 Go version: go1.4.2 Git commit: d12ea79 Built: Thu Aug 13 02:35:49 UTC 2015 OS/Arch: linux/amd64Get http:///var/run/docker.sock/v1.20/version: dial unix /var/run/docker.sock:no such file or directory.* Are you trying to connect to a TLS-enabled daemon without TLS?* Is your docker daemon up and running?

这代表 Docker 守护进程并未运行(或客户端无法访问它)。要查出问题所在,可以先执行 sudo docker daemon 来手动启动 Docker 守护进程。它或许能给出一些信息,指出哪一部分出错,而那些信息也有助于搜寻答案。(请注意,这个建议只适用于 Linux 主机。如果你使用的是 Docker Toolbox 或类似的工具,请求助于相关文档。)第3章迈出第一步

在这一章你将迈出使用 Docker 的第一步。本章先从启动和使用一些简单的容器开始,感受一下 Docker 是如何工作的;然后探讨 Dockerfile——构建 Docker 容器的基石,以及为发布容器提供支持的 Docker Registries(寄存服务),最后讲解怎样通过容器利用持久化存储来托管一个键值存储(key-value store)。3.1 运行第一个镜像

尝试执行下述命令,测试 Docker 的安装是否正确。$ docker run debian echo "Hello World"

运行这个命令需要花点时间,实际所需时间依网络速度而定,但最终你应看到类似下面的结果。Unable to find image 'debian' locallydebian:latest: The image you are pulling has been verified511136ea3c5a: Pull complete638fd9704285: Pull complete61f7f4f722fb: Pull completeStatus: Downloaded newer image for debian:latestHello World

究竟发生了什么?刚才我们调用了 docker run 命令,它的功能是负责启动容器。其中的 debian 参数是我们打算使用的镜像名称,这里所指的是一个被精简过的 Debian Linux发行版。输出结果的第一行告诉我们本地没有 Debian 镜像。Docker 便会在 Docker Hub 进行在线搜索,并下载 Debian 最新版本的镜像。镜像下载后,Docker 会将它转成容器并运行,然后在容器中执行我们指定的命令——echo "Hello World"。命令的结果则显示在输出内容的最后一行。

如果再次执行同一命令,那就无需再下载镜像了,容器会立即启动。而整个命令的运行时间大概只需一秒,要是想象一下它背后所做的一切事情,就会觉得这个速度十分惊人: Docker 部署并启动了我们的容器,执行我们指定的 echo 命令,最后把容器关掉。类似的工作如果用传统的虚拟机执行,所需时间将会是好几秒,甚至是好几分钟。

我们可以用以下命令,请求 Docker 提供一个容器中的 shell。$ docker run -i -t debian /bin/bashroot@622ac5689680:/# echo "Hello from Container-land!"Hello from Container-land!root@622ac5689680:/# exitexit

这样你就可以进入容器中的命令行了,和使用 ssh 进入远程机器很相似。当中的 -i 和 -t 参数表示我们想要一个附有 tty 的交互会话(interactive session),/bin/bash 参数表示你想获得一个 bash shell。当你退出 shell 时,容器就会停止——主进程运行多久,容器就运行多久。3.2 基本命令

为了进一步了解 Docker,我们可以启动一个容器,执行不同命令和行动,并观察容器会作出什么反应。首先,启动一个新的容器,不过这次用 -h 参数来设定一个新的主机名(hostname)。$ docker run -h CONTAINER -i -t debian /bin/bashroot@CONTAINER:/#

如果故意把容器弄坏会怎样呢?root@CONTAINER:/# mv /bin /basketroot@CONTAINER:/# lsbash: ls: command not found

我们移动了 /bin 目录的位置,现在这个容器已经没用了,至少暂时是这样的。在删掉这个容器之前,先来看看 ps、inspect 和 diff 会显示什么结果。现在,打开一个新的终端(同时保持原来的容器运行),并在主机执行 docker ps。运行结果如下:CONTAINER ID IMAGE COMMAND ... NAMES00723499fdbf debian "/bin/bash" ... stupefied_turing

上面的内容告诉我们目前运行中的容器的一些详细信息。其中大部分信息应无需多作解释,不过,有一点要特别注意,那就是 Docker 为容器起了一个容易看懂的名称,这里叫作“stupefied_turing”,在本机上可以用它来识别这个容器。我们可以把容器的名称或 ID 作为 docker inspect 命令的参数,来获取更多有关某个容器的信息:$ docker inspect stupefied_turing[{ "Id":"00723499fdbfe55c14565dc53d61452519deac72e18a8a6fd7b371ccb75f1d91", "Created": "2015-09-14T09:47:20.2064793Z", "Path": "/bin/bash", "Args": [], "State": { "Running": true,...

这里有很多有用的信息,但却不太容易读懂。我们可以用 grep 或 --format 参数(需要一个 Go 模板)来过滤感兴趣的信息。例如:$ docker inspect stupefied_turing | grep IPAddress "IPAddress": "172.17.0.4", "SecondaryIPAddresses": null,$ docker inspect ––format {{.NetworkSettings.IPAddress}} stupefied_turing172.17.0.4

这两行命令都能找出容器的 IP 地址。现在来看看另一个命令,docker diff:$ docker diff stupefied_turingC /.wh..wh.plnkA /.wh..wh.plnk/101.715484D /binA /basketA /basket/bashA /basket/catA /basket/chaclA /basket/chgrpA /basket/chmod...

可以看到,在这个运行中的容器内,有哪些文件被改动过;而这个例子中,被删除的文件有 /bin,有新增的 /basket 以及它底下的文件,还有一些存储驱动的相关文件。Docker 容器使用联合文件系统(union file system,UFS),它允许多个文件系统以层级方式挂载,并表现为一个单一的文件系统。镜像的文件系统以只读方式挂载,任何对运行中容器的改变则只会发生在它之上的可读写层。因此,Docker 只需查看最上面的可读写层,便可找出曾对运行系统所作的所有改变。

关于这个容器的实验即将结束,最后要为大家介绍的是 docker logs。以容器名称作为它的参数,就能得知这个容器里曾经发生过的一切事情:$ docker logs stupefied_turingroot@CONTRAINER:/# mv /bin /basketroot@CONTRAINER:/# lsbash: ls: command not found

现在,对这个坏掉了的容器的实验到此结束,是时候把它删掉了。首先,从 shell 退出:root@CONTRAINER:/# exitexit$

由于 shell 是唯一一个在容器中运行的进程,容器也会同时停止。这时候如果执行 docker ps,你会发现已经没有任何正在运行的容器了。

不过,这并非事实的全部。如果键入 docker ps -a,它会列出所有容器,包括已经停止的容器(官方说法是“已退出容器”,exited container)。已退出的容器可以用 docker start 重启(因为我们已经把之前那个容器的路径弄坏了,所以它已无法重启)。要把容器删掉,需要使用 docker rm 命令:$ docker rm stupefied_turingstupefied_turing清理已停止的容器

如果想删除所有已停止的容器,可以利用 docker ps -aq -f status=exited 的结果,结果中包含所有已停止容器的 ID。例如:$ docker rm -v $(docker ps -aq -f status=exited)

这个命令很常用,因此你可以考虑把它写成一个 shell 脚本或定义为 alias。请注意 -v 参数在这里的作用,它意味着当所有由 Docker 管理的数据卷已经没有和任何容器关联时,都会一律删除。

为了避免已停止的容器的数量不断增加,可以在执行 docker run 的时候加上 --rm 参数,它的作用是当容器退出时,容器和相关的文件系统会被一并删掉。

好了,现在来看怎样创建一个全新且具有实用价值的容器,一个我们会真正保留下来的容器。我们打算将一个名为 cowsay 的应用“Docker 化”。如果你不知道什么是 cowsay 的话,待会儿别被吓倒了。首先启动一个容器,并安装一些包:$ docker run -it --name cowsay --hostname cowsay debian bashroot@cowsay:/# apt-get update...Reading package lists... Doneroot@cowsay:/# apt-get install -y cowsay fortune...root@cowsay:/#

现在就来试一试吧!

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载