以下均翻译自Docker官方文档 ,转载请注明:Vikings翻译。
Docker 是一个开源的平台,设计目标是可以方便开发,方便部署和方便执行应用。使用docker可以快速分发开发好的应用。借助于Docker,你可以将开发平台和应用分离开,并且像管理应用一样管理开发平台。Docker可以帮助你快速开发应用,快速测试应用,快速部署应用,并且缩短开发代码和执行代码之间的周期间隔。
Docker 是凭借一个轻量级容器的虚拟化平台工作流和相关工具来达到上述功能的,并且使用这个轻量化容器来帮助你管理和部署应用。
在Docker核心层,它提供了一种方式来让各种应用运行在各个隔离的容器中。这种方式允许docker同一时间在同一台主机上面运行若干个容器。这种轻量级的容器运行方式,几乎没有额外的运行开销。这意味着你可以充分使用主句的硬件能力。
使用Docker提供的工具和虚拟化平台,你可以完成以下事情:
1、将你的应用或者组件部署到容器中。
2、将你的容器分发给你的团队进行下一步的开发或者测试
3、将你开发的应用部署到发布环境中,无论这些环境是本地模式或者云模式。
1、快速分发应用
Docker可以帮助你把控开发各个周期。Docker允许你在本地的开发环境中进行代码开发,然后将开发好的应用整合到团队的开发流程中。
比如:你可以再本地编写代码,当编写完成后。你将代码开发堆栈信息共享给团队成员。当他们也编写完成后,同样共享开发堆栈信息。然后再测试环境中,使用团队共享的开发堆栈就可以进行所需要的测试了。当完成测试后,团队就可以将测试通过的docker镜像(images)发布到产品环境中。
2、方便部署和易于管理
Docker基于容器的机制可以很容易进行部署。Docker容器可以在本地主机上面执行,也可以在虚拟机中执行,不论这些虚拟机是在本地或者云中。
Docker快速部署和轻量级的特性也使得管理负载变得很容易。你可以快速启动或者销毁容器。这种时间几乎是实时的。
3、可以执行大量的工作负载
因为Docker具有便于部署和快速启停的方式,同时docker也提供了可行的,符合效益-成本的虚拟机管理机制。使得docker很适合负载要求高的环境。比如:将你的云平台作为PAAS用途时,或者你要求你的环境具有高资源使用率时。
Docker主要有两个组件:
Docker:开源的容器虚拟化平台
Docker Hub:一个Software-as-a-Service平台,用来共享和管理docker容器。
Docker采取的C-S结构。Docker client同Docker daemon通讯,Docker daemon负责维护docker 容器的构建,运行和分发。
Client和Daemon可以再同一台主机上面执行,也可以分开执行。本地的client可以连接远程的daemon。Client可以通过socker或者REST API同daemon通讯。
如上图所示,daemon在主机上面执行。用户只能通过client同daemon通讯。
Docker client是用户与Docker之间的重要接口。它从用户那里接受命令,并且将daemon的返回数据展现出来。
为了深入理解docker的内部机制,需要了解以下三个组件:
Docker image是一个只读类型的模板。比如一个镜像可以是一个包含apache和你的web应用的ubuntu操作系统。我们经常使用镜像来创建容器。Docker提供了一种快捷的方式来构建新镜像或者更新镜像,同时你也可以下载其他人已经创建好的镜像。Docker image是Docker结构中的构建组件。
Docker registries用来保存镜像。它分为公开仓库和私有仓库,你可以从仓库中上传或者下载镜像。公开的Docker 仓库称之为"Docker Hub".它提供了你可以使用的非常多的镜像。你可以自由的创建镜像或者使用这里面其他人已经创建好的镜像。Docker registries属于Docker中的分发组件。
Docker containers同目录有几分相似。Docker containers保存了执行应用所需的所有资源。每一个Docker containers都是由image创建的。Docker containers可以run, started, stopped, moved, and deleted。需要注意的是,Docker containers之间是隔离的。Docker containers属于Docker中的执行组件。
目前为止,我们已经可以完成以下几个工作:
1、创建一个包含你需要执行应用的镜像。
2、根据这个镜像,你可以创建一个容器。
3、你可以将这个容器上传到仓库中提供给其他人使用。
下面,我们看一下如何执行Docker。
我们知道Docker containers启动时所以来的Docker images其实是一个只读性质的模板。每个模板都包含若干层。Docker采取了union file systems 的机制将这些曾聚合为一个image。Union file systems 允许物理隔离的文件或者目录,相互重叠覆盖,形成线性的文件系统。
Docker也正是基于上述层的实现方式而做到了轻量级。当你修改一个image时,docker并没有修改原有的image数据,而是新建了一个数据层。当你在docker中修改整个image或者重建实体时,原有数据都没有变化,只是若干层发生了变化。所以当image发生了变化时,不需要重新同步整个image,而只要将发生变化的层同步一次就可以。这样就使docker image做的快速并且简单。
每个image都是从base image演变过来的。你可以创建你的base image。如果你有apache的image,就可以把这个镜像作为你应用程序的base image。
Note:Docker 一般都是从Dock Hub上面获取base images。
Docker通过一些很简单的步骤就可以依据base images创建新的image。每执行一个步骤,新的image就会创建一个新层(layer)。基本的步骤如下:
这些命令可以再Dockerfile中定义。当你需要新建一个image是,docker可以自动读取Dockerfile中的命令,并且执行这些命令。最终生成一个新的image。
Docker registry是用来保存images的。当你新建好image后,就可以将image上传到Dock Hub或者你私有的store中。
借助于Docker client,你可以在Dock Hub检索你所需的image,同时将这些image下载到本地。
同时Dock Hub也提供公开和私有两种模式,处于公开模式下的image,所有人都可以下载和使用这些image。而处于私有模式下的image,只有本人或者经过授权后的人才能下载并且使用这些image。
一个标准容器包括:操作系统,用户自定义的文件和原数据。正如我们所知的那样,每个容器都是由image所创建的。image告诉docker,这个容器运行时,应该有哪些进程和应该有哪些配置参数。因为image是只读的,所以容器在运行时会在image原有层的基础上面创建一些可读可写的新层。而你的应用运行所需的数据将会被记录到这些数据层中。
不论是使用docker程序或者API,docker client都会通知docker daemon如何操作容器。
当我们执行如下命令时:
$ docker run -i -t ubuntu /bin/bash
docker client会启动,然后使用后面的run参数来通知docker daemon启动一个新容器。这个简短的命令将会通知docker daemon以下信息:
1、容器所需的image在哪里,这里image名称是ubuntu,是一个base image。
2、当容器启动时,你想让容器初始化的动作,这里我们需要容器启动时自动切换到/bin/bash下面。
所以当我们敲下回车后,docker将会如何处理呢?
ubuntu
image: Docker 检测image是否存在,如果本地不存在,则默认从Dock Hub下载。如果本地存在,则使用本地的image启动容器。以上是容器的执行过程,下面我们将开始描述如何管理容器,包括:结束,停止和移除。
Docker 底层使用的是Linux内核中的虚拟化技术,来呈现我们刚才所看到的一切功能。
Docker采用了称之为"Namespaces"的技术解决方案来隔离不同的workspace(也就是上面所定义的容器)。当你执行一个容器时,docker会为这个容器创建一系列的namespace。
以下是docker所创建的namespace:
pid
namespace: 用来隔离进程。(PID就是process id)net
namespace: 用来管理网络接口ipc
namespace: 用来控制IPC资源的访问。mnt
namespace: 用来管理挂载点(mnt是 mount point)uts
namespace: 用来隔离内核和版本信息(UTS,分时复用系统 Unix Timesharing System)Docker同时也采用了一种称之为"cgroups"的技术来控制group。不同应用之间隔离的关键在于,每个应用只能访问属于自己的资源。这样才能确保主机上面同时存在多个用户。Cgroups可以确保docker将可用的硬件资源共享给所有容器,并且可以在必要时间,对容器限制硬件资源。例如可以限制每个容器可以访问的内存容量。
Union file systems 或者称为"UnionFS"是docker在创建层时采用的文件系统。这种文件系统使docker变得很轻量级并且执行速度很快。Docker使用UnionFS为容器提供相对应的数据块(data blocks)。Docker可以使用多种类型的UnionFS,比如:AUFS, btrfs, vfs, and DeviceMapper.
Docker将上面我们所描述的各种组件封装成container数据类型(我们就称其为容器)。默认的容器类型是libcontainer。Docker同样也支持传统Linux使用LXC实现的容器类型。再未来,Docker也将支持其他类型的容器,比如:BSD Jails 或者Solaris Zones 版本的容器类型。