项目1Docker容器简介
任务1.1 了解Docker历史
1.1.1 什么是 Docker
Docker 最初是dotCloud 公司创始人 Solomon Hykes在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于2013 年 3 月以 Apache 2.0 授权协议开源),主要项目代码在GitHub上进行维护。Docker 项目后来还加入了Linux 基金会,并成立推动开放容器联盟。
Docker 自开源后受到广泛的关注和讨论,至今其GitHub 项目已经超过 3 万6 千个星标和一万多个 fork。甚至由于Docker 项目的火爆,在 2013 年底,dotCloud 公司决定改名为 Docker。Docker 最初是在 Ubuntu 12.04上开发实现的;Red Hat 则从RHEL 6.5 开始对 Docker 进行支持;Google 也在其 PaaS 产品中广泛应用Docker。
Docker 使用Google 公司推出的Go 语言进行开发实现,基于 Linux 内核的cgroup,namespace,以及AUFS类的 Union FS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于LXC,从 0.7 以后开始去除LXC,转而使用自行开发的 libcontainer,从1.11 开始,则进一步演进为使用 runC 和containerd。
对于Docker,目前的定义是一个开源的容器引擎,可以方便地对容器进行管理。其对镜像的打包封装,以及引入Docker Regsitry 对镜像的统一管理,构建了方便快捷的“Build,Ship and Run”流程,它可以统一整个开发、测试和部署的环境和流程,极大地减少运维成本。另外,得益于容器技术带来的轻量级虚拟化,以及Docker在分层镜像应用上的创新,Docker在磁盘占用、性能和效率方面相较于传统的虚拟化都有非常明显的提高,所以理所当然,Docker开始不断蚕食传统虚拟化的市场。
时间 | 版本 | 更新内容 |
2013.7.18 | v0.5 | 主要增加对外置存储、高级网络、自组织注册项的支持 |
2015.8.26 | v1.8 | Toolbox 以及编排工具大更新 |
2015.10.20 | v1.9.0 | 使用linux容器引擎 |
2016.7.28 | v1.12.0 | 改进了服务的负载均衡参数 |
2016.12.14 | v1.12.4 | 更新容器文件系统 |
表1.1 Docker版本变更表
任务1.2 容器和虚拟机对比
1.2.1 容器和虚拟机差异
下面的图片比较了 Docker和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
图1.1 传统虚拟化架构
图1.2 Docker架构
1.2.2 为什么要使用Docker?
作为一种新兴的虚拟化方式,Docker跟传统的虚拟化方式相比具有众多的优势。
(1)更高效的利用系统资源
容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
(2)更快速的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
(3)一致的运行环境
开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些bug 并未在开发过程中被发现。而 Docker的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性。
(4)持续交付和部署
对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。
使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署(Continuous Delivery/Deployment) 系统进行自动部署。
而且使用 Dockerfile使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
(5)更轻松的迁移
由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
(6)更轻松的维护和扩展
Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
(7)对比传统虚拟机总结
特性 | 容器 | 虚拟机 |
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为 MB | 一般为 GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
表1.2 Docker容器与传统虚拟机对比表
任务1.3 Docker架构及基本组件
1.3.1 认识Docker 平台
Docker是开发、测试、部署、运行应用的一个开放平台,目的让应用快速交付,快速上线。Docker遵循开源Apache 2.0协议。
Docker提供一个安全隔离用于打包和运行应用的轻量级环境—容器(Container),一个宿主机可以同时运行很多容器(数量远远超过虚拟机VM的方式)。
1)Docker引擎
Docker引擎Docker Engine是C/S架构,主要有以下部件组成::
服务器(Docker daemon):后台运行的Dockerdaemon进程。Daemon进程用于管理Docker对象,包括镜像(images,)容器(containers)网络(networks)数据卷(data volumes)。
REST接口:同daemon交互的REST API接口。
客户端(Docker client):命令行(CLI)交互客户端。客户端使用REST API接口同Dockerdaemon进行访问。
图1.3 Docker服务的架构图
2)Docker平台组成
图1.4 Docker服务组成图
运行一个Docker服务,组成包括Docker daemon服务器、Docker Client客户端、DockerImage镜像、Docker Registry库、Docker Contrainer容器。
(1)Docker镜像:
是一个只读模板,用于创建Docker容器,由Dockerfile文本描述镜像的内容。镜像定义类似“面对对象的类”,从一个基础镜像(Base Image)开始。构建一个镜像实际就是安装、配置和运行的过程,Docker镜像基于UnionFS把以上过程进行分层(Layer)存储,这样更新镜像可以只更新变化的层。Docker的描述文件为Dockerfile,Dockerfile是一个文本文件,基本指令包括:
FROM:定义基础镜像。
MAINTAINER :作者或维护者。
RUN:运行linux 命令。
ADD:增加文件或目录。
EVN:定义环境变量。
CMD:运行进程。
(2)Docker容器:
是一个镜像的运行实例。容器有镜像创建,运行过程例如:
运行ubuntu操作系统镜像,-I 前台交互模型,运行命令为/bin/bash
$ docker run -i -t ubuntu /bin/bash
运行过程如下:
拉(pull)镜像,Docker Engine 检查ubuntu 镜像是否存在,如果本地已经存在,使用该镜像创建容器,如果不存在,Docker Engine从镜像库拉镜像。
使用该镜像创建新容器。
分配文件系统,挂载一个读写层,在读写从加载镜像。
分配网络/网桥接口,创建一个网络接口,让容器和主机通信。
从可用的IP池选择IP地址,分配给容器。
执行命令/bin/bash。
捕获和提供执行结果。
(3)Docker 仓库:
Docker仓库是Docker镜像库。Docker Registry也是一个容器。Docker Hub是Docker公司提供的互联网公共镜像仓库。可以构建自己本地的镜像仓库,国内有些公司也构建了镜像仓库。包括阿里云、新浪等。Docker 集群服务:Docker集群服务运行承租的Docker节点一起工作。目前支持swarm模式。
一个 Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。
一般而言,一个仓库包含的是同一个软件的不同版本的镜像,而标签则用于对应于软件的的不同版本。可以通过<仓库名>:<标签> 的格式来指定具体是哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
以 Ubuntu 镜像 为例,ubuntu 是仓库的名字,其内包含有不同的版本标签,如,14.04, 16.04。可以通过 ubuntu:14.04,或者ubuntu:16.04 来具体指定所需哪个版本的镜像。如果忽略了标签,比如ubuntu,那将视为 ubuntu:latest。
最常使用的 Registry公开服务是官方的 Docker Hub,这也是默认的Registry,并拥有大量的高质量的官方镜像。除此以外,还有 CoreOS的 Quay.io,CoreOS 相关的镜像存储在这里;Google的 Google ContainerRegistry,Kubernetes 的镜像使用的就是这个服务。
由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对Docker Hub 的镜像服务(RegistryMirror),这些镜像服务被称为加速器。常见的有 阿里云加速器、DaoCloud 加速器、灵雀云加速器等。
除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry。Docker 官方提供了Docker Registry镜像,可以直接使用做为私有 Registry服务。在后续的相关章节中,会有进一步的搭建私有 Registry 服务的讲解。
开源的 Docker Registry镜像只提供了 Docker RegistryAPI 的服务端实现,足以支持 docker 命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。在官方的商业化版本Docker Trusted Registry 中,提供了这些高级功能。
除了官方的 Docker Registry外,还有第三方软件实现了 Docker Registry API,甚至提供了用户界面以及一些高级功能。比如,VMWare Harbor 和 Sonatype Nexus。
任务1.4 Docker容器目前的使用情况
1.4.1 Google与容器
Google自从2004年起就已经开始使用容器技术了,于2006年发布了cgroups,发布了lmctfy项目。Imctfy是Google开源版本的容器栈,它提供了用来代替LXC的Linux应用容器。
Google云平台的高级软件工程师Joe Beda在2014年Gluecon上做了一个关于Google如何使用Linux容器技术的报告。报告中声称现在Google所有的应用都是运行在容器中的。Google每周要启动超过20亿个容器,每秒钟要启动超过3000个容器,这还不包括那些长期运行的容器。Google同样也正在将容器集成到Google云平台中。
Google 2014年开源容器集群管理系统Kubernetes,Kubernetes构建在Docker之上。
图1.5 Google开源容器管理平台
1.4.2 京东与容器
2013年,京东弹性计算云从KVM起步,京东弹性云首先应用于京东私有云上,在选择Docker之前,尝试了KVM虚拟化方案,各方反馈性能不够好,无法满足大促的需求。
2014年10月,京东开始思考用Docker重构,在2014年底,决定采用Docker容器化方案,基于Docker镜像的方式进行发布,其快速的弹性伸缩能力适合京东大规模生产需求,并且其具备轻量、高性能和便捷性的优势。京东首先使用图片系统来验证其性能和弹性伸缩能力,之后再逐步推广到如单品页这样的核心系统,并进行网络的优化,以满足京东应用的性能。
在2015年的618大促中,京东大胆启用了基于Docker的容器技术来承载大促的关键业务(图片展现、单品页、团购页),当时基于Docker容器的弹性云项目已经有近万个Docker容器在线上环境运行,并且经受住了大流量的考验。而今年618,弹性云项目更是担当重任,全部应用系统和大部分的DB服务都跑在Docker上。经受住了2015年618和双11大流量的考验后,2016年双活的数据中心全部采用弹性云进行建设,同时2016年618流量全部落到弹性云上。
图1.6 京东容器架构
1.4.3 阿里与容器
T4是从阿里内部的资源管理和日常运维中土生土长出来的产品,在诞生的第一天就针对内部基础设施、运维工具甚至是运维习惯做了很多特别的设计。
阿里从2015年开始对Docker和T4都做了一些修改整合后,将两者融合为了一个产品,相当于既让T4具备了Docker的镜像能力,又让Docker具备了T4对内部运维体系的友好性,并且能够运行在内部的AliOS5u7和2.6.32内核上。这个产品在阿里内部称为AliDocker。
阿里成立了专门的项目组,快速推进这个事情,目标是把双十一流量覆盖的核心应用全部升级为镜像化模式的Docker应用。2016年双十一最终交易全链路所有核心应用,全部在AliDocker容器中圆满完成了1207亿成交额的答卷,证明了AliDocker技术体系在电商交易级别的大规模应用中能够担负重任!
图1.7 阿里云容器架构
1.4.4 全球用户2016年调研情况
根据CloudFoudry的2016年用户分析报告,目前容器主要用于继续集成开发、微服务资源分享、运行环境的版本控制、操作系统和替换虚拟机。
图1.8 容器主要使用场景
主要使用的容器管集群理平台主要是Docker Swarm、GoogleKubenetes、Amazon ECS等。其他还包括Apache MESOS、Rancher的CATTLE等。
图1.9 容器主要的管集群理平台
1.4.5 持续集成DevOps
以上都是容器在互联网公司生产系统的应用,Docker容器还有一个重要的应用场景,就是开发的持续集成。
传统的开发方式是瀑布开发模式,敏捷开发过程的一个基本原则就是以更快的频率交付最小化可用的软件。在敏捷的目标里,最明显的是在每个Sprint的迭代周期末尾,都具备可以交付的功能。
图1.10 Scrum敏捷开发流程
部署的高频率经常会导致部署堆积在IT运维的面前。敏捷对于开发重新获得商业的信任是大有益处的,但是它无意于将IT运维拒之门外,DevOps使得IT组织作为一个整体重新获得商业的信任。
DevOps不仅仅创建了一个面向IT运维的工作流,当代码已经开发完成但是却无法被部署到生产上时,这些部署就会堆积在IT运维的面前,客户也将因而无法享受到任何价值,更糟糕的是,部署经常导致IT环境的中断和服务不可用。
图1.11 研发运维一体化(DevOps)
DevOps和敏捷软件开发是相辅相成的,因为它拓展和完善了持续集成和发布流程,因此可以确保代码是生产上可用,并且确实能给客户带来价值。
容器为可以实现开发、测试、预生产和生产环境的自动部署,提供整体可视化的主机、容器、网络及存储管理,大幅简化运维人员故障排除和生产部署的工作量。
图1.12 持续集成