Docker简介

Docker的概念

Docker最初是dotCloud公司的内部项目,是基于dotCloud公司多年云服务的一次革新,于2013年3月开源。Docker被称为第三代Paas平台,是一种容器(虚拟化的轻量级替代技术)技术,将应用软件及其依赖软件(运行时环境、系统工具、系统库)等打包在容器中,使应用具备完整性、移植性和隔离性。以容器的方式交付应用,可以让应用无差别地运行在开发、测试、生产环境,提供标准化的环境和标准化的交付、标准化的部署。

Dcoker的技术依赖

Docker使用Go语言进行开发实现,基于Linux内核的cgroupnamespace以及AUFS类的UnionFS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其他的隔离的进程,因此也称其为容器。最初实现是基于LXC、0.7后去除LXC,使用自行开发的libcontainer。从1.11开始,则使用runCcontainerd

(1)cgroup是将任意进程进行分组化管理的Linux内核功能。重要概念是子系统,即资源控制器。先挂载子系统,然后在子系统中创建一个control group节点,将需要控制的进程id和属性写入,从而完成内存的资源限制。
(2)LXC(Linux containers),一种基于容器的操作系统层级的虚拟技术,借助于namespace的隔离机制和cgroup限额功能,提供了一套统一的API和工具来建立和管理container,旨在提供一个共享kernel的OS级虚拟化方法。
(3)AUFS是一个能透明覆盖一或多个现有文件系统的层状文件系统,支持将不同目录挂载到同一个虚拟文件系统下,可以把不同的目录联合在一起,组成一个单一的目录。
(4)App打包:Docker额外提供的Feature,标准统一的打包部署运行方案。

Docker的优势

Docker在容器的基础上,进行了进一步封装,从文件系统、网络互联到进程隔离等,极大地简化了容器的创建和维护,使得Docker技术比虚拟机技术更为轻便、快捷。Docker和传统虚拟化方式的不同:传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上运行所需的应用进程;而容器内的应用进程直接运行于宿主的内核,没有自己的内核,而且也没有进行硬件虚拟,所以容器更为轻便。

(1)更高效的利用系统资源
由于容器不需要硬件虚拟化以及运行完整的操作系统等额外开销,Docker对系统的资源利用率更高。因此一个相同配置的主机,可以运行更多应用。
(2)更快速的启动
Docker容器应用由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级,甚至毫秒级的启动,大大节约了开发、测试、部署的时间。
(3)一致的运行环境
Docker镜像提供了除内核外完整的运行时环境,确保了应用运行环境的一致性。
(4)持续交付和部署
Docker可以通过定制应用镜像实现持续集成、持续交付、部署。开发人员可以通过Dockerfile来创建镜像,并结合持续集成(Continuous integration)系统进行集成测试,而运维人员则可以直接在生成环境中快速部署该镜像,甚至结合持续部署(Continuous Delivery/Deployment)系统进行自动部署。而且使用Dockerfile使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需环境,帮助更好地部署该镜像。
(5)更轻松的迁移
由于Docker确保了运行环境的一致性,使得应用迁移更加容易。
(6)更轻松的维护和扩展
Docker使用的分层存储以及镜像技术,使得应用重复部分的复用更容易,也使得维护更新更容易,扩展镜像更容易.

Docker相关的基础概念

Docker Image

操作系统分为内核和用户空间。对于Linux而言,内核启动后,会挂载root文件系统为其提供用户空间支持。Docker镜像(Image)就相当于是一个root文件系统。Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含一些为运行时准备的配置参数(如匿名卷,环境变量,用户等)。镜像不包含任何动态数据,其内容在构建后也不会被改变。

分层存储

因为传统镜像包含操作系统完整的root文件系统,其体积往往庞大。因此在Docker设计时,就充分利用Union FS技术,将其设计为分层存储的架构。所以严格来说,Docker镜像并非像ISO那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说由多层文件系统联合组成。

镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除某一层文件时,仅在当前层标记为该文件已经删除,但实际该文件会一直跟随镜像。因此构建镜像时,每一层尽量只包含该层需要添加东西,任何额外的东西应在该层构建结束前清理结束
分层存储使得镜像的复用、定制、甚至以此为基础构建新的镜像变得更容易。

Docker Container

镜像(Image)是静态定义,容器(Container)是镜像运行时的实体。容器可以被创建、启动、停止等。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的root文件系统、网络配置、进程空间,甚至自己的用户ID空间。容器内的进程是运行在一个隔离的环境中,使用起来,就像是在一个独立于宿主的系统下操作。这特性使得容器封装的应用比直接在宿主机运行更安全。
容器也是分层存储的,每个容器运行时以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层
容器存储层的生存周期和容器周期一样,容器消亡时,容器存储层随之消失。

按照Docker最佳实践的要求:容器不应该向存储层写入任何数据,容器存储层要保持无状态化。所有文件写入操作,都应该使用数据卷或者绑定宿主机目录,在这些位置的读取会跳过容器存储层,直接对宿主或网络存储发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器,不随着容器消亡。

Docker Registry

镜像构建完成后,可以很容易地在本地运行。但如需在其他服务器使用该镜像,就需要一个集中的存储、分发镜像的服务,即Docker Registry
一个Docker Registry包含多个仓库(Repository);每个仓库包含多个标签Tag;每个Tag对应一个镜像。通常一个仓库中会包含同一个软件不同版本的镜像,而标签就对应该软件的各个版本。我们可以通过<仓库名>:<标签>来获取指定版本的镜像,如果不给出标签,就将以latest为默认标签。
Docker Registry公开服务是开放给用户使用、允许用户管理镜像的服务,一般允许用户免费上传、下载公开的镜像。最常使用的Registry公开服务就是官方的Docker Hub
除了公开服务外,用户还可以在本地搭建私有的Docker Registry。Docker官方提供Docker Registry镜像,可以直接使用作为私有Registry服务。