架构
Docker是典型的C/S架构,主要由docker-client和docker-daemon组成。docker-daemon的架构在不断演进中,将不同功能抽离成独立的模块,降低docker-daemon的复杂度。因此,不同版本docker对应的架构图、源码等可能都有所差异。文中出现的相关架构图、源码等都以Docker 1.10版本为主。
我们以一个下面我们以容器的创建过程为例,简单介绍下各个模块的协作关系。
- 输入 docker run -it ubuntu bash 命令运行一个容器时,首先会通过docker client 向 docker daemon发起创建命令。
- 此时daemon会向image management模块发起请求,如果本地没有镜像,则由其中的distribution和register模块从远端的镜像仓库获取镜像,然后通过image、reference、layer等存储镜像的元数据,最后交由graphdriver模块存入操作系统的文件系统中。
- 此时docker daemon会通过libnetwork创建对应的网络、通过libcontainer模块创建对应的namespace、CGroups等所需的资源隔离和限制资源、通过volume 创建对应的volume资源等
- 最后返回客户端结果
Docker client
Docker client用来向docker daemon发起请求,所有实现了Docker全部或部分API的都可以称为docker client。
Docker daemon
Docker daemon是Docker架构中主要的用户接口,他提供了API Server模块,对Docker client暴露对应的操作API,并根据操作的不同,分发给不同模块执行相应的功能。在之前的老版本中,Docker daemon实现了Docker拥有的大部分功能。但是社区一直在对Docker daemon进行解耦,在1.10版本中,Docker已将容器运行时、volume、镜像管理模块独立到其他模块或者项目中。
libcontainer
针对Linux操作系统namespace和cgroups的封装,提供上层对于容器运行时的管理。
libnetwork
在Docker1.9之前,容器的网络是由docker的networkdriver模块和libcontainer模块共同完成,从Docker1.10开始,由libnetwork库独立负责。他抽象出了容器网络模型(Container Network Model,CNM),对外提供统一的调用接口。CNM模型中,抽象了sandbox、endpoint、network三类资源,具体的实现交由具体的网络驱动实现,包括创建namespace、虚拟网卡、分配ip、端口映射、hosts、域名、iptables等。
Image Management
Image Management主要的功能是提供镜像管理的相关接口和实现,主要由distribution、register、layer、image、reference等模块组成。
- distribution:主要负责与镜像仓库(Docker register模块)交互,负责上传和下载镜像以及保存一些和仓库相关的元信息
- register:该模块主要与镜像仓库(Docker register模块)交互,进行身份认证、镜像查找及验证等操作
- image:负责镜像元数据相关的查找、存储等,负责镜像层的索引、查找以及镜像tar包的导入和导出等
- reference:负责存储本地镜像的repo和tag名,维护其和镜像ID的映射关系
- layer:负责镜像层元数据的增删改查,并将对应的操作映射到graphdriver相关的文件操作
*driver
Docker为了对docker daemon屏蔽底层操作的差异、提供统一接口,Docker对于主要功能做了抽象,定义了一些驱动,根据功能类型的不同,Docker定义了三种驱动(镜像存储驱动、执行驱动、挂载卷驱动):
- graphdriver:所有镜像相关管理操作在操作系统层面的执行者,通过Image Management的相关镜像的CURD都会转换成 graphdriver 对于文件系统的操作。graphdriver通过维护一组目录或者文件和对应的镜像层的关系,将底层文件系统的细节屏蔽掉,对于上层Image Management来说,只需要针对元数据进行CURD,并不需要关心底层文件系统的具体差异,例如:屏蔽底层文件系统vfs、overlay差异和操作细节等。
- execdriver:对于容器运行时的封装,主要封装了Linux中的namespace、cgroups、SELinux等容器运行所需要的系统操作。最主要的实现,也是Docker默认使用的实现就是libcontainer模块。
- volumedriver:提供挂载卷的操作接口,对上层docker daemon屏蔽底层文件系统差异,其主要通过插件实现,docker中默认实现是local vloume,其他实现通过volume 插件的形式实现。