【试读】《Docker:容器与容器云》

ncnf

贡献于2015-11-27

字数:0 关键词: 虚拟化

内 容 提 要 本书从实践者的角度出发,基于 Docker 和 Kubernetes 最新源码,系统梳理了 Docker 容器技术和 Kubernetes 项目的实现原理和设计思路,有助于读者在实际场景中利用 Docker 容器和容器云解决问题并启 发新的思考。全书包括两部分,第一部分深入解读 Docker 容器技术,包括 Docker 架构与设计、核心源码 解读和高级实践技巧 ;第二部分归纳和比较了三类基于 Docker 的主流容器云项目,包括专注 Docker 容器 编排与部署的容器云、专注应用支撑的容器云以及一切皆容器的 Kubernetes,进而详细解读了 Kubernetes 核心源码的设计与实现,最后介绍了几种典型场景下的 Kubernetes 最佳实践。 本书适用于有一定 Docker 基础的开发者、架构师、IT 专业学生以及探索基于 Docker 构建云计算平台 的技术人员,也非常适合作为高校教材或培训资料。 定价:89.00元 读者服务热线:(010)51095186转600 印装质量热线:(010)81055316 反盗版热线:(010)81055315 广告经营许可证:京崇工商广字第 0021 号 著    浙江大学SEL实验室 责任编辑 王军花 策划编辑 张 霞 责任印制 杨林杰 人民邮电出版社出版发行  北京市丰台区成寿寺路11号 邮编 100061  电子邮件 315@ptpress.com.cn 网址 http://www.ptpress.com.cn 北京      印刷 开本:800×1000 1/16 印张:26 字数:614千字 2015年 9 月第 1 版 印数:1 — 3 500册 2015年 9 月北京第 1 次印刷 ◆ ◆ ◆ 推荐序 III 1 2 3 5 7 10 12 8 9 4 6 11 推荐语 “虽然在此之前已经有了由 Docker 团队出的第一本 Docker 书,但是这是国内第一本深入解 读 Docker 与 Kubernetes 原理的原创图书,这一点意义重大。本书比较完整地介绍了 Docker 与 Kubernetes 的工作原理和生态,非常有借鉴意义。” ——许式伟,七牛云存储 CEO “Docker 容器技术已经在国内如火如荼地流行起来,浙江大学 SEL 实验室目前是国内掌握 Docker 技术最熟练的技术团队之一,他们在国内 Docker 技术界一直产生着重要影响。这次他们 把 Docker 的实战经验汇编成书,可以帮助更多的 Docker 爱好者学习到一手的实战经验。” ——肖德时,数人科技 CTO “本书非常细致地讲解了 Docker 技术的来龙去脉和技术细节,更为难得的是还加入了 Docker 生态当中的其他技术。Docker 这项技术本身就是将多种思想和技术融合的产物,从生态的视角去 解读技术的来龙去脉将极大地促进读者对云计算和容器技术的重新思考。” ——程显峰,OpenAPM 首席运营官 “本书宏观上描绘了容器和容器云技术发展的浪潮和生态系统,微观上以 Docker 和 Kubernetes 为典型进行了深度分析。无论是 Docker 技术爱好者,还是系统架构师、云端开发者、系统管理 和运维人员,都能在本书中找到适合自己阅读的要点。浙江大学 SEL 实验室云计算团队是一支 非常优秀的云计算研究团队,很多 85 后、90 后人才活跃在顶级社区前沿,感谢他们能将多年的 知识和智慧积累分享出来!” ——刘俊,百度运维部高级架构师,百度最高奖获得者 “本书是浙江大学 SEL 实验室云计算团队多年深耕 Docker 及背后的容器技术的结晶。最大的 特点就是深入,并且有各种实用案例和细致讲解。另外,这本书在怎样真正地把 Docker 及周边 IV 推荐语 产品落地以构建灵活多变的云平台方面也进行了生动的阐释。” ——郝林,微影时代架构师,《Go 并发编程实战》作者 “Docker 颠覆了容器技术,也将容器技术带到了新的高度。InfoQ 从 2014 年初就开始密切关 注容器技术,见证并切身参与了容器技术的发展。作为我们的优秀作者,浙江大学 SEL 实验室 在 InfoQ 撰写了很多与 Docker、Kubernetes 相关的技术文章,得到了广大读者的肯定。希望这本 书能推动容器技术在中国的落地。” ——郭蕾,InfoQ 主编 “浙江大学 SEL 实验室属于国内较早接触并研究开源 PaaS 技术的团队之一,从传统 PaaS 的 开源代表 CloudFoundry、OpenShift,到新一代基于 Docker 的 PaaS 平台如 DEIS、Flynn 等,他们 均有深入的研究和实践经验。更为难得的是,他们不仅参与开源贡献,而且笔耕不辍,通过博客、 论坛等方式积极分享有深度、有内涵的技术文章,并广泛参与国内 PaaS 届各种技术交流会议。 华为PaaS团队也在与之交流中汲取了不少营养。此次,他们将近年来对Docker容器和Kubernetes、 DEIS、Flynn 等 PaaS 开源平台的研究成果结集成册,内容详尽且深入浅出。我相信,无论是入 门者还是老手,都能够从中获益。” ——刘赫伟,华为中央软件院高级软件架构师 “容器技术在大型互联网企业中已广泛应用,而 Docker 是容器技术中的杰出代表。本书不仅 介绍了 Docker 基础知识,而且进行了代码级的深入分析,并通过对 Kubernetes 等技术的讲解延 伸至集群操作系统以及对 Docker 生态领域的思考,同时结合了大量实践,内容丰富,值得拥有。” ——王炜煜,百度运维部高级架构师,JPaaS 项目负责人 “Docker 作为操作系统层面轻量级的虚拟化技术,凭借简易的使用、快速的部署以及灵活敏 捷的集成支持等优势,奠定了 Docker 如今在 PaaS 领域的江湖地位。浙江大学 SEL 实验室在云计 算和 PaaS 领域耕耘多年,积累了丰富的经验。本书既有对 Docker 源代码层面的深度解读,也有 实战经验的分享,希望这本书能够帮助 Docker 开发者在技术上更上一层楼。” ——李三红,蚂蚁金服基础技术部 JVM Architect 推荐序 V 1 2 3 5 7 10 12 8 9 4 6 11 序 我已从事软件工程研究工作二十余年,在这期间,软件开发方式发生了巨大的变化。瞬息万 变是这个时代的特征,固守经典、一成不变已无法应对,当代的软件工程拥有快速迭代的生命周 期,越来越多的开发组织投入巨大精力关注软件开发的敏捷性。 云计算有了明确定义,浙江大学就组织研究力量投入这滚滚浪潮之中。云计算定义了一种按 需索取、实时供应的特性,它是敏捷的。云平台提供的资源是计算能力,人们获得计算能力资源 一如获取自来水和管道煤气一样方便。这为软件工程注入了新的活力,如果软件开发者可以快速、 自由地获取开发过程中所需的各种资源,那么软件开发必将迎来一次飞跃式的发展。 然而,我们似乎并没有获得想要的飞跃。 众所周知,云计算拥有一个圣经般的三层模型,界限明确,职责分明。当下,依照圣经“戒 律”,众多业内巨头率先建立起一批重型云平台,然而问题却慢慢浮现——按照传统定义设计的 “云”对应用不够友好要么做得不够,要么管得太死。 是时候打破“戒律”了吗?我认为是。 Docker 让所有人眼前一亮,它模糊了 IaaS 与 PaaS 之间的界限,为云计算的服务形式带来了 无限的可能,Docker 带着它的容器理念破而后立,是云计算运动中一项了不起的创举。 丁轶群老师带领他的团队写作的这本《Docker——容器与容器云》,在很大程度上填补了国 内容器与容器云技术领域深度分析的空白。本书浓缩了浙大 SEL 实验室 4 年来在 PaaS 以及容器 技术领域的研究成果与开发实践经验,深入浅出地分析了云计算领域容器应用现状,是一部值得 业内人士和容器技术爱好者长置案头的好书。 杨小虎 浙江大学软件学院院长 VI 前 言 前 言 本书的写作目的不仅是在技术层面深入分析 Docker 背后的技术原理和设计思想,更在于从 我们团队几年来在云计算方面的积累出发,理清当前基于 Docker 的云计算平台(容器云)的发 展脉络,以期对 IT 企业的开发运维人员、容器云服务提供商以及 Docker 技术爱好者在技术选型、 技术路线规划上有所帮助。 2013 年是 Docker 正式开源发布的年份,也是我们团队开始使用 Docker 的时间。当时 Docker 作为一个单机版轻量级虚拟化工具,并没有如当前发达的生态系统。我们使用 Docker 处理 Cloud Foundry 这类复杂分布式系统的快速部署和迁移。结果是我们体验到了惊喜还有遗憾。确实,那 时候 Docker 1.0 尚未发布,作为最先吃螃蟹的人之一,我们除了能感受到 Docker 相比虚拟机的 在资源利用率和性能上的巨大优势以及在使用方式上的高效便捷,还不得不忍受当时的 Docker 与一个完整的数据中心运维系统之间的差距。比如网络,跨宿主机间的通信在很长一段时间都困 扰着我们;比如容器内部不能单独配置内核参数,一旦应用对性能有特殊要求的时候,就无法单 独进行优化定制;再比如维护,时常需要手动清理僵尸容器、镜像等。 在随后的一整年里,我们真真切切地感受到了 Docker 是如何从一个开发运维人员略有耳闻 的工具成为一个技术圈里家喻户晓的名词。基于 Docker 的公有云、私有云项目也如雨后春笋般 涌现;各大知名技术社区都为 Docker 开辟专栏,甚至出现了专为讨论 Docker 而生的技术社区。 基于 Docker 的中国本土化也开始萌芽,各类国内镜像托管和加速服务层出不穷。Docker 官方也 没有闲着,前不久 Docker 的各类邮件列表中都出现了招聘中国区执行官的消息。Docker 生态系 统的建立已经是不争的事实,在这一年的时间里,我们团队也从 Docker 的使用者,成为了 Docker、 Kubernetes、libcontainer 等开源项目的特性维护者(maintainer)和代码贡献者(contributor)。 当前 Docker 已决不仅仅是一项轻量级虚拟化技术,官方的 Docker 运维三件套、来自第三方 的 Kubernetes、OpenShift v3、Flynn、Deis 等项目已经基于 Docker 这种容器技术构建出各种各样 的容器云服务平台,关于 Docker 等容器技术的讨论重心也已经从“容器”转变为“容器云”。Docker 对于 IT 行业的价值也从节省资源这一方面扩展到对整个软件开发运维生命周期的改造。 作为软件行业多年的实践者和教育者,我们一直试图探索这样一些问题:云计算除了当前被 广为接受的基础设施云平台(IaaS)的形态,是否还有更加贴近开发人员和运维人员的形态?云 计算如何以更好的形态服务于互联网、互联网+这样一个以软件连接人与人,以软件连接人与企业, 以软件连接企业与企业的时代?正是 Docker 这样的容器技术的出现使得这样的探索成为可能。 前 言 VII 1 2 3 5 7 10 12 8 9 4 6 11 本书结构 本书共分两部分,沿着从容器到容器云的发展脉络,介绍 Docker 以及围绕 Docker 构建的各 类容器云平台技术,深入分析了 Kubernetes 背后的技术原理和设计思想。 第一部分讲解了 Docker 容器的核心原理和实践技巧。其中第 1 章和第 2 章能够让读者在短 时间内体验这场 IT 界的风暴,并且初步了解 Docker 的使用方法,为后续的源码解析做铺垫。第 3 章是本书第一部分的核心,这一章以最新的 Docker 1.6.2 版本源码为基础,结合最新的社区主 干 1.7.0 代码进展,深入地分析了容器的 namespace 和 cgroups 原理,紧接着我们以 docker run 命 令为线索,一路贯穿 Docker 的容器创建、镜像组织、联合文件系统以及容器网络初始化的源码, 深入透彻地向读者展示了从一句指令到最终 Linux 容器生成的整个过程中,Docker 源码背后的执 行路线和设计原理。第 4 章则介绍了 Docker 相关的几类实践技巧,包括网络、监控、服务发现 等。值得一提的是,在上述代码走读的过程中,本书几乎没有贴出任何一部分 Docker 源码或者 函数,而是力图使用平实的语言和生动的图示来展示代码背后的执行逻辑和设计思想。Docker 的源码字字珠玑,我们希望能够使用这样的解读方式使读者真正理解 Docker 和容器背后的设计 方法和技术本质,而不是变成一本单纯的技术手册。 第二部分深入分析基于 Docker 的各类容器云平台的架构细节和背后的设计理念,这些容器 云虽然在底层技术上都基于 Docker 这样的容器技术,但在背后的设计思想上却存在很大的差异。 我们将看到一个颠覆原有的 IaaS、PaaS 云计算生硬的分类方式而精彩纷呈的容器云世界,其中 第 5 章介绍了一个最简单的容器云解决方案作为引子;第 6 章和第 7 章分析和比较了几类典型的 容器云开源项目,这包括了 Docke 官方的三剑客项目、Fleet 以及更类似经典 PaaS 的 Flynn 和 Deis; 第 8 章是本书第二部分的重点章节,我们以 Kubernetes 0.16 版本源码为基础,从核心概念到架构 梳理,再到深入到组件级别的 Kubernetes 源码解析,从多个维度详细讲解了 Kubernetes 容器云平 台的各种技术细节,这在国内尚属首次。希望通过这部分容器云平台源码解读,我们能够带领读 者从纷繁复杂的容器云项目中梳理出一个细致的脉络,让读者在选型和二次开发的过程中减少迷 茫和试错。而作为 Kubernetes 项目的贡献者和特性维护者,我们希望有更多的技术人员能够从源 码层面对 Kubernetes 有更深刻的理解和认识,并且同我们一起来推动这个优秀的开源项目在国内 的进步和落地。在第二部分的结尾,我们试图回答之前的提问,即容器云应该以何种形态来更好 地支撑当今时代。 致谢 对于能够编写国内第一本在源代码层面深度解析 Docker 和 Kubernetes,并揭秘基于 Docker 容器的云计算生态圈底层技术的图书,我们感到非常荣幸。浙江大学 SEL 实验室云计算团队在 此向所有支持帮助我们的朋友表达最诚挚的谢意,没有大家的支持,我们很可能无法顺利地完成 这项工作。 VIII 前 言 感谢浙江大学软件学院杨小虎院长对云计算团队一直以来的关怀和支持,杨院长的远见卓识 和诲人不倦令人钦佩。 感谢多年来与我一同奋战在云计算前线,并参与本书大量编写工作的张磊和孙健波。他们自 加入云计算团队以来一直战斗在云计算领域最前沿,是写作本书的中坚力量。 感谢以极大热情参与到本书写作中的浙江大学计算机学院、软件学院的各位研究生,他们的 热情是我们团队活力的源泉,他们使那些分散在各个领域的技术得以整合。在本书编写过程中, 他们不计个人得失地精诚合作,这是本书得以成书的基石。 特别要感谢不辞辛劳为本书出谋划策、日以继夜不断审阅修改的图灵公司的编辑们。在整个 写作过程中,我们团队得到了出版方的大力支持,他们认真负责的态度是本书顺利出版的保证。 感谢 InfoQ 主编郭蕾一直以来对浙大团队技术分享工作所做出的支持和推广,他和 InfoQ 的 同事们的努力是推动本书发起的最大动力。 感谢《第一本 Docker 书》的译者刘斌对本书进行的细致的审读,并为我们提出了宝贵的修 订建议。 感谢浙江大学 SEL 实验室云计算团队的其他所有人,他们认真负责的工作态度和令人满意的 工作成果是本书不可或缺的支持力量。 感谢大家的共同努力,让我们的成果得以面世,在 Docker 布道之路上贡献一份光热,传播 惠及当下的云计算前沿技术。 丁轶群 浙江大学 SEL 实验室云计算团队 目 录 IX 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 17 目 录 第一部分 Docker深入解读 第 1 章 从容器到容器云 .................................2 1.1 云计算平台................................................2 1.2 容器,新的革命 ........................................3 1.3 进化:从容器到容器云.............................7 第 2 章 Docker 基础........................................8 2.1 Docker 的安装 ...........................................8 2.2 Docker 操作参数解读................................9 2.3 搭建你的第一个 Docker 应用栈..............16 2.3.1 Docker 集群部署..........................16 2.3.2 第一个 Hello World .....................17 2.3.3 开发、测试和发布一体化............27 第 3 章 Docker 核心原理解读.....................28 3.1 Docker 背后的内核知识 ..........................28 3.1.1 namespace 资源隔离 ....................28 3.1.2 cgroups 资源限制 .........................45 3.2 Docker 架构概览......................................53 3.3 client 和 daemon ......................................55 3.3.1 client 模式 ....................................55 3.3.2 daemon 模式.................................57 3.3.3 从client 到 daemon ......................63 3.4 libcontainer ..............................................66 3.4.1 libcontainer 的工作方式...............68 3.4.2 libcontainer 实现原理...................69 3.4.3 使用nsinit 与 libcontainer 进行 交互..............................................74 3.5 Docker 镜像管理......................................76 3.5.1 什么是 Docker 镜像 .....................76 3.5.2 Docker 镜像关键概念 ..................78 3.5.3 Docker 镜像操作解析 ..................80 3.5.4 Docker 容器的迁移方法 ..............84 3.6 Docker 存储驱动 .....................................85 3.6.1 存储驱动的功能与管理 ...............86 3.6.2 aufs 与 Device Mapper 驱动.........87 3.7 Docker 数据卷 .........................................93 3.7.1 数据卷的使用方式.......................94 3.7.2 数据卷原理解读...........................98 3.8 Docker 网络管理 ...................................102 3.8.1 Docker 网络基础........................102 3.8.2 Docker daemon 网络配置原理 ....107 3.8.3 libcontainer 网络配置原理.........111 3.8.4 Link 原理解析............................115 3.9 Docker 与容器安全 ...............................118 3.9.1 Docker 的安全机制....................118 3.9.2 Docker 安全问题........................122 3.9.3 Docker 安全的解决方案 ............126 第 4 章 Docker 高级实践技巧 ..................138 4.1 容器化思维............................................138 4.1.1 SSH 服务器的替代方案.............139 4.1.2 Docker 内应用日志管理方案.....139 4.1.3 其他技巧汇总 ............................140 4.2 Docker 高级网络实践............................142 4.2.1 玩转Linux network namespace ...143 4.2.2 pipework 原理解析.....................148 4.2.3 pipework 跨主机通信.................154 4.2.4 OVS 划分 VLAN........................159 4.2.5 OVS 隧道模式............................163 4.3 Dockerfile 最佳实践..............................175 X 目 录 4.3.1 Dockerfile 的使用 ......................176 4.3.2 Dockerfile 实践心得 ..................180 4.4 Docker 容器的监控手段........................182 4.4.1 Docker 容器监控维度 ................182 4.4.2 容器监控命令 ............................183 4.4.3 常用的容器监控工具.................186 4.5 容器化应用构建的基础:高可用 配置中心 ...............................................189 4.5.1 etcd 经典应用场景.....................190 4.5.2 etcd 实现原理.............................194 第二部分 Docker云平台解读 第 5 章 构建自己的容器云.........................210 5.1 再谈云平台的层次架构.........................210 5.2 从小工到专家........................................213 第 6 章 专注编排与部署:三剑客 与 Fleet............................................218 6.1 编排小神器 Fig......................................218 6.1.1 再谈容器编排与部署.................218 6.1.2 Compose 原理:一探究竟.........221 6.2 环境透明化工具 Machine .....................225 6.2.1 Machine 与虚拟机软件..............226 6.2.2 Machine 与 IaaS 平台.................227 6.2.3 Machine 小结 .............................228 6.3 集群抽象工具 Swarm............................229 6.3.1 Swarm 简介................................229 6.3.2 试用Swarm................................230 6.3.3 Swarm 集群的多种创建方式 .....231 6.3.4 Swarm 对请求的处理.................233 6.3.5 Swarm 集群的调度策略.............233 6.3.6 Swarm 与 Machine .....................234 6.4 编排之秀 Fleet.......................................235 6.4.1 旧问题新角度:Docker distro ...235 6.4.2 Fleet 的原理剖析........................239 第 7 章 专注应用支撑和运行时: Flynn 和 Deis .................................245 7.1 Flynn,一个小而美的两层架构............245 7.1.1 第0 层:容器云的基础设施 ..... 246 7.1.2 第1 层:容器云的功能框架 ..... 246 7.1.3 Flynn 体系架构与实现原理....... 247 7.2 谈谈Deis 与 Flynn ................................ 257 7.2.1 应用发布上的比较 .................... 258 7.2.2 关于Deis 的一些思考 ............... 260 第 8 章 一切皆容器:Kubernetes ......... 261 8.1 Kubernetes 简介 .................................... 261 8.2 Kubernetes 的设计解读......................... 262 8.2.1 一个典型案例:Guestbook ....... 263 8.2.2 Kubernetes 核心概念剖析.......... 265 8.3 Kubernetes 核心组件解读 ..................... 294 8.3.1 APIServer................................... 294 8.3.2 Scheduler ................................... 301 8.3.3 Controller Manager .................... 309 8.3.4 kubelet ....................................... 314 8.3.5 kube-proxy................................. 320 8.3.6 核心组件协作流程 .................... 325 8.4 Kubernetes 用户认证授权与资源 管理....................................................... 328 8.4.1 namespace 解析.......................... 328 8.4.2 基于token 文件或客户端证书 的认证机制................................ 333 8.4.3 基于访问规则的授权机制......... 334 8.4.4 基于资源的授权控制 Admission Control....................................... 336 8.5 Kubernetes 网络核心原理 ..................... 347 8.5.1 单pod 单 IP 模型....................... 348 8.5.2 pod 和网络容器 ......................... 350 8.5.3 实现Kubernetes 的网络模型..... 353 8.6 Kubernetes 高级实践............................. 356 8.6.1 Kubernetes 高级实践之应用 健康检查.................................... 356 8.6.2 Kubernetes 高级实践之高 可用性 ....................................... 358 8.6.3 Kubernetes 高级实践之日志...... 362 8.6.4 Kubernetes 高级实践之集成 DNS ........................................... 364 8.6.5 Kubernetes 高级实践之容器 上下文环境................................ 366 目 录 XI 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 17 8.7 不要停止思考 ........................................368 第三部分 附录 附录 A Docker 的安装 ..........................372 附录 B 阅读Docker 源代码的神兵 利器..........................................379 附录 C 快速熟悉开源项目.....................388 附录 D cgroups 的测试与使用 ..............391 附录 E cgroups 子系统配置参数介绍....395 附录 F Kubernetes 的安装....................400 后记........................................................403 XII 目 录 第一部分 Docker 作为时下流行的容器技术,已经在云计算领域掀起了一股狂潮。本 书的第一部分从 Docker 容器技术的出现背景谈起,阐述这门技术的方方面面。 第 1 章中说明了 Docker 的发展脉络,帮助读者了解到底是什么赋予了 Docker 如此大的魅力。第 2 章用 Docker 的一个实际使用案例展示 Docker 的基本使用 方法。第 3 章是本书的一大核心,从源码的层面,对构成 Docker 的各个模块 进行原理上的解读。第一部分的最后一章介绍使用 Docker 的高级实践技巧。 相信当你阅读完本部分的内容后,会对 Docker 容器技术有全面而深刻的理解。 Docker 深入解读 2 第1 章 从容器到容器云 从容器到容器云 2013年初,一个名字从云计算领域横空出世,并在整个IT行业激起千层浪。这就是Docker—— 一个孕育着新思想的“容器”。Docker选择容器作为核心和基础,依靠容器技术支撑的Docker迅 速成为国内外各大云计算厂商以及开发者手中的至宝。在一片热火朝天之中,新的革命已经悄然 来临。 1.1 云计算平台 回首历史,云计算时代蕴育出了众多的云计算平台,虽然在服务类型或平台功能上有所差异, 但它们的本质上如出一辙,都与NIST①对于云计算平台的定义有着密切的关系。 云计算是一种资源的服务模式,该模式可以实现随时随地、便捷按需地从可配置计 算资源共享池中获取所需的资源(如网络、服务器、存储、应用及服务),资源能够快 速供应并释放,大大减少了资源管理工作开销,你甚至可以再也不用理会那些令人头痛 的传统服务供应商了。 经典云计算架构包括了IaaS(Infrastructure as a Service,基础设施即服务)、PaaS(Platform as a Service,平台即服务)、SaaS(Software as a Service,软件即服务)三层服务,如图1-1所示。  IaaS层为基础设施运维人员服务,提供计算、存储、网络及其他基础资源,云平台使用者 可以在上面部署和运行包括操作系统和应用程序在内的任意软件,无需再为基础设施的 管理而分心。  PaaS层为应用开发人员服务,提供支撑应用运行所需的软件运行时环境、相关工具与服 务,如数据库服务、日志服务、监控服务等,让应用开发者可以专注于核心业务的开发。  SaaS层为一般用户服务,提供了一套完整可用的软件系统,让一般用户无需关注技术细 节,只需通过浏览器、应用客户端等方式就能使用部署在云上的应用服务。 —————————— ① National Institute of Standards and Technology,“The NIST Definition of Cloud Computing”论文定义了人们认可的云 计算三层服务模型。 第1章 1.2 容器,新的革命 3 1 2 3 4 5 8 6 7 图1-1 云平台经典架构 同时,随着计算机技术推陈出新,应用的规模愈发庞大,逻辑愈发复杂,迭代更新愈发频繁, 应用开发所需的统一规范和原有开发模式杂乱无章成了追求进步的主要障碍。在尖锐的矛盾中, 云时代应用生命周期管理机制(Application Lifecycle Management,ALM)和十二要素应用规范 (The Twelve-Factor App)①应运而生。 所有理论设计和预想一定是美好的,只是对于一个新的理论而言,如何经受住实践的考验, 并将美好的愿景转化为生产力才是重中之重。IaaS的发展主要以虚拟机为最小粒度的资源调度单 位,出现了资源利用率低、调度分发缓慢、软件堆栈环境不统一等一堆问题。PaaS在IaaS基础上 发展而来,众多PaaS已经意识到可以利用容器技术解决资源利用率问题,但是PaaS通常在应用架 构选择、支持的软件环境服务方面有较大的限制,这带来了应用与平台无法解耦、应用运行时环 境局限性强、运维人员控制力下降的问题。 可见不论IaaS还是PaaS都有各自适用的场景,但依旧存在诸多缺陷,人们亟需一个真正可用 的解决方案。 1.2 容器,新的革命 每一场革命背后都有着深刻的历史背景和矛盾冲突,新陈代谢是历史的必然结果,新生取代 陈旧得益于理念的飞跃和对时代发展需求的契合,很显然Docker抓住了这个契机。 Docker是什么? —————————— ① 参考自The Twelve-Factor App英文原版(http://12factor.net/)。 4 第1 章 从容器到容器云 根据官方的定义,Docker是以Docker容器为资源分割和调度的基本单位,封装整个软件运行 时环境,为开发者和系统管理员设计的,用于构建、发布和运行分布式应用的平台。它是一个跨 平台、可移植并且简单易用的容器解决方案。Docker的源代码托管在GitHub上,基于Go语言开发 并遵从Apache 2.0协议。Docker可在容器内部快速自动化地部署应用,并通过操作系统内核技术 (namespaces、cgroups等)为容器提供资源隔离与安全保障。 我们应该看看Docker的发展历程。 每一个传奇都需要一个这样的开头,很久很久以前:Docker项目由Solomon Hykes所带领的 团队发起,在Docker公司的前身dotCloud内部启动孕育,代码托管于GitHub。 2013年3月:Docker正式发布开源版本,GitHub中Docker代码提交盛况空前,风头之劲一时 无两。见图1-2。 图1-2 GitHub上Docker项目提交数统计图 2013年11月:REHL 6.5正式版发布,集成了对Docker的支持,拉开了业界各大厂商竞相支持 Docker的序幕。 2014年4月到6月:云技术市场上的三大巨头Amazon、Google及MicroSoft Azure相继宣布支持 Docker,并着手开发基于容器的全新产品。 2014年6月:DockerCon 2014大会召开,会上来自Google、IBM、Amazon、Red Hat、Facebook 及Twitter等全球领先企业的演讲嘉宾组成了豪华的阵容。此时, Docker自开源版本后又经历了15 个月左右的飞速发展,Docker 1.0版本正式发布。 2014年8月:VMware宣布与Docker建立合作关系,标志了虚拟化市场形成了新的格局。 2014年10月:微软宣布将整合Docker进入下一代的Windows Server中。 2014年10月15日:Azure和Docker共同举办了Docker全球开发者大会,并宣布双方建立战略 合作伙伴关系。 2014年底:Google率先发布容器引擎Google Container Engine(GCE),整合了Docker、Google 自有容器技术和在DockerCon 2014大会上发布的Kubernetes,致力于为用户提供面向Docker化应 1.2 容器,新的革命 5 1 2 3 4 5 8 6 7 用的云计算平台;Amazon发布EC2 Container Service(ECS),它是一项高度可扩展、高性能、 免费的容器管理服务,并能够在托管的Amazon EC2实例集群上轻松地发布、管理和扩展Docker 容器,使得Amazon Web Services(AWS)用户能够使用AWS上的容器轻松地运行和管理分布式 应用。 2015年4月:Docker公司宣布完成了9500万美元的D轮融资。此前,他们已完成三轮融资,包 括1500万美元的B轮融资及4000万美元的C轮融资。 截至2015年5月:GitHub中Docker的贡献者多达近千人,被关注和喜爱(Star)多达两万一千 余次(相比之下,此时Linux源码多年来积累的被关注次数为两万两千余次),并有近五千多个开 发分支(Fork),Docker成为了GitHub上排名前20的明星项目。 Docker官方存储应用镜像的镜像仓库也获得了大量开发者支持,其镜像仓库里已有四万五千 余个不同应用功能的公共镜像。最受欢迎的Ubuntu、MySQL、nginx、WordPress镜像,下载量已 达到三四百万次。这些数字还在不断地增长! 在国内一线城市,几乎每一两周就有一场关于Docker的讨论大会,Docker永远不会让你孤独。 从此以后的未来,Docker已经给云计算带来了深远的影响,这是一次真正的计算机技术革命, 来吧,拥抱变化! 一个软件项目的成功常常需要依托其衍生的生态系统,围绕或基于核心技术而构建的相关项 目日臻丰富和完善,软件本身的功能和易用性也随之增加,Docker的迅猛发展与其强大的生态系 统息息相关。首先我们从图1-3中整体上来审视一下它①。 如图1-3所示,围绕Docker的生态系统自下而上分别覆盖了IaaS层和PaaS层所涉及的各类问 题,包括资源调度、编排、部署、配置管理、网络管理、应用开发和部署平台、应用开发工具、 应用服务供应以及大数据分析等云计算相关的服务。除了基于Docker技术解决构建分布式平台无 法回避的经典问题,Docker及其生态系统主要带来了以下几点好处。  持续部署与测试。Docker消除了线上线下的环境差异,保证了应用生命周期的环境一致 性和标准化。开发人员使用镜像实现标准开发环境的构建,开发完成后通过封装着完整 环境和应用的镜像进行迁移,由此,测试和运维人员可以直接部署软件镜像来进行测试 和发布,大大简化了持续集成、测试和发布的过程。  跨云平台支持。Docker带来的最大好处之一就是其适配性,越来越多的云平台都支持 Docker,用户再也无需担心受到云平台的捆绑,同时也让应用多平台混合部署成为可能。 目前支持Docker的IaaS云平台包括但不限于亚马逊云平台(AWS)、Google云平台(GCP)、 微软云平台(Azure)、OpenStack等,还包括如Chef、Puppet、Ansible等配置管理工具。 —————————— ① 参考自“Docker Ecosystem-MindMeister Mind Map”(https://www.mindmeister.com/389671722/docker-ecosystem)。 6 第1 章 从容器到容器云 图1-3 Docker生态系统  环境标准化和版本控制。基于Docker提供的环境一致性和标准化,你可以使用Git等工具 对Docker镜像进行版本控制,相比基于代码的版本控制来说,你还能够对整个应用运行 环境实现版本控制,一旦出现故障可以快速回滚。相比以前的虚拟机镜像,Docker压缩 和备份速度更快,镜像启动也像启动一个普通进程一样快速。  高资源利用率与隔离。Docker容器没有管理程序的额外开销,与底层共享操作系统,性 能更加优良,系统负载更低,在同等条件下可以运行更多的应用实例,可以更充分地利 用系统资源。同时,Docker拥有不错的资源隔离与限制能力,可以精确地对应用分配CPU、 内存等资源,保证了应用间不会相互影响。  容器跨平台性与镜像。Linux容器虽然早在Linux 2.6版本内核已经存在,但是缺少容器的 跨平台性,难以推广。Docker在原有Linux容器的基础上进行大胆革新,为容器设定了一 整套标准化的配置方法,将应用及其依赖的运行环境打包成镜像,真正实现了“构建一 次,到处运行”的理念,大大提高了容器的跨平台性。  易于理解且易用。Docker的英文原意是处理集装箱的码头工人,标志是鲸鱼运送一大堆 集装箱,集装箱就是容器,生动好记,易于理解。一个开发者可以在15分钟之内入门Docker 并进行安装和部署,这是容器使用史上的一次飞跃。因为它的易用性,有更多的人开始 关注容器技术,加速了容器标准化的步伐。 1.3 进化:从容器到容器云 7 1 2 3 4 5 8 6 7  应用镜像仓库。Docker官方构建了一个镜像仓库,组织和管理形式类似于GitHub,其上 已累积了成千上万的镜像。因为Docker的跨平台适配性,相当于为用户提供了一个非常 有用的应用商店,所有人都可以自由地下载微服务组件,这为开发者提供了巨大便利。 1.3 进化:从容器到容器云 容器为用户打开了一扇通往新世界的大门,真正进入这个容器的世界后,却发现新的生态系 统如此庞大。在生产使用中,不论个人还是企业,都会提出更复杂的需求。这时,我们需要众多 跨主机的容器协同工作,需要支持各种类型的工作负载,企业级应用开发更是需要基于容器技术, 实现支持多人协作的持续集成、持续交付平台。即使Docker只需一条命令便可启动一个容器,一 旦试图将其推广到软件开发和生产环境中,麻烦便层出不穷,容器相关的网络、存储、集群、高 可用等就是不得不面对的问题。从容器到容器云的进化应运而来。 什么是容器云? 容器云以容器为资源分割和调度的基本单位,封装整个软件运行时环境,为开发者和系统管 理员提供用于构建、发布和运行分布式应用的平台。当容器云专注于资源共享与隔离、容器编 排与部署时,它更接近传统的IaaS;当容器云渗透到应用支撑与运行时环境时,它更接近传统 的PaaS。 容器云并不仅限于Docker,基于rkt容器的CoreOS项目也是容器云。Docker的出现让人们意 识到了容器的价值,使得一直以来长期存在但并未被重视的轻量级虚拟化技术得到快速的发展 和应用。鉴于Docker的里程碑意义,本书在讨论容器云时,都以分析Docker为支撑技术的容器 云为主。 Docker公司本身的技术发展,亦是从一个容器管理工具一步步向容器云发展的历史过程。 Docker最初发布时只是一个单机下的容器管理工具,随后Docker公司发布了Compose、Machine、 Swarm等编排部署工具,并收购了Socketplane解决集群化后的网络问题。本书提及Docker时,一 般指Docker容器核心,并不包含它向容器云迈进的一系列扩展工具,这些工具则将在本书第二部 分进行分析。 除了Docker公司之外,业界许多云计算厂商也对基于Docker的容器云做了巨大的投入,以 Docker容器为核心的第三方Docker容器云正在迎来春天。第6章将要介绍的Fleet、第7章将要介绍 的Flynn和Deis以及第8章的Kubernetes,都是基于Docker技术构建的广为人知的容器云。 从容器到容器云是一种伟大的进化,并依旧在日积月累中不断前行,现在让我们一起进入 Docker的世界,感受容器与容器云的魅力。 8 第2 章 Docker 基础 Docker 基础 本章将为Docker开发者、系统管理员及相关技术爱好者介绍Docker的基础知识,包括Docker 的安装流程、Docker操作相关命令和参数解读,并在最后提供一个实例来展示Docker的具体用法, 读者可以参照本书开始你的Docker之旅。 本章假定读者熟知Linux/Unix环境,掌握一定的操作技能,对命令行、软件包安装、系统管 理及网络知识有一定了解。Docker是一个跨平台、可移植的解决方案,当前各大主流平台均宣布 对Docker提供支持,包括Ubuntu、RHEL(Red Hat Enterprise Linux),以及CentOS、Debian、Fedora、 Oracle Linux等Linux的衍生系统和发行版本,此外还可利用虚拟环境(Boot2Docker或虚拟机)实 现Docker移植到OS X、Microsoft Windows等系统。 Linux平台是Docker原生支持平台,在Linux上使用Docker可以得到最佳的用户体验。本章主 要以Linux平台下操作系统为例讲解Docker的安装和使用,同时,也会对非Linux平台下Docker安 装进行简单讲解,读者可根据自身需要选择相应的小节查阅。 2.1 Docker 的安装 Docker是一个轻量级虚拟化技术,它具备传统虚拟机无可比拟的优势。它更简易的安装和使 用方式、更快的速度、服务集成与开发流程自动化,都使Docker被广大技术爱好者青睐。 安装Docker的基本要求如下:  Docker只支持64位CPU架构的计算机,目前不支持32位CPU;  建议系统的Linux内核版本为3.10及以上;  Linux内核需开启cgroups和namespace功能;  对于非Linux内核的平台,如Microsoft Windows和OS X,需要安装使用Boot2Docker工具。 下面将选择5类主流的操作系统来讲解Docker的安装,它们包括:  在Ubuntu系统中安装Docker;  在REHL系统中安装Docker;  在REHL衍生的Linux发行版(CentOS/Fedora)中安装Docker; 第2章 2.2 Docker 操作参数解读 9 1 2 3 4 5 8 6 7  在OS X系统中安装Docker;  在Microsoft Windows系统中安装Docker。 每一个操作系统都各有所长,读者可根据需求选择安装。本书将Docker在相应系统中的具体 安装流程收录在了附录中,方便读者查阅。 2.2 Docker 操作参数解读 本节将有选择地介绍Docker命令行工具的部分功能,旨在帮助读者快速入门,对于Docker 命令行工具的完整介绍,读者可以参考Docker官方网站相关内容。本节主要讲解Docker命令的使 用方法及其操作参数,命令内部的运行流程和原理将在第3章介绍。 用户在使用Docker时,需要使用Docker命令行工具docker与Docker daemon建立通信。Docker daemon是Docker守护进程,负责接收并分发执行Docker命令。 为了了解Docker命令行工具的概况,我们可以使用docker命令或docker help命令来获取 docker的命令清单。 $ sudo docker Commands: attach Attach to a running container build Build a container from a Dockerfile commit Create a new image from a container's changes ... ... version Show the Docker version information wait Block until a container stops, then print its exit code Run 'docker COMMAND --help' for more information on a command. 说明 本书中命令前的sudo用于获取命令执行所需的root权限。 值得一提的是,docker命令的执行一般都需要获取root权限,因为Docker的命令行工具docker 与Docker daemon是同一个二进制文件,而Docker daemon负责接收并执行来自docker的命令,它 的运行需要root权限。同时,从Docker 0.5.2版本开始,Docker daemon默认绑定一个Unix Socket 来代替原有的TCP端口,该Unix Socket默认是属于root用户的。因此,在执行docker命令时,需 要使用sudo来获取root权限。 随着Docker的不断发展,docker的子命令已经达到39个(如attach、build),其中核心子命 令(如run、exec等)还有复杂的可选执行参数,用户可以使用相应的命令和参数实现丰富强大 的功能。对于每一个特定的子命令,用户可以使用docker COMMAND --help命令来查看该子命令的 详细信息,包括子命令的使用方法及可用的操作参数。以下这个例子使用docker start --help 命令获取子命令start的详细信息: 10 第2 章 Docker 基础 $ docker start --help Usage: docker start [OPTIONS] CONTAINER [CONTAINER...] Restart a stopped container -a, --attach=false Attach container's STDOUT and STDERR and forward all signals to the process -i, --interactive=false Attach container's STDIN 此外,除了命令的操作参数外,用于管理容器的Docker daemon也有详细的参数配置,使用 docker命令或docker help命令来查看,读者可以自行尝试。 在进行命令的解读前,本书依据命令的用途对其进行分类,帮助初学者尽快掌握docker命令, 如表2-1所示。 表2-1 Docker子命令分类 子命令分类 子 命 令 Docker环境信息 info、version 容器生命周期管理 Create、exec、kill、pause、restart、rm、run、start、stop、unpause 镜像仓库命令 login、logout、pull、push、search 镜像管理 build、images、import、load、rmi、save、tag、commit 容器运维操作 attach、export、inspect、port、ps、rename、stats、top、wait、cp、diff 系统日志信息 events、history、logs 从docker命令使用出发,梳理出如图2-1所示的命令结构图,希望帮助读者更进一步了解 Docker的命令行工具①。 图2-1 Docker命令结构图 —————————— ① 子命令分类及结构图参考自“docker专题(2):docker常用管理命令(上)”(http://segmentfault.com/a/1190000000751601)。 2.2 Docker 操作参数解读 11 1 2 3 4 5 8 6 7 下面根据表2-1中的Docker的子命令分类清单,选取每个功能分类中常用的子命令进行用法 和操作参数的解读。 1. Docker环境信息 docker info命令用于检查Docker是否正确安装。如果Docker正确安装,该命令会输出Docker 的配置信息。 docker info命令一般结合docker version命令使用,两者结合使用能够提取到足够详细的 Docker环境信息。 $ sudo docker info Containers: 18 Images: 51 Storage Driver: aufs ... ... Kernel Version: 3.16.0-36-generic Operating System: Ubuntu 14.04.2 LTS ... ... $ sudo docker version Client version: 1.6.0 Client API version: 1.18 Go version (client): go1.4.2 ... ... Server version: 1.6.0 Server API version: 1.18 Go version (server): go1.4.2 ... ... docker info和docker version命令的用法比较简单,并没有额外的操作参数。 2. 容器生命周期管理 容器生命周期管理涉及容器启动、停止等功能,下面选取最常用的docker run命令和负责启 动停止的docker start/stop/restart命令举例。  docker run命令 docker run命令使用方法如下: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] docker run命令是Docker的核心命令之一,用户可以选用的选项近40个,所有选项的说明可 以通过docker run --help命令查看。 docker run命令用来基于特定的镜像创建一个容器,并依据选项来控制该容器。具体的使用 示例如下: $ sudo docker run ubuntu echo "Hello World" Hello World 12 第2 章 Docker 基础 这是docker run命令最基本的使用方法,该命令从ubuntu镜像启动一个容器,并执行echo命 令打印出“Hello World”。执行完echo命令后,容器将停止运行。docker run命令启动的容器会随 机分配一个CONTAINER ID,用以标识该容器。 说明 在选取启动容器的镜像时,可以在镜像名后添加tag来区分同名的镜像,如ubuntu:latest、 ubuntu:13.04、ubuntu:14.04。如在选取镜像启动容器时,用户未指定具体tag,Docker将 默认选取tag为latest的镜像。 掌握了基本用法后,结合docker run命令丰富的选项,能够实现更加复杂的功能。来看一个 例子: $ sudo docker run -i -t --name mytest ubuntu:latest /bin/bash root@83b752d52f3f:/# 上例中,docker run命令启动一个容器,并为它分配一个伪终端执行/bin/bash命令,用户 可以在该伪终端与容器进行交互。其中:  -i选项表示使用交互模式,始终保持输入流开放;  -t选项表示分配一个伪终端,一般两个参数结合时使用-it,即可在容器中利用打开的伪 终端进行交互操作;  --name选项可以指定docker run命令启动的容器的名字,若无此选项,Docker将为容器随 机分配一个名字。 通过上面两个例子,相信大家对于docker run命令的使用方法已经有了一个初步的认识。除 了上文例子中讲解的-i、-t和--name选项外,docker run命令还提供很多常用选项,以下对它提 供的主要选项进行详细解释。  -c选项:用于给运行在容器中的所有进程分配CPU的shares值,这是一个相对权重,实际 的处理速度还与宿主机的CPU相关。  -m选项:用于限制为容器中所有进程分配的内存总量,以B、K、M、G为单位。  -v选项:用于挂载一个volume,可以用多个-v参数同时挂载多个volume。volume的格式为 [host-dir]:[container-dir]:[rw|ro]。  -p选项:用于将容器的端口暴露给宿主机的端口,其常用格式为hostPort:containerPort。 通过端口的暴露,可以让外部主机通过宿主机暴露的端口来访问容器内的应用。 其中,前3个选项对于Docker的资源管理的作用非常显著,4.4节有更详细的解释。另外,关 于docker run的其他选项的用法可以通过官方文档查知。  docker start/stop/restart命令 docker run命令可以新建一个容器来运行,而对于已经存在的容器,可以通过docker start/ stop/restart命令来启动、停止和重启。利用docker run命令新建一个容器时,Docker将自动为 2.2 Docker 操作参数解读 13 1 2 3 4 5 8 6 7 每个新容器分配唯一的ID作为标识。docker start/stop/restart命令一般利用容器ID标识确定具 体容器,在一些情况下,也使用容器名来确定容器。 docker start命令使用-i选项来开启交互模式,始终保持输入流开放。使用-a选项来附加标 准输入、输出或错误输出。此外,docker stop和docker restart命令使用-t选项来设定容器停止 前的等待时间。 3. Docker registry Docker registry是存储容器镜像的仓库,用户可以通过Docker client与Docker registry进行通信,以 此来完成镜像的搜索、下载和上传等相关操作。Docker Hub是由Docker公司在互联网上提供的一个镜 像仓库,提供镜像的公有与私有存储服务,它是用户最主要的镜像来源。除了Docker Hub外,用户还 可以自行搭建私有服务器来实现镜像仓库的功能。下面选取最常用的docker pull和push命令举例。  docker pull命令 docker pull 命令是Docker 中的常用命令,主要用于从Docker registry 中拉取image 或 repository①。在Docker官方仓库Docker Hub中有许多即拿即用的镜像资源,通过docker pull命令 可以有效地利用它们,这也体现了Docker“一次编译,到处运行”的特性。同时,当镜像被拉取 到本地后,用户可以在其现有基础上做出自身的更改操作,这也大大加快了应用的开发进程。 该命令的使用方法如下: docker pull [OPTIONS] NAME[:TAG] 在使用docker pull命令时,可以从官方的Docker Hub中的官方镜像库、其他公共库、私人库 中获取镜像资源,同时,还可以从私有服务器中获取镜像资源。只需在具体的镜像名前添加用户 名、特定库名或者服务器地址即可获取镜像。使用示例如下: # 从官方Hub拉取ubuntu:latest镜像 $ sudo docker pull ubuntu # 从官方Hub拉取指明“ubuntu 12.04”tag的镜像 $ sudo docker pull ubuntu:ubuntu12.04 # 从特定的仓库拉取ubuntu镜像 $ sudo docker pull SEL/ubuntu # 从其他服务器拉取镜像 $ sudo docker pull 10.10.103.215:5000/sshd  docker push命令 与docker pull命令相对应的docker push命令,可以将本地的image或repository推送到Docker Hub的公共或私有镜像库,以及私有服务器。 使用方法如下: docker push NAME[:TAG] —————————— ① repository的定义和介绍详见3.5.2节。 14 第2 章 Docker 基础 使用示例如下: # docker push SEL/ubuntu 4. 镜像管理 用户可以在本地保存镜像资源,为此Docker提供了相应的管理子命令,这里选取images、rmi 及rm子命令举例。  docker images命令 通过docker images命令可以列出主机上的镜像,默认只列出最顶层的镜像,可以使用-a选项 显示所有镜像。 使用方法如下: docker images [OPTIONS] [NAME] 使用示例如下: $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu 14.04 8eaa4ff06b53 7 days ago 192.7 MB ubuntu latest 8eaa4ff06b53 7 days ago 192.7 MB busybox latest e72ac664f4f0 3 months ago 2.433 MB 10.10.103.215:5000/sshd latest 692ffdd5ad2a 3 months ago 438.9 MB 上例中,从REPOSITORY属性可以判断出镜像是来自于官方镜像、私人仓库还是私有服务器。  docker rmi和docker rm命令 这两个子命令的功能都是删除,docker rmi命令用于删除镜像,docker rm命令用于删除容器。 它们可同时删除多个镜像或容器,也可按条件来删除。 这两个命令的使用方法如下: docker rm [OPTIONS] CONTAINER [CONTAINER...] docker rmi [OPTIONS] IMAGE [IMAGE...] 需要注意的是,使用rmi命令删除镜像时,如果已有基于该镜像启动的容器存在,则无法直 接删除,需要首先删除容器。当然,这两个子命令都提供-f选项,可强制删除存在容器的镜像或 启动中的容器。 5. 容器运维操作 作为Docker的核心,容器的操作是重中之重,Docker为用户提供了丰富的容器运维操作命令, 这里选取常用的attach、inspect及ps子命令举例。  docker attach命令 docker attach命令对于开发者来说十分有用,它可以连接到正在运行的容器,观察该容器的 2.2 Docker 操作参数解读 15 1 2 3 4 5 8 6 7 运行情况,或与容器的主进程进行交互。 使用方法如下: docker attach [OPTIONS] CONTAINER  docker inspect命令 docker inspect命令可以查看镜像和容器的详细信息,默认会列出全部信息,可以通过 --format参数来指定输出的模板格式,以便输出特定信息。 使用方法如下: docker inspect [OPTIONS] CONTAINER|IMAGE [CONTAINER|IMAGE...] 具体示例如下: # 查看容器的内部IP $ sudo docker inspect --format='{{.NetworkSettings.IPAddress}}' ee36 172.17.0.8  docker ps命令 docker ps命令可以查看容器的相关信息,默认只显示正在运行的容器的信息。可以查看到 的信息包括CONTAINER ID、NAMES、IMAGE、STATUS、容器启动后执行的COMMAND、创建时间CREATED 和绑定开启的端口PORTS。docker ps命令最常用的功能就是查看容器的CONTAINER ID,以便对特 定容器进行操作。 使用方法如下: docker ps [OPTIONS] docker ps命令常用的选项有-a和-l。-a参数可以查看所有容器,包括停止的容器;-l选项则 只查看最新创建的容器,包括不在运行中的容器。 6. 其他子命令 除了上述的命令外,Docker还有一系列非常有用的子命令,如固化容器为镜像的commit命令 等,读者可以尝试自己探索更多有意思的命令功能。下面以一些较为常用的子命令举例。  docker commit命令 commit命令可以将一个容器固化为一个新的镜像。当需要制作特定的镜像时,会进行修改容 器的配置,如在容器中安装特定工具等,通过commit命令可以将这些修改保存起来,使其不会因 为容器的停止而丢失。 使用方法如下: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] 提交保存时,只能选用正在运行的容器(即可以通过docker ps查看到的容器)来制作新的 16 第2 章 Docker 基础 镜像。在制作特定镜像时,直接使用commit命令只是一个临时性的辅助命令,不推荐使用。官方 建议通过docker build命令结合Dockerfile创建和管理镜像。关于docker build命令和Dockerfile 的使用方法,请参考4.2节的内容。  events、history和logs命令 events、history和logs这3个命令用于查看Docker的系统日志信息。events命令会打印出实 时的系统事件;history命令会打印出指定镜像的历史版本信息,即构建该镜像的每一层镜像的 命令记录;logs命令会打印出容器中进程的运行日志。 使用方法如下: docker events [OPTIONS] docker history [OPTIONS] IMAGE docker logs [OPTIONS] CONTAINER 至此,docker常用的子命令及其选项已经讲解完毕,其他docker命令和选项用法,请读者查 阅官方文档或使用docker COMMAND --help命令进一步了解。 对于Docker的操作,读者应更多地结合案例操作进行深入学习和理解,并多做练习,打下坚 实的基础。同时,于读者而言,深入了解Docker的核心原理对于掌握Docker的使用操作颇有益处, 具体内容可查阅第3章。 2.3 搭建你的第一个 Docker 应用栈 Docker的设计理念是希望用户能够保证一个容器只运行一个进程,即只提供一种服务。然而, 对于用户而言,单一容器是无法满足需求的。通常用户需要利用多个容器,分别提供不同的服务, 并在不同容器间互连通信,最后形成一个Docker集群,以实现特定的功能。对于Docker而言,现 在已经有了很多优秀的工具来帮助用户搭建和管理集群。下面将通过示例搭建一个一台机器上的 简化的Docker集群,让用户了解如何基于Docker构建一个特定的应用,基于Docker集群构建的应 用我们称为Docker App Stack,即Docker应用栈。 2.3.1 Docker集群部署 Docker是一个新兴的轻量级虚拟化技术,其易用、跨平台、可移植的特性使其在集群系统的 搭建方面有着得天独厚的优势。Docker能够标准化封装应用程序所需的整个运行时环境,因此基 于Docker,我们可以实现分布式应用集群的快速、准确、自动化部署。 考虑到读者可能是初次接触Docker的新手,我们将降低难度,在一台机器上利用Docker自带 的命令行工具,搭建一个Docker应用栈,利用多个容器来组成一个特定的应用。读者可参考应用栈 部署的过程,一步一步搭建你的第一个Docker应用栈。对于有一定Docker使用经验的读者,也可尝 试在多台机器上搭建一个真正的Docker集群,相信这个过程将对理解Docker相关工作原理大有裨益。 2.3 搭建你的第一个 Docker 应用栈 17 1 2 3 4 5 8 6 7 2.3.2 第一个Hello World 在Docker中,镜像是容器的基础,可以通过镜像来运行容器。本节将举例说明如何有效地利 用Docker Hub中已有的镜像资源来搭建一个Docker应用栈。 在开始搭建过程前,需要对所要搭建的应用栈进行简单的设计和描述:我们将搭建一个包含 6个节点的Docker应用栈,其中包括一个代理节点、两个Web的应用节点、一个主数据库节点及 两个从数据库节点。应用栈具体结构如图2-2所示。 图2-2 Docker应用栈结构图 图2-2中,HAProxy是负载均衡代理节点;Redis是非关系型的数据库,它由一个主数据库节 点和两个从数据库节点组成;App是应用,这里是使用Python语言、基于Django架构设计一个访 问数据库的基础Web应用。 1. 获取应用栈各节点所需镜像 在搭建过程中,可以从Docker Hub获取现有可用的镜像,在这些镜像的基础上启动容器,按 照需求进行修改来实现既定的功能。读者能在此过程中体会到Docker的高可移植特性所带来的便 利,既提高了应用开发的效率,又降低了开发的难度。 依据上文所描述的应用栈结构,需要从Docker Hub获取HAProxy、Redis及Django的镜像。具 体的操作示例如下: $ sudo docker pull ubuntu $ sudo docker pull django $ sudo docker pull haproxy $ sudo docker pull redis $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE redis latest 3b7234aa3098 9 days ago 110.8 MB haproxy latest 380557f8f7b3 9 days ago 97.91 MB django latest 8b9d8caad0d9 9 days ago 885.8 MB ubuntu latest 8eaa4ff06b53 2 weeks ago 188.3 MB 18 第2 章 Docker 基础 2. 应用栈容器节点互联 在搭建第一个Hello World应用栈时,将在同一主机下进行Docker应用栈搭建。如果是一个真 正的分布式架构集群,还需要处理容器的跨主机通信问题,在这里我们将不做介绍,请读者参 考第4章高级实践中关于网络的处理方式。鉴于在同一主机下搭建容器应用栈的环境,只需要完 成容器互联来实现容器间的通信即可,这里采用docker run命令的--link选项建立容器间的互联 关系。 这里介绍一下--link选项的用法,通过--link选项能够进行容器间安全的交互通信,使用格 式为name:alias,可在一个docker run命令中重复使用该参数。使用示例如下: $ sudo docker run --link redis:redis --name console ubuntu bash 上例将在ubuntu镜像上启动一个容器,并命名为console,同时将新启动的console容器连接 到名为redis的容器上。在使用--link选项时,连接通过容器名来确定容器,这里建议启动容器 时自定义容器名。 通过--link选项来建立容器间的连接,不但可以避免容器的IP和端口暴露到外网所导致的安 全问题,还可以防止容器在重启后IP地址变化导致的访问失效,它的原理类似于DNS服务器的域 名和地址映射①。当容器的IP地址发生变化时,Docker将自动维护映射关系中的IP地址,文件示 例如下: # 容器启动命令 $ sudo docker run -it --name redis-slave1 --link redis-master:master redis /bin/bash # 容器内查看/etc/hosts文件 # cat /etc/hosts 172.17.0.6 08df6a2cb468 127.0.0.1 localhost ... 172.17.0.5 master 该容器的/etc/host文件中记录了名称为master的连接信息,其对应IP地址为172.17.0.5,即 redis-master容器的IP地址。 通过上面的原理可以将--link设置理解为一条IP地址的单向记录信息,因此在搭建容器应用 栈时,需要注意各个容器节点的启动顺序,以及对应的--link参数设置。应用栈各节点的连接信 息如下:  启动redis-master容器节点;  两个redis-slave容器节点启动时要连接到redis-master上;  两个APP容器节点启动时要连接到redis-master上;  HAProxy容器节点启动时要连接到两个APP节点上。 —————————— ① link具体原理在3.8.4节有介绍。 2.3 搭建你的第一个 Docker 应用栈 19 1 2 3 4 5 8 6 7 综上所述,容器的启动顺序应为: redis-master → redis-slave → APP → HAProxy 此外,为了能够从外网访问应用栈,并通过HAProxy节点来访问应用栈中的APP,在启动 HAProxy容器节点时,需要利用-p参数暴露端口给主机,即可通过主机IP加暴露的端口从外网访 问搭建的应用栈。以下是整个应用栈的搭建流程示例。 3. 应用栈容器节点启动 之前已经对应用栈的结构进行了分析,获取了所需的镜像资源,同时描述了应用栈中各个容 器之间的互连关系,下面开始利用所获得的镜像资源来启动各个容器。应用栈各容器节点的启动 命令如下: # 启动Redis容器 $ sudo docker run -it --name redis-master redis /bin/bash $ sudo docker run -it --name redis-slave1 --link redis-master:master redis /bin/bash $ sudo docker run -it --name redis-slave2 --link redis-master:master redis /bin/bash # 启动Django容器,即应用 $ sudo docker run -it --name APP1 --link redis-master:db -v ~/Projects/Django/App1: /usr/src/app django /bin/bash $ sudo docker run -it --name APP2 --link redis-master:db -v ~/Projects/Django/App2: /usr/src/app django /bin/bash # 启动HAProxy容器 $ sudo docker run -it --name HAProxy --link APP1:APP1 --link APP2:APP2 -p 6301:6301 -v ~/Projects/HAProxy:/tmp haproxy /bin/bash 说明 以上容器启动时,为了方便后续与容器进行交互操作,统一设定启动命令为/bin/bash, 请在启动每个新的容器时都分配一个终端执行。 启动的容器信息可以通过docker ps命令查看,示例如下: $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bc0a13093fd1 haproxy:latest "/bin/bash" 5 days ago Up 21 seconds 0.0.0.0:6301->6301/tcp HAProxy f92e470d7c3f django:latest "/bin/bash" 5 days ago Up 27 seconds APP2 a1705c6e06a8 django:latest "/bin/bash" 5 days ago Up 34 seconds APP1 7a9e537b661b redis:latest "/entrypoint.sh /bin 5 days ago Up 46 seconds 6379/tcp redis-slave2 08df6a2cb468 redis:latest "/entrypoint.sh /bin 5 days ago Up 57 minutes 6379/tcp redis-slave1 bc8e79b3e66c redis:latest "/entrypoint.sh /bin 5 days ago Up 58 minutes 6379/tcp redis-master 20 第2 章 Docker 基础 至此,所有搭建应用栈所需容器的启动工作已经完成。 4. 应用栈容器节点的配置 在应用栈的各容器节点都启动后,需要对它们进行配置和修改,以便实现特定的功能和通信 协作,下面按照容器的启动顺序依次进行解释。  Redis Master主数据库容器节点的配置 Redis Master主数据库容器节点启动后,我们需要在容器中添加Redis的启动配置文件,以启 动Redis数据库。 需要说明的是,对于需要在容器中创建文件的情况,由于容器的轻量化设计,其中缺乏相应 的文本编辑命令工具,这时可以利用volume来实现文件的创建。在容器启动时,利用-v参数挂载 volume,在主机和容器间共享数据,这样就可以直接在主机上创建和编辑相关文件,省去了在容 器中安装各类编辑工具的麻烦。 在利用Redis镜像启动容器时,镜像中已经集成了volume的挂载命令,所以我们需要通过 docker inspect命令来查看所挂载volume的情况。打开一个新的终端,执行如下命令: $ sudo docker inspect --format "{{ .Volumes }}" bc8e map[/data:/var/lib/docker/vfs/dir/f01cd2d7cecba683e74def4ae9c3c6bf5952a8cfafddbe19136d916154afee34 ] 可以发现,该volume在主机中的目录为/var/lib/docker/vfs/dir/f01cd2d7cecba683e74def4 ae9c3c6bf5952a8cfafddbe19136d916154afee34,在容器中的目录为/data。此时,可以进入主机的 volume目录,利用启动配置文件模板来创建我们的主数据库的启动配置文件,执行命令如下: # cd /var/lib/docker/vfs/dir/f01cd2d7cecba683e74def4ae9c3c6bf5952a8cfafddbe19136d916154afee34 # cp /home/qc/re-ha-dj-file/redis.conf redis.conf # vim redis.conf 对于Redis的主数据库,需要修改模板文件中的如下几个参数: daemonize yes pidfile /var/run/redis.pid 在主机创建好启动配置文件后,切换到容器中的volume目录,并复制启动配置文件到Redis 的执行工作目录,然后启动Redis服务器,执行过程如下: # cd /data # cp redis.conf /usr/local/bin # cd /usr/local/bin # redis-server redis.conf 以上就是配置Redis Master容器节点的全部过程,在完成配置另外两个Redis Slave节点后,再 对应用栈的数据库部分进行整体测试。 2.3 搭建你的第一个 Docker 应用栈 21 1 2 3 4 5 8 6 7  Redis Slave从数据库容器节点的配置 与Redis Master容器节点类似,在启动Redis Slave容器节点后,需要首先查看volume信息。 $ sudo docker inspect --format "{{ .Volumes }}" 08df map[/data:/var/lib/docker/vfs/dir/f74cebbb0d5ceea04e6f47a4750053d9f3a013938abc959d019609c4085cbf4e ] # cd /var/lib/docker/vfs/dir/f74cebbb0d5ceea04e6f47a4750053d9f3a013938abc959d019609c4085cbf4e # cp /home/qc/re-ha-dj-file/redis.conf redis.conf # vim redis.conf 对于Redis的从数据库,需要修改如下几个参数: daemonize yes pidfile /var/run/redis.pid slaveof master 6379 需要注意的是,slaveof参数的使用格式为slaveof ,可以看到对于 masterip使用了--link参数设置的连接名来代替实际IP地址。通过连接名互连通信时,容器会自 动读取它的host信息,将连接名转换为实际IP地址。 在主机创建好启动配置文件后,切换到容器中的volume目录,并复制启动配置文件到Redis 的执行工作目录,然后启动Redis服务器,执行过程如下: # cd /data # cp redis.conf /usr/local/bin # cd /usr/local/bin # redis-server redis.conf 同理,可以完成对另一个Redis Slave容器节点的配置。至此,便完成了所有Redis数据库容器 节点的配置。  Redis数据库容器节点的测试 完成Redis Master和Redis Slave容器节点的配置以及服务器的启动后,可以通过启动Redis的 客户端程序来测试数据库。 首先,在Redis Master容器内,启动Redis的客户端程序,并存储一个数据,执行过程如下: # redis-cli 127.0.0.1:6379> set master bc8e OK 127.0.0.1:6379> get master "bc8e" 随后,在两个Redis Slave容器内,分别启动Redis的客户端程序,查询先前在Master数据库中 存储的数据,执行过程如下: # redis-cli 127.0.0.1:6379> get master "bc8e" 22 第2 章 Docker 基础 由此可以看到,Master数据库中的数据已经自动同步到了Slave数据库中。至此,应用栈的数 据库部分已搭建完成,并通过测试。  APP容器节点(Django)的配置 Django容器启动后,需要利用Django框架,开发一个简单的Web程序。 为了访问数据库,需要在容器中安装Python语言的Redis支持包,执行如下命令: # pip install redis 安装完成后,进行简单的测试来验证支持包是否安装成功,执行过程如下: # python >>> import redis >>> print(redis.__file__) /usr/local/lib/python3.4/site-packages/redis/__init__.py 如果没有报错,说明已经可以使用Python语言来调用Redis数据库。接下来,就开始创建Web 程序。以APP1为例,在容器启动时,挂载了-v ~/Projects/Django/App1:/usr/src/app的volume, 方便进入主机的volume目录来对新建APP进行编辑。 在容器的volume目录/usr/src/app/下,开始创建APP,执行过程如下: # 在容器内 # cd /usr/src/app/ # mkdir dockerweb # cd dockerweb/ # django-admin.py startproject redisweb # ls redisweb # cd redisweb/ # ls manage.py redisweb # python manage.py startapp helloworld # ls helloworld manage.py redisweb 在容器内创建APP后,切换到主机的volume目录~/Projects/Django/App1,进行相应的编辑来 配置APP,执行过程如下: # 在主机内 $ cd ~/Projects/Django/App1 $ ls dockerweb 可以看到,在容器内创建的APP文件在主机的volume目录下同样可见。之后,我们来修改 helloworld应用的视图文件views.py。 $ cd dockerweb/redisweb/helloworld/ $ ls 2.3 搭建你的第一个 Docker 应用栈 23 1 2 3 4 5 8 6 7 admin.py __init__.py migrations models.py tests.py views.py # 利用root权限修改views.py $ sudo su # vim views.py 为了简化设计,只要求完成Redis数据库信息输出,以及从Redis数据库存储和读取数据的结 果输出。views.py文件如下: from django.shortcuts import render from django.http import HttpResponse # Create your views here. import redis def hello(request): str=redis.__file__ str+="
" r = redis.Redis(host='db', port=6379, db=0) info = r.info() str+=("Set Hi
") r.set('Hi','HelloWorld-APP1') str+=("Get Hi: %s
" % r.get('Hi')) str+=("Redis Info:
") str+=("Key: Info Value") for key in info: str+=("%s: %s
" % (key, info[key])) return HttpResponse(str) 需要注意的是,连接Redis数据库时,使用了--link参数创建db连接来代替具体的IP地址;同 理,对于APP2,使用相应的db连接即可。 完成views.py文件修改后,接下来修改redisweb项目的配置文件setting.py,添加新建的 helloworld应用,执行过程如下: # cd ../redisweb/ # ls __init__.py __pycache__ settings.py urls.py wsgi.py # vim setting.py 在setting.py文件中的INSTALLED_APPS选项下添加helloworld,执行过程如下: # Application definition INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'helloworld', ) 24 第2 章 Docker 基础 最后,修改redisweb项目的URL模式文件urls.py,它将设置访问应用的URL模式,并为URL 模式调用的视图函数之间的映射表。执行如下命令: # vim urls.py 在urls.py文件中,引入helloworld应用的hello视图,并为hello视图添加一个urlpatterns 变量。urls.py文件内容如下: from django.conf.urls import patterns, include, url from django.contrib import admin from helloworld.views import hello urlpatterns = patterns('', url(r'^admin/', include(admin.site.urls)), url(r'^helloworld$',hello), ) 在主机下修改完成这几个文件后,需要再次进入容器,在目录/usr/src/app/dockerweb/redisweb 下完成项目的生成。执行过程如下: # python manage.py makemigrations No changes detected # python manage.py migrate Operations to perform: Apply all migrations: sessions, contenttypes, admin, auth Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying admin.0001_initial... OK Applying sessions.0001_initial... OK # python manage.py syncdb Operations to perform: Apply all migrations: admin, auth, sessions, contenttypes Running migrations: No migrations to apply. You have installed Django's auth system, and don't have any superusers defined. Would you like to create one now? (yes/no): yes Username (leave blank to use 'root'): admin Email address: sel@sel.com Password: Password (again): Superuser created successfully. 至此,所有APP1容器的配置已经完成,另一个APP2容器配置也是同样的过程,只需要稍作 修改即可。配置完成APP1和APP2容器后,就完成了应用栈的APP部分的全部配置。 在启动APP的Web服务器时,可以指定服务器的端口和IP地址。为了通过HAProxy容器节点 接受外网所有的公共IP地址访问,实现均衡负载,需要指定服务器的IP地址和端口。对于APP1 使用8001端口,而APP2则使用8002端口,同时,都使用0.0.0.0地址。以APP1为例,启动服务器 2.3 搭建你的第一个 Docker 应用栈 25 1 2 3 4 5 8 6 7 的过程如下: # python manage.py runserver 0.0.0.0:8001 Performing system checks... System check identified no issues (0 silenced). January 20, 2015 - 13:13:37 Django version 1.7.2, using settings 'redisweb.settings' Starting development server at http://0.0.0.0:8001/ Quit the server with CONTROL-C.  HAProxy容器节点的配置 在完成数据库和APP部分的应用栈部署后,最后部署一个HAProxy负载均衡代理的容器节点, 所有对应用栈的访问将通过它来实现负载均衡。 首先,利用容器启动时挂载的volume将HAProxy的启动配置文件复制进容器中,在主机的 volume目录~/Projects/HAProxy下,执行过程如下: $ cd ~/Projects/HAProxy $ vim haproxy.cfg 其中,haproxy.cfg配置文件的内容如下: global log 127.0.0.1 local0 # 日志输出配置,所有日志都记录在本机,通过local0输出 maxconn 4096 # 最大连接数 chroot /usr/local/sbin # 改变当前工作目录 daemon # 以后台形式运行HAProxy nbproc 4 # 启动4个HAProxy实例 pidfile /usr/local/sbin/haproxy.pid # pid文件位置 defaults log 127.0.0.1 local3 # 日志文件的输出定向 mode http # { tcp|http|health } 设定启动实例的协议类型 option dontlognull # 保证HAProxy不记录上级负载均衡发送过来的用于检测状态没有数据的心跳包 option redispatch # 当serverId对应的服务器挂掉后,强制定向到其他健康的服务器 retries 2 # 重试两次连接失败就认为服务器不可用,主要通过后面的check检查 maxconn 2000 # 最大连接数 balance roundrobin # 负载均衡算法,roundrobin表示轮询,source表示按照IP timeout connect 5000ms # 连接超时时间 timeout client 50000ms # 客户端连接超时时间 timeout server 50000ms # 服务器端连接超时时间 listen redis_proxy 0.0.0.0:6301 stats enable stats uri /haproxy-stats server APP1 APP1:8001 check inter 2000 rise 2 fall 5 # 你的均衡节点 server APP2 APP2:8002 check inter 2000 rise 2 fall 5 随后,进入到容器的volume目录/tmp下,将HAProxy的启动配置文件复制到HAProxy的工作 目录中。执行过程如下: 26 第2 章 Docker 基础 # cd /tmp # cp haproxy.cfg /usr/local/sbin/ # cd /usr/local/sbin/ # ls haproxy haproxy-systemd-wrapper haproxy.cfg 接下来利用该配置文件来启动HAProxy代理,执行如下命令: # haproxy -f haproxy.cfg 需要注意的是,如果修改了配置文件的内容,需要先结束所有的HAProxy进程,并重新启动 代理。可以使用killall命令来结束进程,如果镜像中没有安装该命令,则需要先安装psmisc包, 执行如下命令: # apt-get install psmisc # killall haproxy 至此,完成了HAProxy容器节点的全部部署,同时也完成了整个Docker应用栈的部署。  应用栈访问测试 整个应用栈部署完成后,就可以进行访问测试。参考应用栈搭建时的结构图(见图2-2)可 知,整个应用栈群的访问是通过HAProxy代理节点来进行的。在HAProxy容器节点启动时,通过 -p 6301:6301参数,映射了容器访问的端口到主机上,因此可以在其他主机上,通过本地主机的 IP地址和端口来访问搭建好的应用栈。 在应用栈启动后,先在本地主机上进行测试。在浏览器中访问http://172.17.0.9:6301/helloworld 可以查看APP1或APP2的页面内容,如图2-3所示,具体访问到的APP容器节点会由HAProxy代 理进行均衡分配。同时,可以访问http://172.17.0.9:6301/haproxy-stats来查看HAProxy的后台管理 页面。 图2-3 本地主机访问应用栈 说明 172.17.0.9为HAProxy容器的IP地址。 本地测试通过后,尝试在其他主机上通过应用栈入口主机的IP地址和暴露的6301端口来访问 该应用栈的APP,即访问http://10.10.105.87:6301/helloworld,如图2-4所示。 2.3 搭建你的第一个 Docker 应用栈 27 1 2 3 4 5 8 6 7 图2-4 外网其他主机访问应用栈 说明 10.10.105.87为宿主机的IP地址。 2.3.3 开发、测试和发布一体化 从Docker集群的搭建过程不难看出,通过Docker提供的虚拟化方式,可以快速建立起一套可 复用的开发环境,以镜像的形式将开发环境分发给所有开发成员,达到了简化开发环境搭建过程 的目的。Docker的优点在于可以简化CI(持续集成)和CD(持续交付)的构建流程,让开发者 集中精力在应用开发上,同时运维和测试也可以并行进行,并保持整个开发、测试、发布和运维 的一体化。 Docker以镜像和在镜像基础上构建的容器为基础,以容器为开发、测试和发布的单元,将与 应用相关的所有组件和环境进行封装,避免了应用在不同平台间迁移时所带来的依赖性问题,确 保了应用在生产环境的各阶段达到高度一致的实际效果。 在开发阶段,镜像的使用使得构建开发环境变得简单和统一。随着Docker的发展,镜像资源 也日益丰富,开发人员可以轻易地找到适合的镜像加以利用。同时,利用Dockerfile也可以将一 切可代码化的东西进行自动化运行。Docker最佳实践是将应用分割成大量彼此松散耦合的Docker 容器,应用的不同组件在不同的容器中同步开发,互不影响,为实现持续集成和持续交付提供了 先天的便利。 在测试阶段,可以直接使用开发所构建的镜像进行测试,直接免除了测试环境构建的烦恼, 也消除了因为环境不一致所带来的漏洞问题。 在部署和运维阶段,与以往代码级别的部署不同,利用Docker可以进行容器级别的部署,把 应用及其依赖环境打包成跨平台、轻量级、可移植的容器来进行部署。 Docker已经逐渐发展成为一个构建、发布、运行分布式应用的开放平台,以轻量级容器为核 心建立起了一套完整的生态系统,它重新定义了应用开发、测试、交付和部署的过程。在当前云 计算飞速发展的背景下,Docker将引领着云时代进入一个崭新的发展阶段。

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 3 金币 [ 分享文档获得金币 ] 4 人已下载

下载文档

相关文档