什么是Docker?
Docker,对于开发、转移以及运行应用,是一个开发平台。Docker的初衷是使应用的交付更快。借助Docker可以将应用从基础环境上分离出来,使对待基础环境像被管理的应用一样。Docker使代码的转移、测试、部署更快,缩短写代码运行代码的周期。
Docker通过整合轻量级的容器虚拟化平台与工作流,提供管理和部署应用的工具来实现设计的初衷。
Docker核心提供了几乎可以使任何应用安全独立运行于容器的方法。独立与安全允许你在主机同时运行多个容器。容器轻量级的特征,不需要加载额外的监管程序,意味着可以在硬件获得更多的资源。
围绕容器虚拟化的工具和整个平台,可以提供一下帮助:
- 应用或者组件运行在Docker容器中
- 向分配和转移这些容器,便于以后的开发与测试。
- 部署这些应用到生产环境,例如:本地数据中心或者云。
Docker可以做什么?
- 应用的更快交付
Docker有助于完善开发生命周期。Docker允许开发在包含应用和服务的本地容器上开发。它也可以整合到持续集成和部署的开发流程中。
例如:开发者写入本地代码,通过Docker与其他同事分享开发栈。当他们准备好了,可以推送代码和正开开发的栈到测试环境,然后执行测试用例。从测试环境推送Docker镜像到生产环境和部署代码。
- 部署和扩展更容易
Docker基于容器的平台模式具有更高的可移植性。Docker容器可以运行在本地开发者主机,在数据中心或者云上的物理或者虚拟主机。
Docker可移植和轻量级的特性有利于动态管理工作负载。使用Docker可以更快的扩展或者拆毁应用和服务。Docker的扩展速度几乎接近实时。
- 实现高密度和更高的负载
Docker的轻量级和快速。它提供了一个可行的、高效益的方案来替代基于hypervisor的虚拟机。在高密度环境特别有用:构建自己云或者平台作为服务。但是对于中小型部署环境依然很有效,可以获得更多的资源。
Docker的主要组件是什么?
Docker含有两个主要组件:
Docker:开源容器的虚拟化平台
Docker Hub:分享和管理Docker容器的Software-as-a-Service平台
注意:Docker被授权在开发Apache2.0授权下。
Docker使用CS架构。Docker客户端与Docker守护进程建立会话,守护进程繁重管理、运行和分配Docker容器。Docker客户端和守护进程都可以运行在同样的系统上,或者Docker客户端连接一个远程的守护进程。Docker的客户端和守护进程通信可以通过套接字或者REST式的API。
Docker守护进程
如上图所示,Docker守护进程运行在主机上。用户不会对守护进程直接影响,需要通过Docker客户端。
Docker客户端
docker而二进制形式的Docker客户端是主要的用户接口。它接收用户的指令,与守护进程的沟通。
Docker内部
为了理解Docker的内部构建,需要知道三个部件:
- Docker images
- Docker registries
- Docker container
Docker images
Docker image是一个只读的模板。例如,一个image可以包含一个安装Apache和web应用的Ubuntu操作系统。Images被用于创建Docker containers。Docker提供了一个简单的方法去构建新的images或者更新已经存在的images,也可以下载别人创建的images。Docker images是Docker的build组件。
Docker Registries
Docker Registries管理images。有私有的或者公用的商店提供上传或者下载images。公用的Docker Registry被称作Docker Hub。它提供很多已经存在的image供用户使用。这些images可能是你自己创建的,也可以使别人之前创建的。Docker register是Docker的distribution组件。
Docker container
Docker containers类似于一个目录。一个Docker container持有一个应用运行所需要的所有东西。每一个container由Docker image创建。Docker container能够运行、启动、停止、移动和删除。每一个container是一个独立和安全的应用平台。Docker container是Docker的run组件。
Docker是如何工作的?
到目前为止,已经学习了:
1. 构建一个应用的Docker的images。
2. 通过Docker images创建Docker container来运行应用。
3. 通过Docker Hub或者私有的registry来分享这些Docker images。
来看一下这些元素是如何连接起来使Docker工作的。
Docker Image是如何工作的?
Docker image是已经发布的Docker container的一个只读模板。每一个image有一系列的层组成。Docker使用union file systems来整合这些层到单一的image中。union file systems允许分离的文件系统中的文件和目录,称为分支,透明的覆盖重写,形成单个关联的文件系统。
Docker如此轻量级的原因之一是这些层。当改变一个Docke image,例如:更新一个应用到一个新的版本,一个新的层被构建。因此,不需要像在虚拟机上哪像替代整个image或者整个重构,只需要将层添加或者更新。现在,不需要分发整个新image,只需要更新,这是的分发Docker image更快、更简单。
每一个image来源于一个基本的image,例如Ubuntu,一个基本的Ubuntu image或者Fedora,一个基本的Fedora image。也可以使用自己的images作为基础image创建新的image。如果有一个Apache image,你可以使用这个image作为你的WEB应用image的基本image。
注意:Docker通常通过Docker Hub获得这些基本images。
Docker images的构建基于基础images,通过一系列简单、描述性的指令。每一个指令在image中创建一个新的层。指令包括以下动作:
- 运行一个命令
- 添加一个文件或者目录
- 创建一个环境变量
- 当从image运行一个容器时,控制那个进程去运行
这些指令存储在一个文件名为:Dockerfile的文件中。当请求构建一个image,Docker读取Dockerfile,执行指令,返回最终的image。
Docker registry是如何工作的?
Docker registry是Docker images的商店。一旦你构建了Docker image,可以将他推送至公共的registry Docker Hub或者运行在你防火墙后面的私有registry。
使用Docker Client,你可以搜索已经发布的images,然后下载它们到你的Docker主机,然后基于它们构建container。
Docker Hub提供公共和私有的images存储。公共的存储可以被任何人搜索和下载。私有存储不能被搜索,只有你或者你的用户可以下载,使用它们构建容器。
container是如何工作的?
container由操作系统、用户文件、媒体数据等组成。每一个container由image构建。image告诉Docker这个container需要什么,哪些进程需要在container运行时运行,和其他的多种配置数据。Docker image是只读的。当Docker运行container从image,它附加一个读写层在image上(使用union file system),在这个里我们运行应用。
运行container时会发生什么?
通过docker二进制或者通过API,Docker client告诉Docker 守护进程运行一个container。
$ sudo docker run -i -t ubuntu /bin/bash
分析这个命令。Docker client使用docker 二进制运行,通过run选项告诉它运行一个新的container。告诉Docker守护进程Docker client运行container需要的最低限度:
- 这个container构建来源于哪个image,这里是Ubuntu,一个基本的Ubuntu image。
- 当容器启动,希望在容器里运行的命令方式。这里是/bin/bash,启动bash shell在新容器中。
当运行了这个命令,Docker发生了什么?
按照次序,Docker做了以下事情:
推送Ubuntu image:Docker检查存在的Ubuntu image,如果本地主机上不存在,Docker从Docker Hub上下载。如果本地已经存在,Docker使用这个来创建新的container。
创建一个新容器:一旦Docker有了image,就使用这个来创建container。
分配文件系统和加载一个读写层:容器在文件系统上创建,读写层附加在image上。
分配网络/网桥接口:创建一个网络接口来使容器能够与本地主机通信。
创建IP地址:从IP地址池中发现和附加一个可用的IP地址。
执行一个指定的进程:运行应用等。
捕获和提供应用输出:连接和记录标准的输入、输出和错误,来提供你看到应用是如何运行的。
底层技术
Docker由GO语言编写,使用了若干的Linux内核的特性来提供我们见到的功能。
Namespaces
Docker利用命名空间的技术优势来提供称为容器的独立工作空间。当运行container时,Docker为container创建了一套命令空间namespace。
提供了层独立性:容器的每一个层面允在自己的命名空间内,没有与外界的访问。
Docker使用的一下命名空间:
pid:独立进程(Process ID)
net:管理network接口(Networking)
ipc:管理IPC resources的访问(InterProcess Communication)
mnt:管理挂载点(Mount)
uts:独立内核和版本标识(Unix Timesharing System)
Control groups
Docker使用另外一种技术叫做cgroups或者control groups。独立的运行应用,只使用需要的资源。这保证了containers能够很好的在多租户的主机上运行。Control groups允许Docker在containers间分享可用的硬件资源,如果需要可以建立限制和约束。例如:限制某个特定容器的内存可用大小。
Union file systems
Union file systems或者UnionFS是创建层的文件系统,使它们更加轻量级和快。Docker使用union file systems提供container的构建快。Docker使用若干个union file system的变体,包括:AUFS、btrfs、vfs和DeviceMapper。
Container format
Docker 整合这些组件到一个集合,我们称为container format。这个默认的container format被称为libcontainer。Docker也支持传统的Linux container,LXC。在未来,Docker可以支持其他的容器格式,例如:整合BSD Jails或者Solaris Zones.