当前位置: 首页 > 科技观察

9张图让你深入了解Docker架构!

时间:2023-03-12 02:15:43 科技观察

Docker的整体架构Docker是C/S模型架构,后端是松耦合架构,各模块各司其职。下图是它的整体架构图:1.用户使用DockerClient与DockerDaemon建立通信,向后者发送请求。2.DockerDaemon作为Docker架构的主体部分,首先提供了DockerServer的功能,使其能够接受来自DockerClient的请求。3、DockerEngine在Docker内部执行一系列作业,每个作业以Job的形式存在。4.作业运行过程中,需要容器镜像时,从DockerRegistry下载镜像,通过镜像管理驱动Graphdriver将下载的镜像以Graph的形式存储。5、当需要为Docker创建网络环境时,通过网络管理驱动Networkdriver创建并配置Docker容器网络环境。6、当需要限制Docker容器的运行资源或执行用户指令等操作时,通过Execdriver来完成。7.Libcontainer是一个独立的容器管理包。Networkdriver和Execdriver都是通过Libcontainer实现对容器的具体操作。Docker各模块组件解析一、DockerClient“发起请求”1、DockerClient是与DockerDaemon建立通信的客户端。用户使用的可执行文件是docker(一个命令行可执行文件)。docker命令使用后续参数的形式来实现一个完整的请求命令(例如:dockerimages,docker是不可变命令,images是可变参数)。2、DockerClient可以通过以下三种方式与DockerDaemon建立通信:tcp://host:port、unix://pathtosocket和fd://socketfd3。DockerClient发送容器管理请求后,会被DockerDaemonRequest接受并处理,当DockerClient收到返回的请求并简单处理后,一个完整的DockerClient生命周期就结束了。(一个完整的请求:发送请求→处理请求→返回结果),与传统的C/S架构请求流程没有区别。二、DockerDaemon(后台守护进程)Dockerdaemon架构图:DockerServer架构图:1.DockerServer相当于C/S架构的服务器。功能是接受和调度DockerClient发送的请求。DockerServer接受请求后,通过路由和分发调度找到对应的Handler执行请求。2.Docker在启动过程中,通过包gorilla/mux创建了一个mux.Router,提供请求的路由功能。gorilla/mux是Golang中功能强大的URL路由器和调度程序。mux.Router中添加了很多路由项,每个路由项由三部分组成:HTTP请求方法(PUT、POST、GET或DELETE)、URL、Handler。3、创建mux.Router后,Docker以服务器的监听地址和mux.Router为参数,创建一个httpSrv=http.Server{},最后执行httpSrv.Serve()为请求服务。4、在DockerServer的服务过程中,DockerServer在listener上接受DockerClient的访问请求,并创建一个全新的goroutine来为请求服务。在goroutine中,首先读取请求内容并做解析工作,然后找到对应的路由项并调用对应的Handler处理请求,最后Handler处理完请求后回复请求。3、DockerEngine1、DockerEngine是Docker架构中的运行引擎,也是Docker运行的核心模块。它扮演着一个DockerContainer存储仓库的角色,通过执行Jobs来操作和管理这些容器。2、在DockerEngine数据结构的设计和实现过程中,有一个Handler对象。Handler对象存储特定Job的所有Handler处理访问。例子:DockerEngine的Handler对象中有一项:{“create”:daemon.ContainerCreate,},意思是当名为“create”的Job运行时,会执行daemon.ContainerCreate的Handler。Job1,一个Job可以认为是Docker架构中DockerEngine内部最基本的工作执行单元。Docker可以做的每一个工作都可以抽象成一个Job。例如:在容器内运行进程是一项工作;创建一个新容器是一项工作。DockerServer的运行进程也是一个名为ServeApi的Job。2、Job的设计者将Job设计得类似于Unix进程。例如:Job有名称、参数、环境变量、标准输入输出、错误处理、返回状态。四、DockerRegistry(镜像注册中心)1、DockerRegistry是一个存放容器镜像的仓库(注册中心),可以理解为云镜像仓库。按Repository分类,dockerpull根据[repository]:[tag]精确定义一个具体的Image。2、在Docker运行过程中,DockerDaemon会与DockerRegistry通信,实现搜索镜像、下载镜像、上传镜像三个功能。这三个功能对应的作业名称是:“search”、“pull”和“push”。3DockerRegistry可以分为公共仓库(DockerHub)和私有仓库。5.Graph“Docker内部数据库”Graph架构图:Repository1,下载镜像(包括下载镜像和Dockerfile构建的镜像)的保管者。搜索公众号顶级建筑师,回复关键词“整洁结构”,即可获得惊喜礼包。2、一个Repository代表某种类型的镜像仓库(例如:Ubuntu),同一个Repository中的镜像通过Tag来区分(代表不同的tag或者同一类镜像的版本)。一个Registry包含多个Repositories,一个Repository包含多个相同类型的Images。3、镜像存储类型有Aufs、Devicemapper、Btrfs、Vfs等,其中CentOS7.x以下版本使用Devicemapper存储类型。4、同时在Graph的本地目录中存储了每个容器镜像的具体信息,包括:容器镜像的元数据、容器镜像的大小信息、容器镜像所代表的具体rootfs。GraphDB1,下载容器镜像之间关系的记录器。2、GraphDB是建立在SQLite之上的小型数据库,实现了节点的命名和节点间关系的记录。6.Driver“执行部分”Driver是Docker架构中的驱动模块。通过Driver驱动,Docker可以实现Docker容器执行环境的定制化。即Graph负责图片存储,Driver负责容器执行。GraphdriverGraphdriver架构图:1.Graphdriver主要用于完成容器镜像的管理,包括存储和获取。2、存储:dockerpull下载的镜像,由Graphdriver存储在本地指定目录(Graph中)。3、获取:dockerrun(create)使用镜像创建容器时,Graphdriver从本地Graph中获取镜像。NetworkdriverNetworkdriver架构图:Networkdriver的目的是完成Docker容器网络环境的配置,包括:Docker启动时为Docker环境创建网桥。Docker容器在创建时会为其创建一个专用的虚拟NIC设备。Docker容器分配IP、端口并与宿主机进行端口映射,设置容器防火墙策略等。ExecdriverExecdriver架构图:1.Execdriver作为Docker容器的执行驱动,负责创建容器运行命名空间,容器资源使用情况的统计和限制,以及容器内部进程的实际运行情况。2.Execdriver现在默认使用Native驱动,不依赖LXC。七、Libcontainer《函数库》Libcontainer架构图:1.Libcontainer是Docker架构下用Go语言设计实现的库。设计的初衷是希望库可以直接访问内核中容器相关的API,而不需要依赖任何依赖。2、Docker可以直接调用Libcontainer来操作容器的Namespace、Cgroups、Apparmor、网络设备、防火墙规则。3、libcontainer提供了一套标准的接口来满足上层对容器管理的需求。也就是说,Libcontainer屏蔽了Docker上层直接管理容器的功能。八、DockerContainer《服务交付的终极形式》DockerContainer架构:1、DockerContainer(Docker容器)是Docker架构中服务交付的最终形式。2、Docker根据用户的需求和指令定制相应的Docker容器:用户指定容器镜像,这样Docker容器就可以定制rootfs等文件系统。用户通过指定计算资源的配额,使Docker容器使用指定的计算资源。用户通过配置网络及其安全策略,使Docker容器拥有独立、安全的网络环境。用户通过指定要运行的命令,使Docker容器执行指定的工作。