Docker底层原理及源码分析 Docker 架构
若 Docker Client 通过 HTTP 的形式访问 Docker Daemon,创建完 mux.Router 之后,Docker 将 Server 的监听地址以及 mux.Router 作为参数,创建一个 httpSrv=http.Server{},最终执行 httpSrv.Serve() 为请求服务。 在 Server 的服务过程中,Server 在 listener 上接受 Docker Client 的访问请求,并创建一个全新的 goroutine 来服务该请求。在 goroutine 中,首先读取请求内容,然后做解析工作,接着找到相应的路由项,随后调用相应的 Handler 来处理该请求,最后 Handler 处理完请求之后回复该请求。 需要注意的是:Docker Server 的运行在 Docker 的启动过程中,是靠一个名为"serveapi"的 job 的运行来完成的。原则上,Docker Server 的运行是众多 job 中的一个,但是为了强调 Docker Server 的重要性以及为后续 job 服务的重要特性,将该"serveapi"的 job 单独抽离出来分析,理解为 Docker Server。 4.2.2 Engine Engine 是 Docker 架构中的运行引擎,同时也 Docker 运行的核心模块。它扮演 Docker container 存储仓库的角色,并且通过执行 job 的方式来操纵管理这些容器。 在 Engine 数据结构的设计与实现过程中,有一个 handler 对象。该 handler 对象存储的都是关于众多特定 job 的 handler 处理访问。举例说明,Engine 的 handler 对象中有一项为:{"create": daemon.ContainerCreate,},则说明当名为"create"的 job 在运行时,执行的是 daemon.ContainerCreate 的 handler。 4.2.3 Job 一个 Job 可以认为是 Docker 架构中 Engine 内部最基本的工作执行单元。Docker 可以做的每一项工作,都可以抽象为一个 job。例如:在容器内部运行一个进程,这是一个 job;创建一个新的容器,这是一个 job,从 Internet 上下载一个文档,这是一个 job;包括之前在 Docker Server 部分说过的,创建 Server 服务于 HTTP 的 API,这也是一个 job,等等。 Job 的设计者,把 Job 设计得与 Unix 进程相仿。比如说:Job 有一个名称,有参数,有环境变量,有标准的输入输出,有错误处理,有返回状态等。 4.3 Docker Registry Docker Registry 是一个存储容器镜像的仓库。而容器镜像是在容器被创建时,被加载用来初始化容器的文件架构与目录。 在 Docker 的运行过程中,Docker Daemon 会与 Docker Registry 通信,并实现搜索镜像、下载镜像、上传镜像三个功能,这三个功能对应的 job 名称分别为"search","pull" 与 "push"。 其中,在 Docker 架构中,Docker 可以使用公有的 Docker Registry,即大家熟知的 Docker Hub ,如此一来,Docker 获取容器镜像文件时,必须通过互联网访问 Docker Hub;同时 Docker 也允许用户构建本地私有的 Docker Registry,这样可以保证容器镜像的获取在内网完成。 4.4 Graph Graph 在 Docker 架构中扮演已下载容器镜像的保管者,以及已下载容器镜像之间关系的记录者。一方面,Graph 存储着本地具有版本信息的文件系统镜像,另一方面也通过 GraphDB 记录着所有文件系统镜像彼此之间的关系。Graph 的架构如图 4.3。 图 4.3 Graph 架构示意图 其中,GraphDB 是一个构建在 SQLite 之上的小型图数据库,实现了节点的命名以及节点之间关联关系的记录。它仅仅实现了大多数图数据库所拥有的一个小的子集,但是提供了简单的接口表示节点之间的关系。 同时在 Graph 的本地目录中,关于每一个的容器镜像,具体存储的信息有:该容器镜像的元数据,容器镜像的大小信息,以及该容器镜像所代表的具体 rootfs。 4.5 Driver Driver 是 Docker 架构中的驱动模块。通过 Driver 驱动,Docker 可以实现对 Docker 容器执行环境的定制。由于 Docker 运行的生命周期中,并非用户所有的操作都是针对 Docker 容器的管理,另外还有关于 Docker 运行信息的获取,Graph 的存储与记录等。因此,为了将 Docker 容器的管理从 Docker Daemon 内部业务逻辑中区分开来,设计了 Driver 层驱动来接管所有这部分请求。 在 Docker Driver 的实现中,可以分为以下三类驱动:graphdriver、networkdriver 和 execdriver。 graphdriver 主要用于完成容器镜像的管理,包括存储与获取。即当用户需要下载指定的容器镜像时,graphdriver 将容器镜像存储在本地的指定目录;同时当用户需要使用指定的容器镜像来创建容器的 rootfs 时,graphdriver 从本地镜像存储目录中获取指定的容器镜像。 在 graphdriver 的初始化过程之前,有 4 种文件系统或类文件系统在其内部注册,它们分别是 aufs、btrfs、vfs 和 devmapper。而 Docker 在初始化之时,通过获取系统环境变量”DOCKER_DRIVER”来提取所使用 driver 的指定类型。而之后所有的 graph 操作,都使用该 driver 来执行。 graphdriver 的架构如图 4.4: 图 4.4 graphdriver 架构示意图 networkdriver 的用途是完成 Docker 容器网络环境的配置,其中包括 Docker 启动时为 Docker 环境创建网桥;Docker 容器创建时为其创建专属虚拟网卡设备;以及为 Docker 容器分配 IP、端口并与宿主机做端口映射,设置容器防火墙策略等。networkdriver 的架构如图 4.5: 图 4. 5 networkdriver 架构示意图 (编辑:温州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |