让我们稍微深入理解一下 docker 的技术概念(2)

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 让我们稍微深入理解一下 docker 的技术概念(2)

三、docker 架构 2 各个模块的功能

主要的模块有:Docker ClientDocker DaemonDocker RegistryGraphDriverlibcontainer 以及 Docker container

1、docker client

docker client 是 docker 架构中用户用来和 docker daemon 建立通信的客户端,用户使用的可执行文件为 docker,通过 docker 命令行工具可以发起众多管理 container 的请求。


docker client 可以通过一下三种方式和 docker daemon 建立通信:


tcp://host:port

unix:path_to_socket

fd://socketfd。

docker client 可以通过设置命令行 flag 参数的形式设置安全传输层协议(TLS)的有关参数,保证传输的安全性。


docker client 发送容器管理请求后,由 docker daemon 接受并处理请求,当 docker client 接收到返回的请求相应并简单处理后,docker client 一次完整的生命周期就结束了,当需要继续发送容器管理请求时,用户必须再次通过 docker 可以执行文件创建 docker client。

2、docker daemon

docker daemon 是 docker 架构中一个常驻在后台的系统进程,功能是:接收处理 docker client 发送的请求。该守护进程在后台启动一个 server,server 负载接受 docker client 发送的请求;接受请求后,server 通过路由与分发调度,找到相应的 handler 来执行请求。


docker daemon 启动所使用的可执行文件也为 docker,与 docker client 启动所使用的可执行文件 docker 相同,在 docker 命令执行时,通过传入的参数来判别 docker daemon 与 docker client。


docker daemon 的架构可以分为:docker server、engine、job。

3、docker server

docker server 在 docker 架构中时专门服务于 docker client 的 server,该 server 的功能时:接受并调度分发 docker client 发送的请求,架构图如下:

1035234-20181020215539574-213176954.png

在 Docker 的启动过程中,通过包 gorilla/mux(golang 的类库解析),创建了一个 mux.Router,提供请求的路由功能。在 Golang 中,gorilla/mux 是一个强大的 URL 路由器以及调度分发器。该 mux.Router 中添加了众多的路由项,每一个路由项由HTTP请求方法(PUT、POST、GET或DELETE)、URL、Handler 三部分组成。


若 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、engine

Engine 是 Docker 架构中的运行引擎,同时也 Docker 运行的核心模块。它扮演 Docker container 存储仓库的角色,并且通过执行 job 的方式来操纵管理这些容器。


在 Engine 数据结构的设计与实现过程中,有一个 handler 对象。该 handler 对象存储的都是关于众多特定 job 的 handler 处理访问。举例说明,Engine 的 handler 对象中有一项为:{“create”: daemon.ContainerCreate},则说明当名为 create 的 job 在运行时,执行的是 daemon.ContainerCreate 的 handler 。

5、job

一个 Job 可以认为是 Docker 架构中 Engine 内部最基本的工作执行单元。Docker 可以做的每一项工作,都可以抽象为一个 job。例如:在容器内部运行一个进程,这是一个 job;创建一个新的容器,这是一个 job,从 Internet 上下载一个文档,这是一个 job;包括之前在 Docker Server 部分说过的,创建 Server 服务于 HTTP 的 API,这也是一个 job,等等。


Job 的设计者,把 Job 设计得与 Unix 进程相仿。比如说:Job 有一个名称,有参数,有环境变量,有标准的输入输出,有错误处理,有返回状态等。

6、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,这样可以保证容器镜像的获取在内网完成。

7、Graph

**Graph 在 Docker 架构中扮演已下载容器镜像的保管者,以及已下载容器镜像之间关系的记录者。**一方面,Graph 存储着本地具有版本信息的文件系统镜像,另一方面也通过 GraphDB 记录着所有文件系统镜像彼此之间的关系。

Graph 的架构如下:

1035234-20181020215539574-213176954.png

其中,GraphDB 是一个构建在 SQLite 之上的小型图数据库,实现了节点的命名以及节点之间关联关系的记录。它仅仅实现了大多数图数据库所拥有的一个小的子集,但是提供了简单的接口表示节点之间的关系。


同时在 Graph 的本地目录中,关于每一个的容器镜像,具体存储的信息有:该容器镜像的元数据,容器镜像的大小信息,以及该容器镜像所代表的具体 rootfs。

8、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 的架构如下:

1035234-20181020215539574-213176954.png

networkdriver 的用途是完成 Docker 容器网络环境的配置,其中包括 Docker 启动时为 Docker 环境创建网桥;Docker 容器创建时为其创建专属虚拟网卡设备;以及为 Docker 容器分配 IP、端口并与宿主机做端口映射,设置容器防火墙策略等。networkdriver 的架构如下:

1035234-20181020215539574-213176954.png

execdriver 作为 Docker 容器的执行驱动,负责创建容器运行命名空间,负责容器资源使用的统计与限制,负责容器内部进程的真正运行等。在 execdriver 的实现过程中,原先可以使用 LXC 驱动调用 LXC 的接口,来操纵容器的配置以及生命周期,而现在 execdriver 默认使用 native 驱动,不依赖于 LXC。


具体体现在 Daemon 启动过程中加载的 ExecDriverflag 参数,该参数在配置文件已经被设为 native 。这可以认为是 Docker 在 1.2 版本上一个很大的改变,或者说 Docker 实现跨平台的一个先兆。execdriver 架构如下:

1035234-20181020215539574-213176954.png

9、libcontainer

libcontainer 是 Docker 架构中一个使用 Go 语言设计实现的库,设计初衷是希望该库可以不依靠任何依赖,直接访问内核中与容器相关的 API。


正是由于 libcontainer 的存在,Docker 可以直接调用 libcontainer,而最终操纵容器的 namespace、cgroups、apparmor、网络设备以及防火墙规则等。这一系列操作的完成都不需要依赖LXC或者其他包。libcontainer架构如下

1035234-20181020215539574-213176954.png

另外,libcontainer 提供了一整套标准的接口来满足上层对容器管理的需求。或者说,libcontainer 屏蔽了 Docker 上层对容器的直接管理。又由于 libcontainer 使用 Go 这种跨平台的语言开发实现,且本身又可以被上层多种不同的编程语言访问,因此很难说,未来的 Docker 就一定会紧紧地和 Linux 捆绑在一起。而于此同时,Microsoft 在其著名云计算平台 Azure 中,也添加了对 Docker 的支持,可见 Docker 的开放程度与业界的火热度。


暂不谈 Docker,由于 libcontainer 的功能以及其本身与系统的松耦合特性,很有可能会在其他以容器为原型的平台出现,同时也很有可能催生出云计算领域全新的项目。

10、docker container

Docker container(Docker容器)是 Docker 架构中服务交付的最终体现形式。


Docker 按照用户的需求与指令,订制相应的 Docker 容器:


用户通过指定容器镜像,使得Docker容器可以自定义 rootfs 等文件系统;

用户通过指定计算资源的配额,使得 Docker 容器使用指定的计算资源;

用户通过配置网络及其安全策略,使得 Docker 容器拥有独立且安全的网络环境;

用户通过指定运行的命令,使得 Docker 容器执行指定的工作。

1035234-20181020215539574-213176954.png

参考:

相关实践学习
通过容器镜像仓库与容器服务快速部署spring-hello应用
本教程主要讲述如何将本地Java代码程序上传并在云端以容器化的构建、传输和运行。
Kubernetes极速入门
Kubernetes(K8S)是Google在2014年发布的一个开源项目,用于自动化容器化应用程序的部署、扩展和管理。Kubernetes通常结合docker容器工作,并且整合多个运行着docker容器的主机集群。 本课程从Kubernetes的简介、功能、架构,集群的概念、工具及部署等各个方面进行了详细的讲解及展示,通过对本课程的学习,可以对Kubernetes有一个较为全面的认识,并初步掌握Kubernetes相关的安装部署及使用技巧。本课程由黑马程序员提供。   相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
1月前
|
运维 网络安全 持续交付
IDEA+Docker 远程一键部署项目:技术干货分享
【10月更文挑战第4天】在现代软件开发中,快速、可靠、自动化的部署流程是提升开发效率和运维质量的关键。IDEA(IntelliJ IDEA)作为Java开发者首选的IDE,结合Docker这一轻量级容器化技术,能够实现远程一键部署项目,极大地简化了开发到生产的流程。今天,我将和大家分享这一组合在工作学习中的实际应用和技术干货。
192 3
|
2月前
|
弹性计算 运维 持续交付
探索Docker容器化技术及其在生产环境中的应用
探索Docker容器化技术及其在生产环境中的应用
109 5
|
4天前
|
Java 应用服务中间件 Linux
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
本文主要讲解了Docker的安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库以及Docker容器虚拟化与传统虚拟机比较。
【Docker容器化技术】docker安装与部署、常用命令、容器数据卷、应用部署实战、Dockerfile、服务编排docker-compose、私有仓库
|
2月前
|
Linux iOS开发 Docker
Docker:容器化技术的领航者 —— 从基础到实践的全面解析
在云计算与微服务架构日益盛行的今天,Docker作为容器化技术的佼佼者,正引领着一场软件开发与部署的革命。它不仅极大地提升了应用部署的灵活性与效率,还为持续集成/持续部署(CI/CD)提供了强有力的支撑。
232 69
|
13天前
|
Kubernetes Cloud Native 开发者
云原生技术入门:Kubernetes和Docker的协作之旅
【10月更文挑战第22天】在数字化转型的浪潮中,云原生技术成为推动企业创新的重要力量。本文旨在通过浅显易懂的语言,引领读者步入云原生的世界,着重介绍Kubernetes和Docker如何携手打造弹性、可扩展的云环境。我们将从基础概念入手,逐步深入到它们在实际场景中的应用,以及如何简化部署和管理过程。文章不仅为初学者提供入门指南,还为有一定基础的开发者提供实践参考,共同探索云原生技术的无限可能。
22 3
|
21天前
|
存储 应用服务中间件 云计算
深入解析:云计算中的容器化技术——Docker实战指南
【10月更文挑战第14天】深入解析:云计算中的容器化技术——Docker实战指南
50 1
|
26天前
|
运维 JavaScript 虚拟化
探索容器化技术:Docker的实践与应用
【10月更文挑战第9天】探索容器化技术:Docker的实践与应用
47 3
|
2月前
|
运维 Cloud Native Docker
云原生技术入门:Docker容器化实战
【9月更文挑战第20天】本文将引导你走进云原生技术的世界,通过Docker容器化技术的实战演练,深入理解其背后的原理和应用。我们将一起探索如何在云平台上利用Docker简化部署、扩展和管理应用程序的过程,并揭示这一技术如何改变现代软件的开发和运维模式。
|
20天前
|
存储 Kubernetes 监控
深入探索Docker容器化技术的奥秘
【10月更文挑战第15天】深入探索Docker容器化技术的奥秘
17 0
|
21天前
|
运维 Kubernetes 监控
掌握Docker容器化技术:构建、部署与管理的高效实践
【10月更文挑战第14天】掌握Docker容器化技术:构建、部署与管理的高效实践
36 0