Docker开发实践(txt+pdf+epub+mobi电子书下载)


发布时间:2020-05-29 17:11:42

点击下载

作者:曾金龙

出版社:人民邮电出版社

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

Docker开发实践

Docker开发实践试读:

前言

Docker从提出到现在已经走过了两年的时间,在这两年里,它一直都是云计算领域的热点。可以说,它是2014年互联网最热门的技术。Docker得到Google、微软、IBM、Red Hat的声援,而它也不负众望,在这短短的两年里快速迭代,一步步变得更加完善。在Docker之前,开发者都深陷软件环境的配置之苦,虽然说并不是所有的软件配置都很难,但不同环境下的配置问题却层出不穷,相信很多读者和我有类似的经历,就是想用一款开源软件,结果配置了许久都跑不起来,然后不得不放弃用它。而网上总是有很多的答疑,可是跟着照做,发现在自己的机器上就是跑不起来。环境差异,可能会让原本简单的问题复杂化,迟滞我们的开发进程。拿来主义对于懒惰的程序员来说是件好事,我们都希望拿来就用,这样就可以专注于我们本该干的活。对于测试人员和运维人员来说,也是如此,没人喜欢处理这些本不该重点关注、处理不好却会让人寸步难行的问题。Docker就像一个打包器,可以把你的应用及其环境整体打包,然后很方便地迁移到不同的平台,到处运行。在用户看来就如同运行在原来的机器上一样。或许该有人说我用虚拟机也可以实现同样的效果,为什么要选择Docker。当两样东西都能够做同一件事情时,我们比的是效率。你可以在一台服务器上部署几个或者十几个虚拟机实例,但我相信没人会在一台服务器上部署上百个虚拟机实例,这是因为资源的限制。而在一台服务器上部署上百个Docker容器却并不是什么难事。在镜像的传输和共享方面,Docker也做得非常好,它能够只传输那些改变了的数据,而不用像传输虚拟机镜像那样,动辄至少几百兆。在共享方面,Docker建立了Docker Hub,你可以根据已有的镜像定制自己的镜像,而无需每次都再造轮子。如此接地气的技术,怪不得业内都惊呼Docker是下一个Hadoop。本书的起源

虽然Docker人气旺盛,但关于Docker的书却少之又少,更别说汗牛充栋了,这主要是Docker出现的时间尚短。对于已有的书,基础内容不够体系,大多只停留寥寥几个基础命令的展示,并没有很好地归纳整理;而高级篇又只停留于粗浅的概念介绍,毫无实践价值,特别是对Docker具有很大作用的管理工具,例如Fig、Kubernetes、shipyard等内容,没有一本书去系统讲解它们。我们觉得这么好的技术,应该有更为系统的书去让更多的人了解它,理解它,这正是本书存在的价值。

如果不是遇到了王军花编辑,或许就没有本书,而正是在她的鼓励下,才让我们有勇气去将一些原本零碎的知识归纳整理为一本完整的书。本书内容

本书主要介绍了Docker的实践之道。我们按照由浅入深的编排将本书分为三篇。在基础篇,主要是让读者认识Docker的概念和基础操作,对比介绍了Docker和虚拟机等技术,从容器、镜像、数据卷以及容器的连接等方面说明Docker的操作。通过对基础篇的学习,读者不仅对Docker有了全局的认识,而且能够对Docker的基础操作得心应手。该篇包含第1章至第4章的内容。● 第1章从概念上介绍了Docker,让读者对它的概念、背景、

组件以及相关技术有了全局的认识。● 第2章和第3章分别介绍了容器和镜像的相关操作,二者是

Docker操作的核心对象。● 第4章介绍了容器的网络基础、数据卷的配置以及多个容器

之间的互联。

第二篇是案例篇。在这一篇中,我们通过不同类型的应用来说明Docker的实际应用。我们不做案例的简单堆砌,而是通过不同类型的案例来说明各个知识点的应用,它包含第5章至第11章。● 第5章介绍了如何创建SSH服务镜像,这满足了日常SSH远

程登录的需求。● 第6章构建了一个采用Apache作为Web服务器、PHP作为

Web开发语言、MySQL作为数据库的Web应用案例。● 第7章构建了一个采用Node.js作为开发语言、MongoDB作为

数据库的Web案例,该案例着重说明了跨主机的多容器代理互

联。● 第8章和第9章说明了如何在公共云平台——阿里云上部署

Docker应用,这里以WordPress为例进行介绍。● 第10章介绍了如何使用私有仓库。● 第11章将云计算的两大热点联合,说明了如何通过Docker

来构建Hadoop镜像及集群。

第三篇是高级篇。在这一篇中,对Docker的API以及管理工具Fig、Kubernetes、shipyard以及Docker三件套(Machine+Swarm+Compose)都有实践操作,该篇包含第12章至第18章。● 第12章介绍的是容器的高级网络知识。● 第13章从命名空间、cgroups、Linux能力机制以及服务端防

护等方面入手介绍了安全方面的知识。● 第14章则是通过curl工具来学习Docker的API接口,并给出

docker-py库的编程实例。● 在第15章至第18章中,我们分别介绍了Fig、Kubernetes、

shipyard以及Machine+Swarm+ Compose三件套,这些都是为了

更好地管理和使用Docker的工具。

第四篇为附录。在附录A中,我们按照系统镜像、数据库镜像、Web镜像、语言镜像的类别来编排,列举了常见的镜像,以供读者查阅。附录B是Docker API列表的归纳整理,分为容器相关和镜像相关,亦是为了方便读者查阅。附录C是我们在写作过程中所用到的资料引用。阅读须知

阅读本书时,最好能够从前往后依序阅读。特别是基础篇,是理解案例篇和高级篇的基石,读者最好能够读完基础篇,再阅读案例篇和高级篇。在案例篇和高级篇中,章和章之间的联系并没有那么紧密,例如第6章的案例和第7章的案例并没有关联,它们属于侧重点不同的案例,所以无需依序阅读。高级篇的工具也是如此,读者可以根据需求的迫切程度而选择性阅读。目标读者

一切想了解及深入理解Docker技术的人,都是本书的目标读者。对于初级读者,通过本书的基础篇,你就可以成为一个能够灵活应用Docker的人。当你对Docker有一定了解后,通过学习案例篇和高级篇,你也就可以登堂入室了。致谢

本书是很多人共同劳动的成果。三位作者要感谢一些人,感谢他们为本书所作出的巨大贡献和支持。

感谢在迅雷的同事:特别感谢甘南南和潘向荣两位的工作支持和悉心指导,感谢他们的慷慨大方,提供给我们充足的时间来写作本书。此外,还需感谢的同事有涂海涛、李明良、吴小强、易萌萌、何赞裕、吴建国和何锐,感谢他们在成书过程中的宝贵意见。

特别感谢本书的编辑王军花,没有她,本书就只能停留在笔者的脑海里。她不仅仅是一位资深的计算机类图书编辑,更像一名计算机专家,本书很多内容都是在她的指点下得以完善。

本书还需致谢的人有:盛建强博士、高怀恩博士、广发证券信息部的刘润佳和周英贵、美团网的蒋朋、百度的徐则水和罗剑波、腾讯的杨晓颖和郑克松、阿里巴巴的田晓娇以及李海龙、邱俊凌、杨文武、刘汇洋、冯学汉等人。感谢他们让各自公司相关平台成为本书部分案例的尝鲜者,并提出了诸多宝贵意见。

最后,感谢我们的家人。没有你们的支持,就没有这一切。

 —— 第一篇 ——基础篇:Docker 基础第 1 章Docker简介

从虚拟机到容器,再到现在Docker的出现,虚拟化技术越来越受到互联网业界的关注和看好。在本章中,我们简要介绍一下Docker,其中主要包括以下内容。

Docker简介,其中包括Docker的概念、产生的背景、两个比Docker更早的虚拟化技术(虚拟机和容器)及其异同、Docker相对于一般容器的改进和优点以及Docker的应用场景。● Docker的架构和组件。Docker是一种C/S架构的容器引擎,

包含镜像、容器和库这3个重要概念。● Docker的相关技术,主要从隔离性、可度量性、移植性和安

全性这4个方面讨论。● Docker的安装,其中包含各种Linux变种系统上的安装以及

通过虚拟工具在Windows和OS X上的安装。1.1 Docker简介

在互联网初期,几乎所有的应用都以协议栈堆叠的形式进行开发,并且部署到单一的专有服务器上。如图1-1所示,15年前的应用又笨又重,而当时的终端设备也非常笨重,应用是基于一系列良好定义的协议栈进行开发的,它们包含中间件、运行时环境和操作系统;硬件所在的硬件环境也完全一致,即为一个服务配置单一的专有服务器,也就是说脱离了它原本的环境,整套系统或许就不能正常工作。随着互联网的发展,这种模式越来越不能满足日益复杂的互联网环境和产品需求。今天,应用开发者可以通过组合不同的服务来构建和装配应用,并使得应用能够跨越不同的硬件环境,如公共的、私有的以及虚拟的云服务器。图 1-1 互联网应用的演变

做到既能够组合当前最佳服务又跨越多种运行环境并非容易的事情。图1-2展示了当前一个网络应用可能涉及的方方面面,在软件层面,它的前台可能采用Nginx 1.5+ModSecurity+ OpenSSL+Bootstrap 2来构建,后台采用Python 3.0等来构建,而在API端可能采用Python 2.7,数据库方面可能有多种数据库存在,每一项都是拿现存已有的服务,进而装配出应用。在硬件层面,它面对的环境错综复杂,可能是在虚拟机上部署,也可能在公共云、开发者的个人电脑、测试服务器以及产品集群等上部署。当一个应用拥有复杂的软件依赖关系和多样的硬件运行环境时,有以下几个问题必须面对。图 1-2 应用的软件依赖和硬件运行环境的复杂性● 是否能够处理应用依赖的多样性和依赖库之间的不良反应?● 是否能够适应硬件环境的多样性?● 服务和应用之间的交互是否合理?● 是否可以在多个平台之间快捷移动?

想象一下将图1-2所示的各项应用和服务部署到各种硬件环境中的组合,每一个服务都有可能被部署在硬件环境中的一种甚至是多种。这些服务和运行环境的组合是一个可怕的矩阵,每一个服务都需要考虑它将来可能会在多种运行环境下运行。而不同环境对服务的配置也不尽相同,一个环节出错都将给工程进度带来不可预知的迟滞。这给应用的开发人员带来非常大的麻烦,他们可能因此而陷入这些琐碎的事物之中。

有没有一种方法或是一样东西,能够让开发者一次性解决上面的所有问题呢?有,当然存在!那它是什么呢?在揭开谜底之前,我们先卖个关子。

如图1-3所示,20世纪60年代以前的海运,大多数散货通过船进行托运,托运人和承运商都担心货物放置在一起会发生挤压、受损等不良现象,例如一批咖啡豆和钢琴放在了一起,或是一批钢材和香蕉压在了一起等。而且,不同的运输方式之间转运也非常麻烦,港口的码头需要装卸各式各样的货物,其效率低下,而且转运到火车汽车的时候也得面临这个问题。不同货物和不同交通工具之间的组合也是一个巨大的二维矩阵,你会发现这个传统行业的问题和我们刚才遇到的问题是如此的一样!海运界最后在美国海陆运输公司的推动下,制定了国际标准集装箱来解决这个棘手的问题。图 1-3 1960年前的货运

如图1-4所示,所有的货物都可以通过集装箱指定的方式打包进集装箱内部,货物之间的相互影响被集装箱隔绝。集装箱是一个货物集对外的标准接口,无论是海运码头还是汽运,处理的都是标准统一的集装箱,一个标准让货物在多种运输方式下畅通无阻,这极大地加快了货物的装卸、堆积和运输速度,提高了运输的安全性,降低了运输成本。集装箱出现后,得到了大规模的推广,也进一步促进了大宗贸易的全球化。现在,集装箱的货运量已经占到了全球贸易的90%以上,每年大约有5000多艘货轮运送着2亿个集装箱。图 1-4 标准集装箱的出现解决了运输方面的难题

回到主题,在软件应用开发中,我们期待有一种东西,它能够像集装箱一样方便地打包应用程序,隔离它们之间的不良影响,使应用能够在各种运行环境下运行并且在平台之间易于移植。Docker,正是这个集装箱。在Docker出现之前,类似的技术已经存在,例如虚拟机和容器,然而它们能够解决前面4个问题里面的其中某些,却不能解决所有,这也正是它与众不同和受到热捧的重要原因。接下来,我们进入Docker的主题。1.1.1 Docker的概念

什么是Docker?

Docker是一个开源平台,它包含容器引擎和Docker Hub注册服务器。● Docker容器引擎:该引擎可以让开发者打包他们的应用和依

赖包到一个可移植的容器中,然后将其发布到任何流行的Linux

机器上。● Docker Hub注册服务器:用户可以在该服务器上创建自己的

镜像库来存储、管理和分享镜像。利用Docker,可实现软件的一

次配置、处处运行。

Docker是PaaS提供商dotCloud开源的一个基于LXC的高级容器引擎,其源代码托管在GitHub上,它基于Go语言并遵从Apache 2.0协议。Docker自2013年诞生以来,就受到业内的高度关注,从RedHat在RHEL 6.5中集成对Docker的支持,到Google的计算引擎支持Docker在其之上运行,再到国内百度的App引擎也是基于Docker部署的,以及越来越多的软件采用Docker部署。可以说,在云计算的背景下,Docker正带来一场软件开发的革命。由于Docker的影响越来越大,dotCloud公司也更名为Docker公司。随着Docker越来越成熟,它后面采用了自己的libContainer来替换LXC。1.1.2 Docker的背景

前面提到,软件开发者急需一种像集装箱一样的容器来装配运输软件应用。而在云计算兴起后,服务和运行平台越来越多样,这种需求变得更加迫切。云计算兴起后,软件开发更趋向于组件组装,选取最合适的服务集合装配到一起构建出最终的产品,并将应用部署到各类云平台之上。云计算平台对硬件进行抽象和虚拟,按量提供给开发者,使得开发者从硬件管理问题中解脱出来,典型的云计算平台有亚马逊的AWS、国内的阿里云等。在云计算时代,硬件的部署和管理问题已经得到了很好的解决,然而软件的依赖、部署和管理问题依然存在,这主要体现在以下几个方面。● 环境管理复杂。从操作系统到各种依赖库,再到真正的应用

程序,开发者要关心整个环境中的每一个环节。有些开发环境特

别复杂,搭建过程漫长而且容易出错,而当需要将这种开发环境

部署到测试系统和产品环境中时,所有的配置可能需要重新配

置。不同的服务并存可能还会导致不良的影响,由于组件之间存

在复杂的依赖关系,组件的版本升级也非常烦琐,甚至面临升级

失败。事实上,开发者最希望的是专注于自己的业务逻辑,而不

用在基础环境上耗费太多时间。如果基础环境可以直接拿来用,

而不是每次都重新发明轮子,那将极大地减轻开发者的负担,毕

竟站在巨人的肩膀上才可以看得更远。因此,我们需要从繁杂的

管理细节中解脱出来。● 更为轻便的虚拟化需求。云计算时代采用标配硬件来降低成

本,采用虚拟机的虚拟化手段来满足用户的按量分配和隔离性要

求。然而无论是KVM还是Xen,这些虚拟化软件技术都显得冗余

并且浪费资源。用户希望自己在云平台上花的每一分钱都能够用

在刀刃上,而不是将大部分钱耗费在一个个的操作系统和一些公

共库上面。所以,在云计算平台上,用户希望出现一个比虚拟机

更为轻便的虚拟手段。● 移植性的需求。容器是一种比虚拟机更为轻便的虚拟技术,

例如LXC。Docker本身也属于容器的一种。容器可以解决资源浪

费问题,然而在Docker出现之前的容器,并不是为云计算环境设

计的,在可移植性方面做得不好,而且难于配置。用户希望自己

的容器可以部署到尽可能多的平台上去,而又不用关心平台差

异。显然,传统的容器都不能胜任。

新的需求驱动新的技术,Docker为问题而生,作为一个变革者,做了这个众人期待的“集装箱”。如图1-5所示,Docker把运行环境比作海运,把操作系统比作货船,而把Docker容器比作集装箱。Docker容器也就是软件的集装箱,Docker以一套标准的方法让用户可以构建自己的容器,然后容器易于在各大平台移植和运行,Docker对应用也提供了良好的隔离性。Docker容器采用组件的方式构建,用户可以像堆积木一样,基于现有的容器来增加自己的应用,从而构建出自己的容器,Docker的增量式更改减少了容器的冗余,使得Docker容器易于修改和传输。图 1-5 Docker是一个软件应用的集装箱

Docker是如何做了这个变革者的呢?下面我们通过容器和虚拟机的对比说明一下。1.1.3 容器与虚拟机

Docker是容器的一种,容器是一种轻量级的虚拟技术,和容器对应的更为重量级的虚拟技术是虚拟机。提及虚拟机,大家肯定都不陌生,例如VMware、VirtualBox、Virtual PC这些耳熟能详的产品早已深入人心。虚拟机是一种基于硬件的虚拟技术,它采用指令级的虚拟,完全虚拟一整套物理主机,包含CPU、内存、磁盘、网卡等硬件设备,给用户呈现的就是一个物理主机的特性。用户可以在虚拟机里面安装各种各样的操作系统,例如Windows、Linux或者是OS X,一切操作都看起来和真机一样。如图1-6a所示,用户可以在一台主机上安装多个虚拟机,每一个实例都完整地包含硬件虚拟层、操作系统、公共库和应用等部件。然而,有时候这并不是我们想要的,因为这样太耗费资源,而且管理也并不方便。还是那句话,当新的需求出现后,自然会驱动新的技术出现,于是后来出现了一种更为轻量级的虚拟技术——容器。容器是一种基于操作系统的虚拟技术,它运行在操作系统之上的用户空间,所有的容器都共用一个系统内核,甚至是公共库,容器引擎提供进程级别的隔离,让每个容器都像运行在单独的系统之上,但又能够共享很多底层资源,如图1-6b所示。比起虚拟机,容器更为轻量、快速、易于管理。除了Docker,常见的容器还有Solaris Zones、BSD jails、OpenVZ和LXC等。图 1-6 虚拟机和Docker容器的对比

为了更详细地对比虚拟机和容器,我们把二者的异同点列在表1-1中。

表 1-1 容器与虚拟机的对比 容器虚拟机• 都可在不同的主机之间相迁移 同• 都具备root权限点• 都可以远程控制• 都有备份、回滚操作操在性能上有优势,能够作可以安装任何系统,性能不及轻易地同时运行多个操作系系容器统统和宿主主机共享内核,所有容器运行在容器引擎之每一个虚拟机都建立在虚拟的原上,容器并不是一个完整的硬件之上,提供指令级的虚拟,具理操作系统,所有的容器共享备一个完整的操作系统操作系统,在进程级进行隔离对操作系统具有绝对的权限,更为高效、集中。一个对系统版本和升级具有完全管理权硬件节点可以运行数以百计限。具有一整套的资源:CPU、优的容器,非常节省资源。RAM和磁盘。QoS是有保证的。每点QoS会尽量满足,但不保证一个虚拟机像一个真实的物理机一一定满足。内核由提供者升样,可以实现不同的操作系统同时级,服务由服务提供者管理运行在同一物理节点上弹性的资源分配:资源资虚拟机需要重启,虚拟机里面可以在没有关闭容器的情况源的操作系统需要处理新加入的资下添加,数据卷也无需重新管源。例如,添加一块磁盘,则需要分配大小(有些服务的容器理重新分区等需要重启)远根据操作系统的不同,远程控制由虚拟化平台提供,程会通过shell或者远程桌面进可以在虚拟机启动之前连接。所以管行。前提是容器内的操作系可以安装系统理统已经启动对内核没有控制权限,只有容器的提供者具备升级每一台虚拟机具有更大的负权限。只有一个内核运行在缺载,耗费更多的资源,用户需要全物理节点上,几乎不能实现点权维护和管理。一台物理机上能够不同的操作系统混合。容器运行的虚拟机也非常有限提供者一般仅提供少数的几款操作系统配置时间长,从几分钟到几个配快速,秒级即可准备小时,具体取决于操作系统。需要置好。由容器提供者处理自行安装操作系统启动秒级分钟级时间硬盘MBGB使用性接近原生态弱于原生态能系统支单机支持上千个容器一般不多于几十个持量1.1.4 Docker与容器

容器和虚拟机各有各的优缺点,容器也并不是虚拟机的替代品,只是二者在适应不同的需求下各有优点。容器相对于虚拟机的优势在于效率更高,资源占用更小,管理更为便捷。在需要部署的系统都是同一系列的操作系统时,这种性能和便捷性上的优势非常明显。然而就容器本身而言,依然有很多问题需要解决,例如在灵活性、安全性以及配置共享方面都存在不足。我们以Docker早期基于的LXC容器为例,说明Docker对容器进行的改进和优化,其中很多方面是LXC这类容器所没有的新特性。● 跨平台的可移植性。Docker定义了一种统一标准的打包格式,

将应用及其依赖打包进单个的镜像中,该镜像可以在任何Docker

可运行的机器之间便捷传输,并且在不同机器上,Docker隔离了

应用和平台的直接联系,对配置进行了抽象,使得在任何平台上

应用的运行环境都一样。LXC的配置却不是可移植的,它依赖于

某台具体的机器,例如机器的网络、存储、日志、磁盘等配置,

同一配置在不同机器上并不能够通用,这极大地限制了它的可移

植性。● 面向应用。Docker是为优化应用部署而诞生的,LXC则是面

向机器的,这是二者设计哲学上的不同。Docker面向应用的哲学

体现在API、用户接口以及文档等各个方面,Docker都是为了更

简单地做事。而LXC则更关注于使用更少的CPU、更少的RAM,

成为一个更轻量的机器。● 版本控制。Docker的版本控制和git工具非常类似,Docker可

以跟踪一个容器的版本信息,查看版本差异,提交和回滚版本等。

所有的版本信息都将被记录,这样你可以清晰地看到一个应用服

务器的更改历史。● 组件复用。Docker容器以组件式搭建,你可以利用一个基础

镜像构建更多的应用容器。例如,你可以准备好一个Python的运

行环境作为基础镜像,然后以该镜像为基础,构建不同的Web应

用。你可以配置一个postgresql基础镜像,作为未来的数据库基

础组件。这些配置可以手动处理,也可以自动化完成。● 共享性。Docker拥有一个公共的注册服务器。成千上万的开

发者上传了他们的镜像,这些镜像涵盖软件的各个应用领域,我

们可以通过这些共享的镜像来进一步定制自己的镜像。在这些开

发者中,有一大批是官方组织提供的标准库,这些镜像安全、可

靠,有持续的维护和版本升级。而Docker的注册服务器本身也是

一个开源项目,所以任何人都可以下载源码后在自己的网络中部

署自己的注册服务器,以供特殊用途。● 工具生态系统。Docker提供了API以供自动化创建和部署容

器,而越来越多的工具加入到Docker之中来扩展它的能力,例如

PaaS部署工具Dokku、Deis、Flynn,集群管理工具maestro、

salt、mesos、openstack nova,可视化管理工具docker-ui、

openstack horizon、shipyard,配置管理工具chef、puppet,持续

集成工具jenkins、strider、travis等。Docker已经形成了自己的软

件工具生态圈,目前正在高速发展。随着Docker生态圈越来成熟,

Docker的能力将会越来越强。1.1.5 Docker的应用场景

Docker作为一款容器,并且比传统的容器具有那么多的改进和优点,那么我们可以拿它来做些什么?以下是几种典型的应用场景。● 加速本地开发。通过Docker能够快速搭建好开发和运行环境,

并且该环境可以直接传递给测试和产品部署。● 自动打包和部署应用。● 创建轻量、私有的PaaS环境。● 自动化测试和持续集成/部署。● 部署并扩展Web应用、数据库和后端服务器。● 创建安全沙盒。● 轻量级的桌面虚拟化。1.2 Docker的组件

Docker采用的是C/S架构,具体如图1-7所示。Docker客户端,即Docker可执行程序,可以通过命令行和API的形式与Docker守候程序进行通信,Docker守候程序提供Docker服务。图 1-7 Docker的C/S架构

Docker包含三大核心组件——镜像、容器和库。● 镜像:是一个只读的静态模板。它保存着容器需要的环境和

应用的执行代码,可以把镜像看成容器的代码,当代码运行起来

后就成了容器。镜像采用分层机制,每个镜像都是只读的,但是

可以将写数据的层通过联合文件系统附加在原有的镜像之上。这

种增量式修改使得镜像非常容易存储、传输和更新。本书将会涉

及镜像的获取和制作。● 容器:是一个运行时环境,它是一个镜像的运行状态,相对

于静态的镜像而言。容器是镜像执行的动态表现。用户可以在容

器中运行所想要的程序和服务,而容器就像一个集装箱,它并不

关心你运行的到底是什么程序,所有应用的运行方式都一样

——创建、开始、停止、重启和销毁;容器也不在乎你在什么

样的环境中运行它,可以在个人电脑、虚拟机、云服务器、各种

操作系统上运行。容器易于交互、便于传输、易移植、易扩展,

非常适合进行软件开发、软件测试以及软件产品的部署。● 库:Docker采用注册服务器来存储和共享用户的镜像,库是

某个特定用户存储镜像的目录。通常,一个用户可以建立多个库

来保存自己的镜像。从这里可以看出库是注册服务器的一部分,

一个个的库组成了一个注册服务器。注册服务器有公共的和私有

的,其中公共的如Docker官方的Docker Hub。注册一个账号,你

就可以在里面建立自己的镜像库。镜像库可以选择开放,也可以

选择私有,仅有被允许的组成员才可以访问。

图1-8是一个通过Docker进行应用开发和部署的案例流程,通过这张图可以很好地理解这3个概念。首先,在开发主机上构建容器A,构建方法既可以是手工构建,也可以通过Dockerfile自动构建。容器A的构建必须基于一个已有的基础镜像,并在它之上执行一系列操作。镜像A是容器的静态形式,容器是镜像的运行态。将容器A保存为镜像A,然后推送到Docker库中进行共享。这时候,在产品部署方面,另一端则可以通过在Docker库中搜索来获得镜像A,并将其拉取到本地,最后在产品集群中运行容器A,其中产品集群中一般会同时运行很多容器,例如容器B和容器C等,而这些容器互不影响,相互隔离。图 1-8 使用Docker进行开发和部署的流程

选择私有,仅有被允许的组成员才可以访问。

图1-8是一个通过Docker进行应用开发和部署的案例流程,通过这张图可以很好地理解这3个概念。首先,在开发主机上构建容器A,构建方法既可以是手工构建,也可以通过Dockerfile自动构建。容器A的构建必须基于一个已有的基础镜像,并在它之上执行一系列操作。镜像A是容器的静态形式,容器是镜像的运行态。将容器A保存为镜像A,然后推送到Docker库中进行共享。这时候,在产品部署方面,另一端则可以通过在Docker库中搜索来获得镜像A,并将其拉取到本地,最后在产品集群中运行容器A,其中产品集群中一般会同时运行很多容器,例如容器B和容器C等,而这些容器互不影响,相互隔离。图 1-8 使用Docker进行开发和部署的流程1.3 Docker的相关技术

Docker是利用容器来实现的一种轻量级的虚拟技术,从而在保证隔离性的同时达到节省资源的目的。Docker的可移植性也让其能够无缝地运行在各种平台上,方便改写和传输。理解Docker这种虚拟技术,可以从其隔离性、可度量性、移动性和安全性这4个方面来探讨。● 隔离性:Docker采用libcontainer作为默认容器,取代了之前

的LXC。libcontainer的隔离性主要是内核的命名空间来实现的,

具体有pid、net、ipc、mnt和uts等命名空间,它们将容器的进程、

网络、消息、文件系统和主机名进行隔离。● 可度量性:在虚拟机中,由于虚拟好了CPU、内存等硬件要

素,每个用户根据自己的需求选择硬件的配置,所用的资源可以

量化计算。在Docker中,主要通过cgroups(控制组)来控制资

源的度量和分配。● 移植性:在虚拟机中,为了更好地复制、重建和移动虚拟机,

采用了镜像和快照的方法。而像LXC这类容器,其迁移性非常差,

每部署一台计算机,都可能需要重新配置,所以不能实现快速的

大规模部署和更新。Docker利用AUFS来实现对容器的快速更新。

AUFS是一种支持将不同目录挂载到同一个虚拟文件系统下的文

件系统,支持对每个目录的读写权限管理。另外,AUFS具有层

的概念,每一次修改都是在已有的只写层进行增量修改,修改内

容将形成新的文件层,而不影响原有的层。采用AUFS作为

Docker容器的文件系统,能够提供如下好处。● 节省存储空间:多个容器可以共享同一个基础镜像存储。● 快速部署:当要部署多个来自同一个基础镜像的容器时,避免了多次复制操作。● 升级方便:升级一个基础镜像即可影像到所有基于它的容器。● 增量修改:可以在不改变基础镜像的同时修改其目录的文件,所有的更改都发生在最上层的写操作层,这大大增加了基础镜像的可共享内容。● 安全性:容器的安全性是一个比较大的话题,因为任何一个

环节都可以和安全相关。这可以分为容器内部之间的安全性,容

器与宿主主机之间的安全性,前者主要通过命名空间和cgroups

来实现。通过命名空间的隔离,可以保证容器中运行的进程不被

主机的进程和其他容器影响;通过cgroups的审计和限制,保证

容器对资源的管理和控制安全。内核能力机制的控制则可以防止

Docker非法入侵宿主主机。此外,还有一系列工具的组合来保证

Docker的安全性,例如GRSEC、TOMOYO和SELinux等。1.4 Docker的安装

Docker的安装非常容易。目前,Docker支持所有的Linux系列系统,如Ubuntu、RHEL、Debian等。通过Boot2Docker虚拟工具,在OS X和Windows下也能够运行Docker。

但目前而言,Docker的运行环境也有限制,具体如下。● 必须是在64位机器上运行,并且目前仅支持x86_64和

AMD64,32位系统暂时不支持。● 系统的Linux内核必须是3.8或者更新的,内核支持Device

Mapper、AUFS、VFS、btrfs等存储格式。● 内核必须支持cgroups和命名空间。

接下来,我们说明各个操作系统平台下Docker环境的安装。需要说明的是,本书从第2章开始,如不特别说明,默认都是在Ubuntu Trusty 14.04(LTS)(64位)系统下进行的操作。1.4.1 Ubuntu下的安装

Docker支持以下版本的Ubuntu系统:Ubuntu Trusty 14.04、Ubuntu Precise 12.04、Ubuntu Raring 13.04 和 Saucy 13.10。这里以Ubuntu Trusty 14.04(LTS)(64位)为例进行介绍。

Ubuntu Trusty的内核是3.13.0,在这个系统下安装时默认的Docker安装包是0.9.1。

首先,运行以下命令进行安装:$ sudo apt-get update$ sudo apt-get install docker.io

然后重启伪终端即可生效。

如果想安装最新的Docker,首先你需要确认你的apt是否支持https,如果不支持,则需通过如下命令进行安装:$sudo apt-get update$sudo apt-get install apt-transport-https

然后将Docker库的公钥加入到本地apt中:$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9

再将安装源加入到apt源中,并更新和安装:$ sudo sh -c "echo deb https://get.docker.com/ubuntu docker main\ > /etc/apt/sources.list.d/docker.list"$ sudo apt-get update$ sudo apt-get install lxc-docker

为了验证Docker是否安装成功,可以运行如下命令:$ sudo docker info1.4.2 Red Hat下的安装

红帽系列主要有红帽企业版 Linux 6、红帽企业版 Linux 7和Fedora。

1. 红帽企业版Linux 7(RHEL7)

红帽企业版Linux 7(RHEL7) 中已经默认加入了Docker,它位于附加频道中。安装Docker时,首先要启用附加频道,相关命令如下:$ sudo subscription-manager repos --enable=rhel-7-server-extras-rpms

然后进行安装,相关命令如下:$ sudo yum install docker

2. 红帽企业版Linux 6(RHEL6)

首先,你要保证自己的红帽是6.5以上的,内核版本在2.6.32-431以上。

在红帽企业版Linux 6和CentOS 6中,我们首先需要安装EPEL包库,而在Fedora上却不用。对于不同的平台,一些包的命名和版本也不尽相同。

安装EPEL的命令:$ sudo rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386 ? /epel-release-6-8.noarch.rpm

然后安装Docker:$ sudo yum -y install docker-io

3. Fedora上的安装

在Fedora 19上安装Docker的命令如下:$ sudo yum -y install docker-io

在Fedora 20上安装Docker的命令如下:$ sudo yum -y install docker

4. 在红帽系列中启动Docker后台

安装好之后,我们就可以启动Docker的后台服务了。

在RHEL 6和CentOS 6中,可以通过如下命令来启动:$ sudo service docker start

我们还可以让Docker服务开机启动:$ sudo service docker enable

在RHEL 7和Fedora系统中,则是:$ sudo systemctl start docker

开机启动是:$ sudo systemctl enable docker

我们可以通过如下命令来确认Docker是否已经安装成功:$ sudo docker infoContainers: 13Images: 22Storage Driver: aufsRoot Dir: /var/lib/docker/aufsDirs: 48Execution Driver: native-0.2Kernel Version: 3.13.0-24-genericOperating System: Ubuntu 14.04 LTSWARNING: No swap limit support1.4.3 OS X下的安装

因为Docker引擎采用的是Linux的内核和内核特性,如果需要在OS X上运行它,则需要一个虚拟机。Docker已经给我们提供了一种简洁方法,那就是利用Boot2Docker工具来安装虚拟机和配置Docker服务。这里的虚拟机指的是VirtualBox。

首先,可以去GitHub上下载最新的Boot2Docker。在编写这本书的时候,其最新版本是v1.3.2。

双击下载完的安装包,将会自动安装,如图1-9所示。安装的内容包含VirtualBox虚拟机、Docker和Boot2Docker管理工具。图 1-9 OS X系统下Boot2Docker的安装

安装完成之后,你可以在OS X的“应用”文件夹中找到Boot2Docker。直接双击来启动它,或者采用如下命令行的方式:$ boot2docker init$ boot2docker start$ $(boot2docker shellinit)

然后在终端可以验证Docker是否成功安装:$ docker infoContainers: 13Images: 22Storage Driver: aufs...

至此,OS X下的Docker就安装好了。1.4.4 Windows下的安装

在Windows系统下运行Docker也需要虚拟机,我们也一样借助Windows版本的Boot2Docker来安装。

首先,下载最新版本的Windows版的Boot2Docker,当前的最新版本为1.3.2,然后双击安装包安装即可,如图1-10所示。图 1-10 Windows下的Boot2Docker安装

如图1-11所示,运行该脚本,会提示你输入ssh密钥密码,最简单的处理办法是暂时不管它,直接按回车[Enter]即可。图 1-11 Windows下的Docker运行

 第 2 章容器

容器是一个打包了应用和服务的环境。它是一个轻量级的虚拟机,每一个容器都由一组特定的应用和必要的依赖库组成。容器作为一个软件应用的标准集装箱,它必然需要定义一组跟具体应用无关的标准接口。在这一章中,我们主要说明容器的常用标准操作,主要包含以下内容。● 容器的管理操作。包含容器的创建、查看、启动、终止、删

除。● 容器内的信息获取和指令执行。包含附加终端到后台容器,

查看容器日志和详细信息以及容器内执行指定的指令。● 容器的导入和导出。2.1 容器的管理操作

对于容器的常见命令(包括查看、创建、启动、终止和删除等),我们按照由浅到深、由必须到可选的顺序介绍。

要查看某条指令的详细帮助信息,可以访问 http://docs.docker.com/reference/,或者通过docker help命令。此外,我们也可以通过man pages查看(例如:man docker-run)。2.1.1 创建容器

创建容器有两个命令,一个是docker create,另一个是docker run。二者的区别在于前者创建的容器处于停止状态,而后者不仅创建了容器,而且启动了容器。

采用docker create创建一个停止状态的容器,具体如下:$ docker create ubuntu:14.04adedeb41185ad9ac096b8f1a7a3c2d3c2f0cf759643685d320ff656bd49b9d48$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES$ docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESadedeb41185a ubuntu:14.04 "/bin/bash" 27 seconds ago stupefied_brown

创建容器后,Docker会立刻返回容器的ID,例如adedeb…就是我们刚刚所创建容器的ID。ID可以唯一标识一个容器,每一个容器的ID都是独一无二的。docker ps命令用于查看正在运行的容器,我们没有看到任何运行的容器,docker ps –a则是查看所有容器,包含未启动的容器。可以看到,我们创建的容器已经存在。

想要让创建的容器立马进入运行态,可以使用docker run命令,该命令等同于用docker create创建容器后再使用docker start启动容器。使用docker run命令,可以创建两种类型的容器——后台型容器和交互型容器。● 交互型容器:运行在前台,通常会指定有交互的控制台,可

以给容器输入,也可以得到容器的输出。创建该容器的终端被关

闭,在容器内部使用exit命令或者调用了docker stop、docker kill

命令后,容器会变成停止状态。● 后台型容器:运行在后台,创建启动之后就与终端无关。即

便终端关闭了,该后台容器也依然存在,只有调用docker stop或

docker kill命令时才能够使容器变成停止状态。

下面我们创建一个交互型容器,相关代码如下:$ sudo docker run -i -t --name=inspect_shell ubuntu /bin/bashUnable to find image 'ubuntu' locallyPulling repository ubuntu86ce37374f40: Download complete511136ea3c5a: Download complete5bc37dc2dfba: Download complete61cb619d86bc: Download complete3f45ca85fedc: Download complete78e82ee876a2: Download completedc07507cef42: Download completeroot@761ef6d4b28f:/#

首先,告诉Docker要运行docker run命令。这个命令后面是命令行标志-i和-t,前者用于打开容器的标准输入(STDIN),后者告诉Docker为容器建立一个命令行终端。这两个标志为我们和容器提供了交互shell,是创建交互型容器的基本设置。后面的--name标志为容器指定了一个名字,这是一个可选项。当没有这个选项时,Docker会为我们取一个随机的名字。接下来,我们告诉Docker使用哪个镜像去创建容器,这里使用的是ubuntu。ubuntu镜像是一个基础镜像,我们可以使用基础镜像(例如ubuntu、fedora、debian、centos等)作为创建自己镜像的基础。这里我们只是用基础镜像来启动容器,没有添加任何东西。最后,告诉Docker要在容器里面执行命令/bin/bash。

命令本身我们理解了,那么在后台会发生些什么呢?创建容器的流程如图2-1所示,当我们运行docker run命令后,Docker在本地搜索我们指定的ubuntu镜像,如果没有找到,就会到公有仓库Docker Hub中继续搜索。如果在服务器上找到了需要的镜像,Docker就会下载这个镜像,并将其保存到本地。然后,Docker使用这个镜像创建一个新的容器并将其启动;容器的文件系统是在只读的镜像文件上增加一层可读写的文件层,这样可以保证镜像不变而只记录改变的数据,这对容器的共享和传输都非常有利。接着会配置容器的网络,Docker会为容器分配一个虚拟网络接口,并通过网桥的方式将该网络接口桥接到宿主主机上去,然后该虚拟网络接口分配一个IP地址。最后,Docker在新容器中运行指定的命令,例如我们的例子中是/bin/bash。容器创建成功后,会出现类似下面的提示符:root@761ef6d4b28f:/#图 2-1 docker run命令的内部流程

@前面的是我们在容器的登录用户root,后面的761ef6d4b28f是容器的主机名。可以使用ctrl+D或者exit命令退出该容器。容器停止并不代表容器销毁,其实容器还在,只是不再是运行态,可以通过docker ps –a命令查看到已存在的容器。

接下来,我们创建一个后台型容器。在实际的应用中,大多数容器都是后台型容器,因为服务器程序不可能因为创建容器的终端退出而退出。创建后台型容器需要使用-d参数,其创建命令如下:$ sudo docker run --name daemon_while -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"f40f1463221f6fdcd5ae26d223df10273b0a4831d8bf1db16d461f583ac0cfb6

你可能注意到了,上面的命令没有像前面的容器那样关联到一个shell,而是返回了一个容器ID后直接返回到了宿主主机的命令提示符。我们可以通过运行docker ps命令,查看新建的容器是否正在运行:$ sudo docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESf40f1463221f ubuntu:latest /bin/sh -c 'while tr 2 minutes ago Up 2 minutes daemon_while761ef6d4b28f ubuntu:latest /bin/bash 49 minutes ago Up 49 minutes inspect_shell

可以看到,有两个容器在运行,交互型的容器inspect_shell和后台型容器daemon_while。2.1.2 查看容器

在上一节中,我们经常使用docker ps命令来查看正在运行的容器。在这一节中,我们详细说明该命令的参数及输出结果的含义。

使用docker ps命令,可以查看当前运行的容器:$ sudo docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTSNAMESf40f1463221f ubuntu:latest /bin/sh -c 'while tr 16 minutes ago Up 16 minutesdaemon_while761ef6d4b28f ubuntu:latest /bin/bash About an hour ago Up About an hourinspect_shell

下面简要介绍一下该命令的输出中各列的含义。● CONTAINER ID:唯一标识容器的ID。它是一个64位的十六

进制数,对某个容器的操作可以通过它来标识操作目标。在不会

混淆的前提下,可以采用ID的前几位来标识该容器,而在显示的

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

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载