第一本Docker书

978-7-115-37733-3
作者: 【澳】James Turnbull
译者: 李兆海刘斌巨震
编辑: 杨海玲

图书目录:

详情

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

图书摘要

第一本Docker书

THE DOCKER BOOK

[澳]James Turnbull 著

李兆海 刘斌 巨震 译

人民邮电出版社

北京

图书在版编目(CIP)数据

第一本Docker书/(澳)特恩布尔(Turnbull,J.)著;李兆海,刘斌,巨震译.--北京:人民邮电出版社,2015.1

ISBN 978-7-115-37733-3

书名原文:The Docker book

Ⅰ.①第… Ⅱ.①特…②李…③刘…④巨… Ⅲ.①Linux操作系统—程序设计 Ⅳ.①TP316.89

中国版本图书馆CIP数据核字(2014)第288134号

版权声明

Simplified Chinese translation copyright © 2015

by Posts and Telecommunications Press

Published by arrangement with James Turnbull

内容提要

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

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

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

◆著 [澳]James Turnbull

译 李兆海 刘斌 巨震

责任编辑 杨海玲

责任印制 张佳莹 彭志环

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

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

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

北京艺辉印刷有限公司印刷

◆开本:800×1000 1/16

印张:15.75

字数:328千字  2015年1月第1版

印数:1-4000册  2015年1月北京第1次印刷

著作权合同登记号 图字:01-2014-6456号

定价:59.00元

读者服务热线:(010)81055410 印装质量热线:(010)81055316

反盗版热线:(010)81055315

对本书的赞誉

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

——毛文波,道里云CEO,

曾创建EMC中国实验室并担任首席科学家,曾参与创建HP中国实验室

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

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

——喻勇,Cloud Foundry社区创始人

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

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

——程显峰,MongoDB中文社区创始人,蓝海讯通COO

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

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

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

——肖德时,InfoQ《深入浅出Docker》专栏作者

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

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

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

——赵鹏,VisualOps 创始人

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

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

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

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

我们走在容器化的大道上

如果你是一位技术爱好者,时刻关心业界最新动态,那么最近一定没少听说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 与他人分享我们的镜像,与其他服务集成,进行开发流程的自动化。

● 开发工程师开发、提交代码到代码服务器(GitHub、BitBucket、Gitlab等)。

● 代码服务器通过webhook 调用CI/CD服务,如Codeship(没错,就是2014 年11月刚融资800万美元的那家初创公司)、Shippable、CircleCI或者自建Jenkins等。

● CI服务器下载最新代码,构建Docker镜像,并进行测试。

● 自动集成测试通过之后,就可以将之前构建的镜像推送到私有Registry。

● 运维使用新版的Docker镜像进行部署。

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

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中文社区和https://docker.cn的创始人,也是本书中文版翻译工作的发起人。此外还有人民邮电出版社的杨海玲等编辑老师,没有她们的认真校对和排版工作,这本书也不会以完美的形式展现在各位读者面前。

——刘斌

前言

本书面向的读者

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

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

注意

本书基于1.0.0或更高版本的Docker,该版本不向下兼容。而且,在生产环境中,我们也推荐使用1.0.0或更高版本。

致谢

● 感谢我的合伙人及好友Ruth Brown,感谢你迁就我进行本书的写作。

● 感谢Docker公司的团队,感谢你们开发出Docker,并在本书写作期间提供无私的帮助。

● 感谢#docker频道和Docker邮件列表里的朋友们,感谢你们在我遇到问题时为我答疑解惑。

● 感谢Royce Gilbert,感谢你不仅提供超赞的技术插图,还为本书英文版设计了封面。

● 感谢Abhinav Ajgaonkar,感谢你提供自己的Node.js和Express示例应用程序。

● 感谢本书的技术审校团队,你们让我时刻保持头脑清醒,并指出了书中的愚蠢错误。本书中有3张配图是由Docker公司提供的。

Docker™是Docker公司的注册商标。

技术审稿人团队

Scott Collier

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

除思考分布式构架之外,Scott 喜欢跑步、登山、露营,还喜欢陪妻子和三个孩子在得克萨斯州的奥斯汀享受烧烤。他的技术文章以及相关信息都发表在他的个人网站(http://colliernotes.com)上。

John Ferlito

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套件。读者可以在他的个人博客(http://inodes.org/blog)上查看他的文章。John拥有新南威尔士大学的工程学士荣誉学位(计算机科学类)。

Paul Nasrat

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

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

技术插图作家

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

校对者

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

排版约定

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

下面是代码块:

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

This is a code block

过长的代码行会换行。

代码及示例

读者可以在网站上获取本书的代码和示例程序[2] ,也可以获取代码和示例的Git库[3]

说明

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

勘误

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

版本

本书是《The Docker Book》一书v1.3.1 版的中文版。

注释

[1]. http://www.ng-newsletter.com/

[2]. http://www.dockerbook.com/code/index.html

[3]. https://github.com/jamtur01/dockerbook-code

[4]. https://learn.thoughtbot.com/products/1-backbone-js-on-rails

第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 就是为改变这一切而生。

1.1 Docker简介

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

注意

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

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

1.1.1 提供一个简单、轻量的建模方式

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

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

1.1.2 职责的逻辑分离

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

1.1.3 快速、高效的开发生命周期

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

1.1.4 鼓励使用面向服务的架构

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

注意

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

1.2 Docker组件

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

● Docker客户端和服务器;

● Docker镜像;

● Registry;

● Docker容器。

1.2.1 Docker客户端和服务器

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

1.2.2 Docker镜像

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

● 添加一个文件;

● 执行一个命令;

● 打开一个端口。

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

1.2.3 Registry

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可以受到防火墙的保护,将镜像保存在防火墙后面,以满足一些组织的特殊需求。

1.2.4 容器

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

总结起来,Docker容器就是:

● 一个镜像格式;

● 一系列标准的操作;

● 一个执行环境。

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

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

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

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

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

1.3 我们能用Docker做什么

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

● 加速本地开发和构建流程,使其更加高效、更加轻量化。本地开发人员可以构建、运行并分享Docker容器。容器可以在开发环境中构建,然后轻松地提交到测试环境中,并最终进入生产环境。

● 能够让独立服务或应用程序在不同的环境中,得到相同的运行结果。这一点在面向服务的架构和重度依赖微型服务的部署中尤其实用。

● 用Docker创建隔离的环境来进行测试。例如,用Jenkins CI这样的持续集成工具启动一个用于测试的容器。

● Docker可以让开发者先在本机上构建一个复杂的程序或架构来进行测试,而不是一开始就在生产环境部署、测试。

● 构建一个多用户的平台即服务(PaaS)基础设施。

● 为开发、测试提供一个轻量级的独立沙盒环境,或者将独立的沙盒环境用于技术教学,如Unix shell 的使用、编程语言教学。

● 提供软件即服务(SaaS)应用程序,如Memcached 即服务[8]

● 高性能、超大规模的宿主机部署。

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

1.4 Docker与配置管理

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

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

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

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

1.5 Docker的技术组件

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

一个原生的Linux容器格式,Docker中称为libcontainer,或者很流行的容器平台lxc[10] 。libcontainer格式现在是Docker容器的默认格式。

Linxu内核的命名空间(namespace)[11] ,用于隔离文件系统、进程和网络。

● 文件系统隔离:每个容器都有自己的root 文件系统。

● 进程隔离:每个容器都运行在自己的进程环境中。

● 网络隔离:容器间的虚拟网络接口和IP地址都是分开的。

● 资源隔离和分组:使用cgroups[12] (即control group,Linux 的内核特性之一)将CPU和内存之类的资源独立分配给每个Docker容器。

● 写时复制[13] :文件系统都是通过写时复制创建的,这就意味着文件系统是分层的、快速的,而且占用的磁盘空间更小。

● 日志:容器产生的STDOUT、STDERR 和STDIN这些IO流都会被收集并记入日志,用来进行日志分析和故障排错。

● 交互式shell:用户可以创建一个伪tty终端,将其连接到STDIN,为容器提供一个交互式的shell。

1.6 本书的内容

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

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

我们将会教大家如何:

● 安装Docker;

● 尝试使用Docker容器;

● 构建Docker镜像;

● 管理并共享Docker镜像;

● 运行、管理更复杂的Docker容器;

● 将Docker容器的部署纳入测试流程;

● 构建多容器的应用程序和环境;

● 介绍使用Fig进行Docker编配的基础;

● 探索Docker的API;

● 获取帮助文档并扩展Docker。

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

1.7 Docker资源

● Docker官方主页(http://www.docker.com/)。

● Docker Hub(http://hub.docker.com)。

● Docker官方博客(http://blog.docker.com/)。

● Docker官方文档(http://docs.docker.com/)。

● Docker快速入门指南(http://www.docker.com/tryit/)。

● Docker的GitHub 源代码(https://github.com/docker/docker)。

● Docker Forge(https://github.com/dockerforge):收集了各种Docker工具、组件和服务。

● Docker邮件列表(https://groups.google.com/forum/#!forum/docker-user)。

● Docker的IRC 频道(irc.freenode.net)。

● Docker的Twitter主页(http://twitter.com/docker)。

● Docker的StackOverflow问答主页(http://stackoverflow.com/search?q=docker)。

● Docker官网(http://www.docker.com/)。

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

注释

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

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

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

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

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

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

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

[8]. http://www.memcachedasaservice.com/

[9]. https://web.archive.org/web/20090207105003/http://madstop.com/2009/02/04/golden-image-or-foil-ball

[10]. http://lxc.sourceforge.net/

[11]. http://lwn.net/Articles/531114/

[12]. http://en.wikipedia.org/wiki/Cgroups

[13]. http://en.wikipedia.org/wiki/Copy-on-write

第2章 安装Docker

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或RHEL宿主机中部署Docker,这两个发行版中直接提供了可安装的软件包。本章将介绍如何在四种各有所长的操作系统中安装 Docker,包括:

● 在运行Ubuntu 系统的宿主机中安装Docker;

● 在运行RHEL 或其衍生的Linux 发行版的宿主机中安装Docker;

● 在OS X系统中用Boot2Docker[1] 工具安装Docker;

● 在Microsoft Windows系统中使用Boot2Docker工具安装Docker。

提示

Boot2Docker是一个极小的虚拟机,同时提供了一个包装脚本(wrapper script)对该虚拟机进行管理。该虚拟机运行一个守护进程,并在OS X或Microsoft Windows中提供一个本地的Docker守护进程。Docker的客户端工具docker可以作为这些平台的原生程序安装,并连接到在Boot2Docker虚拟机中运行的Docker守护进程。

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

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

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

提示

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

2.1 安装Docker的先决条件

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

● 运行64 位CPU构架的计算机(目前只能是x86_64 和amd64),请注意,Docker目前不支持32位CPU。

● 运行Linux 3.8或更高版本内核。一些老版本的2.6.x或其后的内核也能够运行Docker,但运行结果会有很大的不同。而且,如果你需要就老版本内核寻求帮助时,通常大家会建议你升级到更高版本的内核。

● 内核必须支持一种适合的存储驱动(storage driver),例如:

◆ Device Manager[12]

◆ AUFS[13]

◆ vfs[14]

◆ btrfs[15]

◆ 默认存储驱动通常是Device Mapper。

● 内核必须支持并开启cgroup[16] 和命名空间[17] (namespace)功能。

2.2 在Ubuntu中安装Docker

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

● Ubuntu Trusty 14.04(LTS)(64 位);

● Ubuntu Precise 12.04(LTS)(64 位);

● Ubuntu Raring 13.04(64位);

● Ubuntu Saucy 13.10(64 位)。

注意

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

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

2.2.1 检查前提条件

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

1.内核

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

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

$ uname -a

Linux darknight.example.com 3.8.0-23-generic #34~precise1-Ubuntu SMP Wed May

29 21:12:31 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

可以看到,这里安装的是3.8.0 x86_64 版本的内核。这是Ubuntu 12.04.3 及更高版本(包括Ubuntu 13.04 Raring)默认的内核。

但是,如果我们使用Ubuntu 12.04 Precise较早的发行版,可能是3.2 内核。我们也可以轻松地把 Ubuntu12.04 升级到最新的内核。例如,本书写作时,3.8 版本的内核已经可以用apt-get来安装了,如代码清单2-2所示。

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

$ sudo apt-get update

$ sudo apt-get install linux-headers-3.8.0-27-generic

linux-image-3.8.0-27-generic linux-headers-3.8.0-27

注意

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

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

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

$ sudo update-grub

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

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

$ sudo reboot

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

注意

请记住:如果在 Ubuntu Raring中安装Docker,无需升级内核,因为 Raring本身的内核就是3.8版本。

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。

2.2.2 安装Docker

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

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

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

$ sudo sh -c "echo deb https://get.docker.io/ubuntu docker main >

/etc/apt/sources.list.d/docker.list"

安装之前,我们首先需要确认已经安装了curl命令,如代码清单2-9所示。

代码清单2-9 检测curl命令是否安装

$ whereis curl

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

如果没有找到curl命令,我们需要先安装它,如代码清单2-10所示。

代码清单2-10 如果需要,安装curl

$ sudo apt-get -y install curl

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

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

$ curl -s https://get.docker.io/gpg | sudo apt-key add -

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

代码清单2-12 更新APT源

$ sudo apt-get update

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

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

$ sudo apt-get install lxc-docker

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

安装完毕,可以用docker info 命令来确认Docker 是否已经正常安装并运行了,如代码清单2-14所示。

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

$ sudo docker info

Containers: 0

Images: 0

...

2.2.3 Docker与UFW

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

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

DEFAULT_FORWARD_POLICY="DROP"

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

DEFAULT_FORWARD_POLICY="ACCEPT"

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

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

$ sudo ufw reload

2.3 在Red Hat和Red Hat系发行版中安装Docker

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

● RHEL(和CentOS)6 或以上的版本(64 位);

● Fedora Core 19 或以上的版本(64 位)。

● Oracle Linux 6 和Oracle Linux 7,带有Unbreakable企业内核发行版 3(3.8.13)或者更高版本(64位)。

提示

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

2.3.1 检查前提条件

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

1.内核

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

代码清单2-18 检查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 Core 19 及更高版本宿主机中,应该也都安装了Device Mapper,不过我们还是需要确认一下,如代码清单2-19所示。

代码清单2-19 检查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-20所示。

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

$ sudo grep device-mapper /proc/devices

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

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

$ sudo yum install -y device-mapper

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

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

$ sudo modprobe dm_mod

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

2.3.2 安装Docker

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

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

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

代码清单2-23 在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-24所示。

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

$ sudo yum -y install docker-io

2.在RHEL 7 中安装Docker

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

代码清单2-25 在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-26所示。

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

$ sudo yum -y install docker-io

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

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

$ sudo yum -y install docker

2.3.3 在Red Hat系发行版中启动Docker守护进程

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

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

$ sudo service docker start

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

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

$ sudo service docker enable

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

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

$ sudo systemctl start docker

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

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

$ sudo systemctl enable docker

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

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

$ sudo docker info

Containers: 0

Images: 0

...

2.4 在OS X中安装Boot2Docker

如果使用的是OS X系统,则可以使用Boot2Docker工具[20] 快速上手Docker。Boot2Docker是一个极小的虚拟机,Boot2Docker 在OS X 宿主机上安装了一个原生的命令行工具,并提供了一个Docker环境。

要在OS X中安装Boot2Docker,也依赖于两个必要的条件:

● VirtualBox;

● Docker客户端。

2.4.1 在OS X中安装Boot2Docker

要在OS X中安装Boot2Docker,需要去GitHub 下载相应的安装程序[21]

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

代码清单2-33 下载Boot2Docker PKG文件

$ wget https://github.com/boot2docker/osx-installer/releases/

download/v1.3.0/Boot2Docker-1.3.0.pkg

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

2.4.2 在OS X中启动Boot2Docker

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

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

2.4.3 测试Boot2Docker

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

代码清单2-34 在OSX中测试Boot2Docker

$ 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了!

2.5 在Windows中安装Boot2Docker

如果使用的是Microsoft Windows系统,也可以使用Boot2Docker工具[22] 快速上手Docker。Boot2Docker是一个极小的虚拟机,Boot2Docker在Windows宿主机上安装了一个原生的命令行工具,并提供了一个Docker环境。

要在Windows中安装Boot2Docker,也依赖于两个必要的条件:

● VirtualBox;

● Docker客户端。

2.5.1 在Windows中安装Boot2Docker

要在Windows中安装Boot2Docker,需要从GitHub上下载相应的安装程序[23]

首先我们也需要下载最新版本的Boot2Docker,如代码清单2-35所示。

代码清单2-35 下载Boot2Docker的. exe文件

$ wget https://github.com/boot2docker/windows-installer/releases/

download/v1.3.0/docker-install.exe

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

2.5.2 在Windows中启动Boot2Docker

安装完Boot2Docker后,就可以从桌面或者Program Files > Boot2Docker for Windows 来运行Boot2Docker Start 脚本,如图2-4 所示。

2.5.3 测试Boot2Docker

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

代码清单2-36 在Windows中测试Boot2Docker

$ 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了!

2.6 使用本书的Boot2Docker示例

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

要想得到Boot2Docker的IP地址,可以查看DOCKER_HOST环境变量的值。当启动或安装Boot2Docker的时候,会弹出代码清单2-37所示的信息来提示设置这个变量。

代码清单2-37 Boot2Docker启动信息

$ boot2docker start

2014/07/31 05:59:40 Waiting for VM to be started...

2014/07/31 05:59:46 Started.

2014/07/31 05:59:46 To connect the Docker client to the Docker daemon,

please set:

2014/07/31 05:59:46 export DOCKER_HOST=tcp://192.168.59.103:2375

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

代码清单2-38 获取Boot2Docker的IP地址

$ boot2docker ip

The VM's Host only interface IP address is: 192.168.59.103

获取了Boot2Docker的IP地址后,就可以连接localhost上的容器了。例如,使用curl命令时,只需将localhost替换成相应的IP地址即可。

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

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

$ curl localhost:49155

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

$ curl 192.168.59.103:49155

另外,很重要的一点是,如果你在 OS X 或 Windows 操作系统下使用 1.3 之前版本的Boot2Docker的话,那么本书中所有使用卷或带有-v 选项的docker run 命令的示例都不能将本地目录挂载到Docker容器。你无法将OS X或Windows宿主机上的本地目录挂接到运行在Boot2Docker虚拟机之内的Docker容器上,因为它们无法共享文件系统。

不过到了Boot2Docker 1.3这一状况有所改善,在OS X上已经支持共享本地文件系统了,但是Windows还不支持。如果你要使用带有卷的示例,如本书第5章和第6章中的示例,则必须在基于Linux的宿主机上运行Docker。当然如果你的Linux是运行在Windows或者OS X上的虚拟机的话也是可以的。

注意

有一个很棒的博客(Chris Jones的博客:http://viget.com/extend/how-to-use-docker-on-os-x-the-missing-guide)讨论了这些问题,并推荐了一些变通的方法。

2.7 Docker安装脚本

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

注意

该脚本目前只支持在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命令来安装curl,如代码清单2-43所示。

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

$ sudo yum -y install curl

有了curl,我们就可以下载安装脚本并安装Docker了,如代码清单2-44所示。

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

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

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

2.8 二进制安装

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

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

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

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

2.9 Docker守护进程

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

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

警告

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

2.9.1 配置Docker守护进程

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

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

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

$ sudo /usr/bin/docker -d -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 /usr/bin/docker -d -H unix://home/docker/docker.sock

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

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

$ sudo /usr/bin/docker -d -H tcp://0.0.0.0:2375 -H unix://home/

docker/docker.sock

在启动守护进程时,我们还可以通过在命令前指定 DEBUG=1 参数来输出更详细的信息。目前,Docker的日志输出还比较少。在使用了Upstart的Ubuntu系统下,Docker守护进程生成的日志输出都保存在/var/log/upstart/docker.log 文件中,如代码清单2-50所示。

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

DEBUG=1 /usr/bin/docker -d

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

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

注意

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

2.9.2 检查Docker守护进程是否正在运行

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

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

$ sudo status docker

docker start/running, process 18147

此外,我们还可以用Upstart的start和stop命令来启动和停止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守护进程就可以独立运行。不过现在这种模式已经被废弃了。

2.10 升级Docker

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

例如,可以运行apt-get update 命令,然后安装新版本的Docker,如代码清单2-55所示的。

代码清单2-55 升级Docker

$ sudo apt-get update

$ sudo apt-get install lxc-docker

2.11 Docker图形用户界面

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

● Shipyard[24] :Shipyard 提供了通过管理界面来管理各种Docker资源(包括容器、镜像、宿主机等)的功能。Shipyard是开源的,源代码可以在https://github.com/ehazlett/shipyard获得。

● DockerUI[25] :DockerUI 是一个可以与Docker Remote API交互的Web 界面。DockerUI是基于AngularJS框架,采用JavaScript编写的。

● maDocker[26] :maDocker是采用NodeJS和Backbone编写的一个Web UI,还处于早期开发阶段。

2.12 小结

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

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

注释

[1]. http://boot2docker.io

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[17]. 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

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

[20]. http://boot2docker.io

[21]. https://github.com/boot2docker/osx-installer/releases

[22]. http://boot2docker.io

[23]. https://github.com/boot2docker/windows-installer/releases

[24]. http://shipyard-project.com/

[25]. https://github.com/crosbymichael/dockerui

[26]. https://github.com/izifortune/maDocker

相关图书

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

相关文章

相关课程