Docker是为应用的开发和部署提供的“一站式”容器解决方案,它能帮助开发者高效快速的构建应用,实现“Build,Ship and Run Any App, Anywhere”,从而达到“一次构建,到处运行”的目的。
Docker解决了什么问题
Docker项目的发起人Solomon Hykes认为:
Docker在正确的地点,正确的时间顺应了正确的趋势--即高效地构建应用。
随着各种云平台的兴起,开发者或者应用部署者有一种迫切的想要将应用从底层机器环境中脱离的需求,并且还需要让同一个应用在“任何时间任何地点”可以方便地被获取。
传统的方式中,在服务器中搭建一个常见的LAMP(Linux+Apache+Mysql+PHP)网站的步骤:
下载安装Apache,Mysql和PHP以及其它的相关依赖环境。
分别进行配置和测试。
整合到一起进行功能测试。
这种方式操作枯燥繁琐,将不同的软件集成起来的过程中有很多不可控的风险,最无法忍受的是,一旦需要重新迁移服务器或者重新部署一套环境,这样的琐碎和无趣的“体力活”还将重新执行一遍。
针对这个问题,以前我们通常用虚拟机集成部署好一套环境,然后做成一个虚拟机模版来解决。不过这种方式有资源利用率低,灵活性差和迁移平台限制等问题。例如,我们想要的仅仅是一个LAMP环境,但是用这种方式却必须集成打包一个完整的操作系统(每个虚拟机需要单独分配独占的内存,磁盘等资源)。此外,这样打包后的一套LAMP环境中,软件之间版本依赖性强,很难进行变更更新。最后,通常这样的虚拟机还需要绑定特定的虚拟化管理程序来管理,这样对于迁移的平台就有了限制。
如今,Docker通过对Linux容器技术LXC
(Linux Containers)等进一步优化,提供了各种容器管理工具,通过容器来管理应用,这样便可以达到"build once, works everywhere"的目的。也就是说对于开发和部署来说,使用Docker可以:
更快速的交付和部署应用环境。
更高效的资源利用率。
更便捷的迁移和扩展性。
更便捷的应用更新管理。
Docker与虚拟机
Docker和虚拟机都是基于软件的平台虚拟化技术,其中:
虚拟机属于
完全虚拟化
,即模拟完整的底层硬件环境特权指令的执行,客户操作系统无需进行修改。比如我们常用的VirtualBox,VMWare Workstation和Parallels Desktop等虚拟化软件。Docker和其它容器技术便是
操作系统级虚拟化
,即直接通过内核创建虚拟的操作系统实例(内核和库),来隔离不同的进程和资源。
也就是说,Docker容器不需要额外的虚拟机管理软件和虚拟机操作系统层,直接在宿主机操作系统层面上实现虚拟化,从而达到轻量级,高效的目的。如下图所示(源自what-docker),左侧是传统的虚拟化方式,右侧是Docker虚拟化的方式。很显然,Docker的虚拟化方式没有了虚拟机管理程序Hypervisor和虚拟机操作系统Guest OS层,取而代之的是Docker Engine容器支持层。
Docker中不仔需要为不同的应用启动相应的虚拟机了,直接在Docker容器中运行应用,并不需要消耗额外的系统的资源。因此,Docker的启动速度很快,通常可以达到秒级,而传统的虚拟机基本是分钟级。
关于Docker中使用的容器技术和虚拟机性能的比较,IBM的一份研究报告An Updated Performance Comparison of Virtual Machines and Linux Containers.中通过试验得出结论表示,通常情况下,Docker容器技术的性能等同或超出使用KVM的性能。当然,在CPU和内存性能方面,KVM和Docker一样都有明显的但可忽略不计的开销。同时,对于I/O密集型的应用,Docker和KVM也都需要进行调整来减少开销带来的影响。
在隔离性方面,传统虚拟机使用的是完全隔离,而Docker利用的是Linux系统的多种安全防护机制,从这个角度来看,传统虚拟机比Docker多一层额外的隔离。当然,这并不意味着,Docker就不安全,Docker使用了多种机制如安全选项和镜像签名机制等来保障使用Docker的安全性(Docker Doc:Introduction to Container Security。
Docker核心概念
接下来, 我们通过源自官网的Docker Architecture图,来详细阐述说明Docker的核心概念,其中主要构成:
Docker Client
是Docker的主要的用户管理接口,也就是docker
命令行管理界面,用户与Docker Client
打交道,通过它与Docker Daemon
守护进程进行交互,进而管理Docker中的Containers容器。Docker Daemon
是运行在主机上的一个守护进程。其中Docker Client
和Docker Daemon
可以运行在同一个主机中,也可以通过Docker Client
连接远程主机的Docker daemon。Registry
是注册服务器,注册服务器是存放仓库(Repository
)的具体服务器。
此外,Docker的核心概念中还包括镜像(Images),容器(Container)和仓库(Repository),其中:
Docker镜像(
Images
)可以类比传统的虚拟机中的模版,我们可以简单将其理解成一个面向Docker Engine且包含文件系统的只读模版。Docker容器(
Containers
),容器Containers相当于镜像Images的一个运行实例。镜像本身是只读且保存不变的,容器在启动镜像时,Docker会在镜像的最上层创建一个可写文件层。因此,也可以看出,容器才是直接提供一个或一组应用服务,以及它们的必需运行环境的组件。Docker仓库(
Repository
),是集中存放镜像的地方,我们可以把它看成是一组镜像的集合或者一个具体的项目,因为通常一个完整的应用是由很多镜像堆积而成的。如下图所示,便是官网公共库https://hub.docker.com 中的repostitories列表,很显然一个repository相当于一个完整的项目。
Docker容器运行过程
接下来, 我们还是通过源自官网的Docker Architecture图,使用docker run ubuntu /bin/echo 'Hello world'
命令为例子,来阐述一个Docker容器运行的整体过程。
当我们使用docker run
运行下载自官网的ubuntu
repository(其实也就是ubuntu镜像)时,Docker在后台运行的一整套标准操作包括:
docker daemon检查本地是否存在ubuntu镜像,不存在就从公有Registry仓库中下载。
使用ubuntu镜像创建并启动一个容器。
分配一个文件系统,并在只读的镜像层外面挂载一层可读写层。
从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去。
从地址池配置一个 ip 地址给容器。
执行用户指定的应用程序
/bin/echo 'Hello world'
。执行完毕后,容器被终止。
参考&引用
[1] Docker White Paper: Intro to Container Security
[2] 杨保华, 戴王剑,曹亚仑.(2015).Docker技术入门与实战.机械工业出版社.
[3] Wes Felter, Alexandre Ferreira, Ram Rajamony, Juan Rubio.(2014).IBM Research Report:An Updated Performance Comparison of Virtual Machines and Linux Containers.
[4] Docker Doc:Introduction to Container Security
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。