一、整体框架
Docker架构概览
由上图可以看出,docker是c/s架构,docker deamon是docker架构的核心部分,API Server用来接收Docker client的请求,然后根据不同的请求分发给不同的模块执行相应的工作。docker的架构是松耦合的,数据卷、网络、镜像、容器运行时的具体实现都已放在daemon以外的模块中。
二、各模块说明
1.首先,了解linux内核提供的三块重要能力:
namespace(命名空间):容器之间资源的隔离(User(用户),Mnt(挂载点),Network(网络),UTS(主机名和域名),IPC(进程间通信的资源如消息队列、信号量、消息队列、共享内存),Pid(进程))依赖的是linux kernel的namespace技术。
cgroups(控制组):提供了资源控制、优先级分配、资源统计、进程控制的能力,限制了各容器的CPU、内存、IO的使用。
UnionFS:Linux 的命名空间和控制组分别解决了不同资源隔离的问题,但是在 Docker 中还有另一个非常重要的问题需要解决 , 也就是镜像。docker的镜像是一系列的只读层组成的,这些层可以在不同容器间共享,启动一个容器,相当于在镜像的最上层添加一个可读写的层,所有对于运行时容器的修改其实就是对这个可读层的修改。存储驱动就是将多个文件系统『联合』到同一个挂载点的文件系统服务。典型的存储驱动有UnionFS、AUFS、devicemapper、overlay2等。
AUFS作用示意图
2.docker的三大驱动说明:
execdriver:是对Linux系统的namespace、cgroups、SElinux等容器运行时所需的系统操作进行的一层二次封装,其本质作用类似于LXC(linux container:一种内核虚拟化技术),但功能更全面。LXC可以作为execdriver的一种实现,当前默认的实现是libcontainer库。
graphdriver:存储驱动,是所有与容器镜像相关操作的最终执行者,常见的有:AUFS、devicemapper、overlay、vfs。它会在docker工作目录下维护一组与镜像层对应的目录,并记录镜像层之间的关系以及与具体graphdriver实现相关的元数据(例如:/var/lib/docker/overlay2目录下link文件记录了本层的标记id,lower文件记录了本层下面关联的所有镜像层的linkid,diff目录记录了本层的元数据;)。这样用户对镜像的操作最终被映射成对这些目录文件以及元数据的增删改查,从而屏蔽掉不同文件存储实现对于上层调用者的影响。
volumedriver:是volume数据卷存储操作的最终执行者,负责卷的增删改查,屏蔽不同驱动实现的区别。docker中作为默认实现的volumedriver是local,默认将文件存储于docker根目录下的volume文件夹里。其他volumedriver均是通过外部插件实现的。
3.docker的2个库的说明:
libcontainer:是对namespace和cgroups的二次封装,execdriver通过对libcontainer来实现对容器的具体管理,资源隔离和资源限制。
libnetwork:docker daemon 通过调用libnetwork对外提供的api完成网络的创建和管理。libnetwork里面包含3种组件(沙盒、端点、网络,这些组件由CNM提供)、5种驱动(bridge、host、overlay、remote、null),各组件的详细作用可以自行查找资料