docker overview
docker是一个可以开发、传输和运行程序的开放平台。Docker让我们可以将应用程序从基础架构中拆分出来,这样我们就可以快速的分发我们的软件。使用Docker,可以像管理应用程序一样去管理基础设施。利用Docker的方法学快速的去传输、测试和部署代码,我们能明显缩短代码的编写到部署上线的时间。也就是说,Docker将应用程序和底层基础设施结偶,可以明显加快应用程序的迭代速度,这一点对于业务发展迅速的互联网公司十分重要。
Docker平台
Docker为我们提供在一种被称为容器这一相对隔离程度较低的环境中打包和运行应用程序的能力。隔离性和安全性允许我们可以在一台主机上同时运行多个容器。容器是轻量级的,因为他们不需要像虚拟机一样引入hypervisor的额外性能消耗,而是直接运行在主机的内核里面。这意味着比起使用虚拟机,我们可以在一台宿主机上运行更多的容器,我们甚至可以在虚拟机上运行Docker容器。
Docker提供工具和平台来管理容器的生命周期:
- 使用容器来开发应用程序和对应的依赖;
- 容器成为应用程序分发和测试的单元;
- 当一切就绪后,将应用程序部署到生产环境,作为一个容器或者被编排的服务。无论你的生产环境是本地数据中心、云环境或者两者的混合,这些容器运行效果是一致的;
Docker引擎
docker引擎是个client-server的应用,包含如下组件:
- dockerd守护进程,作为docker server;
- REST API:指定了和dockerd进程如何交互以及能执行哪些指令;
- docker CLI client:docker的命令行客户端
CLI通过脚本或者直接的CLI命令使用docker REST API来控制或者和Docker守护进程交互。
一些其他的Docker应用使用底层的API和CLI。
守护进程负责创建和管理docker对象:
- image
- container
- networks
- volums
Docker的用处
快速持续分发应用。
Docker通过允许开发者使用本地容器来在标准化环境中进行开发,从而使得应用程序开发生命周期流程化。容器很好的支持了持续集成和持续分发。
考虑下面的场景:
- 开发者本地编写代码,使用Docker容器将代码分享给同事;
- 他们使用Docker将应用推送到测试环境,然后执行自动和手动测试;
- 当开发者发现 bugs的时候,他们在开发环境修复bug,然后再一次将其部署到测试环境进行测试验证;
- 当测试完毕以后,使得fix线上生效,仅仅需要将被更新的镜像推送到生产环境即可;
响应式开发和伸缩
Docker给予容器的平台允许高度可移植的工作流。Docker容器能运行在开发者的笔记本,在物理或者虚拟机上,在云环境中,或者在这些环境的混合环境中。
在相同的硬件上运行更多的工作流
Docker是轻量级和快速的。它提供一个可行的、经济的替代给予hypervisor虚拟机的方案,因此你能使用计算机资源更多的来完成业务目标。Docker完美支持高密度环境,对于中小型开发,你可以使用较少的资源做更多的事情。
Docker架构
Docker架构图:
- Client:docker client
- Docker Host:物理机
- Registry:docker镜像仓库
- Docker daemon:
dockerd监听Docker API的请求,然后管理类似镜像、容器、网络和卷。一个守护进程也能和其他守护进程进行通信从而来管理Docker服务。 - Docker client
docker client docker是一些docker用户和Docker交互的主要方式。当你使用类似docker run的命令,客户端将这些命令发送给dockerd守护进程,由dockerd负责解释执行。docker使用Docker API。Docker client也能和多个守护进程通信。 - Docker registries
docker registry存储Docker镜像。Docker Hub和Docker Cloud是公开的registry,任何人都能访问 使用它。Docker默认配置是去Docker Hub上搜索镜像。你能搭建自己的私有docker registry。
当你使用docker pull或者docker run命令的时候,被需要的镜像将会从你配置的resigtry中拉取下来。当你使用docker push的时候,你的镜像会被推送到你配置的registry。
Docker store运行你购买和售卖Docker镜像或者免费发布他们。例如,你可以购买一个包含软件提供商提供的服务或程序的镜像,然后使用这个镜像来将程序部署到你的测试 预发和生产环境。对于更新,你仅仅需要拉取一个新版本的镜像,然后重新部署这个容器即可。
Docker objects
当你使用docker的时候,你正在创建和使用镜像、容器、网路、卷、插件和其他对象。下面是对一些对象的简要介绍。
- images
镜像是一个含有创建一个Docker容器指令的只读模版。通常,一个镜像是基于另一个镜像加上一些定制化。例如,你也许基于Ubuntu镜像构建了一个新的镜像,但是这个新的镜像中安装了Apache Web Server和你的应用程序,同时还有一些程序运行的配置细节。
你可以创建你自己的镜像或者使用别人创建的发布在registry商现成的镜像。为了构建你自己的镜像,你性能使用简单语法创建一个Dockerfile,这个文件定义了创建一个镜像和运行它的必要步骤。在Dockerfile中的每个指令都会在镜像中创建一层。当你改变Dockerfile然后重新构建镜像的时候,仅仅那些发生实际改变的层才会被重新构建。这就是使得镜像相对于其他虚拟化技术更加轻量快速的原因之一。
- containers
一个容器是镜像的可运行的实例。你能使用Docker API或者CLI创建、启动、停止、移动或者删除一个容器。你也能将一个容器链接到一个或多个网络,给容器附加存储,甚至基于当前的状态构建新的镜像。
默认的,容器与容器之间、容器与宿主机之间还是相对隔离的很好的。你可以控制一个容器的网络、存储或者其他底层子系统是如何同其他容器或者宿主机隔离的。
当你创建或者启动一个容器的时候,镜像和一些你提供的配置就定义一个容器。当一个容器被移除的时候,任何没有进行持久存储的状态改变都将丢失。
docker run命令的例子:
下面的命令运行一个ubuntu容器,交互式的将本地的命令行会话附加到容器,然后执行/bin/bash命令。
docker run -i -t ubuntu /bin/bash
当你运行这个命令的时候,会发生下面的事情:
- 如果你没有ubuntu镜像在本地,Docker将从你配置的registry中拉取,正如你手动执行 docker pull ubuntu一样。
- Docker创建一个新的容器,正如你手动运行docker container create命令。
- Docker分配一个读写文件系统给该容器,作为它的final layer。这个允许一个运行的容器能够在他自己的文件系统里面创建或者修改文件和目录。
- Docker创建一个网络接口来将容器链接到默认的网络,因为你没有指定网络选项。这个包括指定一个IP地址给容器。默认的,容器能够使用宿主机的网络连接到外部网络。
- Docker启动容器然后执行 /bin/bash命令。因为容器正在以交互式模式在运行,且已经附加到你的终端,所以你能够使用你的键盘进行输入,同时输出也会log到你的终端上。
- 当你敲击exit来结束/bin/bash命令的时候,这个容器停止但是没有被移除,你可以启动它或者移除它。
- service
Service允许你能跨多个Docker守护进程进行容器的伸缩,这些工作起来就像是一个拥有多个manager和worker的群体swarm。每个swarm的成员就是一个Docker守护进程,这些守护进程使用Dokcer API进行通信。一个服务运行你定一个期望的状态,例如服务热备份的数量。默认的,服务是跨所有work节点进行负载均衡的。对于服务消费者,Docker服务好像是一个应用。从Docker1.12开始,Docker引擎支持swarm模式。
底层技术
- NameSpace
Docker使用Linux提供的namespace功能提供隔离的工作空间,这个叫做容器。当创建一个docker容器的时候,docker会为这个容器创建一系列的namespace。
namespace提供一个隔离层。运行在不同的namespace的容器,每一项访问都限制在自己对应的namespace里面。
Docker引擎在linux上面使用下面的namspace:
- pid 进程隔离
- net:管理网络接口
- ipc:管理ipc资源的访问
- mnt:管理文件系统挂载点
- uts:隔离内核和版本标志(uts:unix timesharing system)
- Cgroup
在Linux上的Docker引擎也依赖control groups简称cgroup技术。一个cgroup限制一个应用使用指定的资源集合。cgroup允许docker引擎让容器共享硬件资源,同时施加一些限制和约束。例如,我们可以对某个容器限制其可用的内存大小。
- UnionFS
Union File Systems通过创建不同的层,来达到非常轻量快速的目的。Docker引擎使用UFS为容器提供构建块。Docker Image的分层就是利用UnionFS来实现的。
- libcontainer
Docker将namespace、cgroup、ufs结合在一起成为了一个wrapper,格式为libcontainer。