Docker架构

news2024/11/26 2:55:48

目录

  • Docker总架构图
    • Docker Client
    • Docker Daemon
      • Docker Server
      • Docker Engine
      • Job
    • Docker Registry
    • Graph
    • Driver
      • GraphDriver
      • NetworkDriver
      • ExecDriver
    • Libcontainer
    • Docker Container

Docker可以帮助用户在容器内部快速自动化部署应用,并利用Linux内核特性命名空间(namespaces)及控制组(cgroups)等为容器提供隔离的运行环境。Docker借助操作系统层的虚拟化实现资源的隔离,因此Docker容器在运行时与虚拟机(VM)的运行有很大的区别,Docker容器与宿主机共享同一个操作系统,不会有额外的操作系统开销。这样的优势很明显,因而大大提高了资源利用率,并且提升了I/O等方面的性能。

Docker总架构图

Docker的总架构如图1-1所示。架构中主要的模块有:DockerClient、DockerDaemon、Docker Registry、Graph、Driver、libcontainer以及Docker Container。

对用户而言,Docker Client是与Docker Daemon建立通信的最佳途径。用户通过Docker Client发起容器的管理请求,请求最终发往Docker Daemon。

Docker Daemon作为Docker架构中的主体部分,首先具备服务端的功能,有能力接收Docker Client发起的请求;其次具备Docker Client请求的处理能力。Docker Daemon内部所有的任务均由Engine来完成,且每一项工作都以一个Job的形式存在。

Docker Daemon需要完成的任务很多,因此Job的种类也很多。若用户需要下载容器镜像,Docker Daemon则会创建一个名为“pull”的Job,运行时从Docker Registry中下载镜像,并通过镜像管理驱动graphdriver将下载的镜像存储在graph中;若用户需要为Docker容器创建网络环境,Docker Daemon则会创建一个名“allocate_interface”的Job,通过网络驱动networkdriver分配网络接口的资源……

libcontainer是一套独立的容器管理解决方案,这套解决方案涉及了大量Linux内核方面的特性,如:namespaces、cgroups以及capabilities等。libcontainer很好地抽象了Linux的内核特性,并提供完整、明确的接口给Docker Daemon。
当用户执行运行容器这个命令之后,一个Docker容器就处于运行状态,该容器拥有隔离的运行环境、独立的网络栈资源以及受限的资源等。

image-20230714105724589

Docker Client

Docker Client是Docker架构中用户与Docker Daemon建立通信的客户端。在一台安装有Docker的机器上,用户可以使用可执行文件docker作为Docker Client,发起众多Docker容器的管理请求。

Docker Client可以通过以下三种方式和Docker Daemon建立通信,分别为:

  • tcp://host:port、
  • unix://path_to_socket
  • fd://socketfd。

为简单起见,本书主要使用第一种方式作为讲述两者通信的原型。通信方式确定后,DockerClient与Docker Daemon建立连接并传输请求时,可以通过命令行flag参数的形式,设置安全传输层协议(TLS)的有关参数,保证传输的安全性。

Docker Client发送容器管理请求后,请求由Docker Daemon接收并处理,当Docker Client接收到返回的请求响应并做简单处理后,Docker Client一次完整的生命周期就此结束。若需要继续发送容器管理请求,用户必须再次通过可执行文件docker创建Docker Client,并走完以上相同的流程。

Docker Daemon

Docker Daemon是Docker架构中一个常驻在后台的系统进程。所谓的“运行Docker”,即代表运行Docker Daemon。总之,DockerDaemon的作用主要有以下两方面:

·接收并处理Docker Client发送的请求。

·管理所有的Docker容器。

Docker Daemon运行时,会在后台启动一个Server,Server负责接收Docker Client发送的请求;接收请求后,Server通过路由与分发调度,找到相应的Handler来处理请求。

启动Docker Daemon所使用的可执行文件同样是docker,与Docker Client启动所使用的可执行文件docker相同。既然Docker Client与Docker Daemon都可以通过docker二进制文件创建,那么如何辨别两者就变得非常重要。实际上,执行docker命令时,通过传入的参数可以辨别Docker Daemon与Docker Client,如docker–d代表Docker Daemon的启动,dockerps则代表创建Docker Client,并发送ps请求。

Docker Daemon的架构大致可以分为三部分:Docker Server、Engine和Job。Daemon的架构如图1-2所示。

Docker Server

image-20230714150755893

Docker Engine

image-20230714150835152

Engine是Docker架构中的运行引擎,同时也是Docker运行的核心模块。Engine存储着大量的容器信息,同时管理着Docker大部分Job的执行。换言之,Docker中大部分任务的执行都需要Engine协助,并通过Engine匹配相应的Job完成Job的执行。

在Docker源码中,有关Engine的数据结构定义中含有一个名为handlers的对象。该handlers对象存储的是关于众多特定Job各自的处理方式handler。举例说明,Engine的handlers对象中有一项为:{“create”:daemon.ContainerCreate,},则说明当执行名为“create”的Job时,执行的是daemon.ContainerCreate这个handler。

除了容器管理之外,Engine还接管Docker Daemon的某些特定任务。当Docker Daemon遭遇到自身进程需要退出的情况时,Engine还负责完成DockerDaemon退出前的所有善后工作。

Job

Job可以认为是Docker架构中Engine内部最基本的工作执行单元。DockerDaemon可以完成的每一项工作都会呈现为一个Job。例如,在Docker容器内部运行一个进程,这是一个Job;创建一个新的容器,这是一个Job;在网络上下载一个文档,这是一个Job;包括之前在Docker Server部分谈及的,创建Server服务于HTTP协议的API,这也是一个Job,等等。

有关Job接口的设计,与UNIX进程非常相仿。比如说,Job有一个名称,有运行时参数,有环境变量,有标准输入与标准输出,有标准错误,还有返回状态等。

对于Job而言,定义完毕之后,运行才能完成Job自身真正的使命。Job的运行函数Run()则用以执行Job本身。

Docker Registry

Docker Registry是一个存储容器镜像(Docker Image)的仓库。容器镜像(Docker Image)是容器创建时用来初始化容器rootfs的文件系统内容。Docker Registry将大量的容器镜像汇集在一起,并为分散的Docker Daemon提供镜像服务。

Docker的运行过程中,有三种情况可能与Docker Registry通信,分别为搜索镜像、下载镜像、上传镜像。这三种情况所对应的Job名称分别为search、pull和push。

不同场景下,Docker Daemon可以使用不同的Docker Registry。公有Registry与私有Regsitry就是两种场景模式不同的Docker Registry。其中,大家熟知的Docker Hub,就是全球范围内最大的公有Registry。Docker可以通过互联网访问Docker Hub,并下载容器镜像;同时Docker也允许用户构建本地私有Registry,使容器镜像的获取在内网完成。

Graph

Graph在Docker架构中扮演的角色是容器镜像的保管者。不论是Docker下载的镜像,还是Docker构建的镜像,均由Graph统一化管理。由于Docker支持多种不同的镜像存储方式,如aufs、devicemapper、Btrfs等,故Graph对镜像的存储也会因以上种类而存在一些差异。对Docker而言,同一种类型的镜像被称为一个repository,如名称为ubuntu的镜像都同属一个repository;而同一个repository下的镜像则会因tag存在差异而不同,如ubuntu这个repository下有tag为12.04的镜像,也有tag为14.04的镜像。

Docker的graphdriver负责镜像本地的管理和存储以及对运行中的容器生成镜像等工作。(与registry不同)

Driver

Driver是Docker架构中的驱动模块。通过Driver驱动,Docker可以实现对Docker容器运行环境的定制,定制的维度主要有网络环境、存储方式以及容器执行方式。需要注意的是,Docker运行的生命周期中,并非用户所有的操作都是针对Docker容器的管理,同时包括用户对Docker运行信息的获取,还包括Docker对Graph的存储与记录等。因此,为了将仅与Docker容器有关的管理从Docker Daemon的所有逻辑中区分开来,Docker的创造者设计了Driver层来抽象不同类别各自的功能范畴。

Docker Driver的实现可以分为以下三类驱动:graphdriver、networkdriver和execdriver。

GraphDriver

graphdriver主要用于完成容器镜像的管理,包括从远程Docker Registry上下载镜像并进行存储,也包括本地构建完镜像后的存储。当用户下载指定的容器镜像时,graphdriver将容器镜像分层存储在本地的指定目录下;同时当用户需要使用指定的容器镜像来创建容器时,graphdriver从本地镜像存储目录中获取指定的容器镜像,并按特定规则为容器准备rootfs;另外,当用户需要通过指定Dockerfile构建全新镜像时,graphdriver会负责新镜像的存储管理。

在graphdriver的初始化过程之前,有4种文件系统或类文件系统的驱动Driver在DockerDaemon内部注册,它们分别是aufs、btrfs、vfs和devmapper。其中,aufs、btrfs以及devmapper用于容器镜像的管理,vfs用于容器volume的管理。Docker在初始化之时,优先通过获取系统环境变量“DOCKER_DRIVER”来提取所使用driver的指定类型。因此,之后所有的Graph操作,都使用该driver来执行。Docker镜像是Docker技术中非常关键的。2014年12月,在Linux 3.18-rc2版本中OverlayFS被合并至Linux内核主线,在Docker 1.4.0版本发布时,Docker官方宣布支持overlay这一类graphdriver,即用户在启动Docker Daemon时可以选择制定graphdriver的类型为overlay。graphdriver的架构如图1-5所示。

image-20230714153438913

NetworkDriver

networkdriver的作用是完成Docker容器网络环境的配置,其中包括Docker Daemon启动时为Docker环境创建网桥;Docker容器创建前为其分配相应的网络接口资源;以及为Docker容器分配IP、端口并与宿主机做NAT端口映射,设置容器防火墙策略等。networkdriver的架构如图1-6所示。

image-20230714153538483

ExecDriver

execdriver作为Docker容器的执行驱动,负责创建容器运行时的命名空间,负责容器资源使用的统计与限制,负责容器内部进程的真正运行等。在Docker 0.9.0版本之前,execdriver只能通过LXC驱动来实现容器的启动管理。实际上,当时Docker通过LXC驱动调用Linux下的LXC工具管理容器的创建,并控制管理容器的生命周期。从Docker 0.9.0开始,在继续支持LXC的情况下,Docker的execdriver默认使用native驱动,native驱动完全独立于LXC,属于Docker项目下第一个全新的子项目,用于容器的创建与管理。Docker默认使用native驱动的具体体现为:Docker Daemon启动过程中加载的ExecDriverflag参数在配置文件中已经被设为native。native这个execdriver的存在,使得Docker对Linux容器的创建与管理有了自己的解决方案。execdriver架构如图1-7所示。

image-20230714153715700

Libcontainer

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

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

image-20230714153929554

另外,libcontainer提供了一整套标准的接口来满足上层对容器管理的需求。或者说,libcontainer屏蔽了Docker上层对容器的直接管理。又由于libcontainer使用Go这种跨平台的语言开发实现,且本身又可以被上层多种不同的编程语言访问,因此,很难说未来的Docker一定会与Linux平台紧紧捆绑在一起。Docker Daemon的逻辑完全有可能位于其他非Linux操作系统的平台上,仅仅通过libcontainer的远程调用来实现对Docker容器的管理。另一方面,libcontainer与Docker Daemon的松耦合设计,似乎让用户感受到了除Linux Container之外其他的容器技术接入Docker Daemon的可能性。libcontainer承接Linux内核与Docker Daemon的同时,也让Docker的生态在跨平台方面充满生机。与此同时,Microsoft在其著名云计算平台Azure中,也添加了对Docker的支持,可见Docker的开放程度与业界的火热度。

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

Docker Container

Docker Container(Docker容器)是Docker架构中服务交付的最终体现形式。Docker通过DockerDaemon的管理,libcontainer的执行,最终创建Docker容器。Docker容器作为一个交付单位,功能类似于传统意义上的虚拟机(Virtual Machine),具备资源受限、环境与外界隔离的特点。然而,实现手段却与KVM、Xen等传统虚拟化技术大相径庭。

Docker容器的从无到有,涉及Docker利用到的很多技术。总而言之,用户可以根据自己的需求,通过Docker Client向Docker Daemon发送容器的创建与启动请求,请求中将携带容器的配置信息,从而达到定制相应Docker容器的目的。用户对Docker容器的配置有以下4个基本方面:

  • ·通过指定容器镜像,使得Docker容器可以自定义rootfs等文件系统。
  • ·通过指定物理资源的配额,如CPU、内存等,使得Docker容器使用受限的物理资源。
  • ·通过配置容器网络及其安全策略,使得Docker容器拥有独立且安全的网络环境。
  • ·通过指定容器的运行命令,使得Docker容器执行指定的任务。

Docker容器示意图如图1-9所示。

image-20230714154734306

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/753772.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微软将推出更多Edge特有功能,与Chrome展开竞争

微软在 2018 年宣布将推出基于 Chromium 构建的 Edge 浏览器,并于 2020 年 1 月推出了新版 Edge。如今时隔三年,根据统计 Edge 全平台的市场占有率仅为 4.23%,如果只考虑桌面端的话,Edge 的市场占有率则是 10.98%,这两…

系统设计蓝图 / 备忘单

开发一个强大、可扩展和高效的系统可能会令人望而却步。然而,了解关键概念和组件可以使这个过程更可管理。在本博客文章中,我们将探讨系统设计的关键概念和组件,如DNS、负载均衡、API网关等,以及一个简明的备忘单,可以…

inux运维面试题(二)之系统管理类面试题

Linux运维面试题(二)之系统管理类面试题 1.权限优化1.1 简述Linux权限划分原则文件基本权限默认权限特殊权限sudo授权文件系统属性权限 解答 2.备份策略2.1需要备份的内容备份策略备份频率备份存储位置 2.2网站服务器每天产生的日志数量较大,…

LLM - 读取 Lora 模型进行文本生成

目录 一.引言 二.Lora 模型文本生成 1.模型读取 1.1 AutoModelForCausalLM.from_pretrained 1.2 PeftModel.from_pretrained 2.文本生成 2.1 Tokenizer 2.2 model.generate 3.输出实践 三.总结 一.引言 前面介绍了使用 Baichuan7B 从样本生成到 Lora 模型微调和存储…

磁盘擦写次数计算

1.让机器能有外网 2,安装工具 sudo apt-get install smartmontools 3,输入查询命令 sudo smartctl -x /dev/sda |egrep Device Model|User Capacity|Sector Size|173|Logical Sectors Written|Percentage Used Endurance Indicator 4,计算擦写次数 计算方法:25…

hadoop启动无法启动datanode或者namenode

首先进入hadoop安装目录下例如: 再进入dfs目录下,没有出现在hdfs-site.xml配置的data或者name cd data/current vim VERSION 打开VERSION文件复制:clusterID下的内容 将内容复制到name中的VERSION。再进行重启Hadoop

常见的前端安全以及常规安全策略

1、CSRF:跨站请求伪造(Cross-site request forgery); 原理: (1) 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A; (2&#xff…

mapping文件目录生成修改

参考文章: gradle编译完成Copy mapping文件 - 简书 (jianshu.com) 第一步:在app的build.gradle中做如下配置: android {android.applicationVariants.all {variant ->def buildType variant.buildType.nametasks.all {def mappingDir …

米尔基于STM32MP135核心板,助力充电桩发展

随着电动车的普及和人们环保意识的增强,充电桩作为电动车充电设备的重要一环,充电桩行业正迅速发展,消费市场的大量应用也造就市场的需求量不断增长。因此,产品的功能、可靠性、安全性等要求也变得尤为重要,而采用传统…

Leetcode---353周赛

周赛题目 2769. 找出最大的可达成数字 2770. 达到末尾下标所需的最大跳跃次数 2771. 构造最长非递减子数组 2772. 使数组中的所有元素都等于零 一、找出最大的可达成数字 这题就是简单的不能在简单的简单题, 题目意思是:给你一个数num和操作数t&…

智能分析网关V2有抓拍告警但无法推送到EasyCVR,是什么原因?

我们在此前的文章中也介绍了关于智能分析网关V2接入EasyCVR平台的操作步骤,感兴趣的用户可以查看这篇文章:在EasyCVR新版本v3.3中,如何正确接入智能分析网关V2? 智能分析网关V2是基于边缘AI计算技术,可对前端摄像头采…

机器学习 day27(反向传播)

导数 函数在某点的导数为该点处的斜率,用height / width表示,可以看作当w增加ε,J(w,b)增加k倍的ε,则k为该点的导数 反向传播 tensorflow使用反向传播来自动计算神经网络模型中的导数

中国区域地面气象要素驱动数据集(1979-2018)

中国区域地面气象要素驱动数据集(1979-2018) 摘要 中国区域地面气象要素驱动数据集,包括近地面气温、近地面气压、近地面空气比湿、近地面全风速、地面向下短波辐射、地面向下长波辐射、地面降水率共7个要素。数据为NETCDF格式,时…

Redis_非关系型数据库

一、 Redis介绍 1.NoSQL 也叫Not Only SQL(不仅仅是SQL, 不用 sql语言操作的数据库), 一般指非关系型数据库 关系型数据库: 以数据库表为单位存储,表与表之间存在某种关系 非关系型数据库: 数据与数据之间没有关系, 数据就是以键值对的形式存储, 通过键获取到值 在互联网发展中…

cjson的内存泄漏案例

1、当我们使用下面这些创建json对象时,需要用cJSON_Delete();释放,(当然,释放父JSON对象后,子JSON对象也会被释放) 2、多次释放同一内存空间 在recv_write_property函数中的data,在Equipment_re…

Unity游戏源码分享-Unity5.4.1打砖块游戏Breakout_Game_Starter_Kit

Unity5.4.1打砖块游戏Breakout_Game_Starter_Kit 童年的回忆 项目地址:https://download.csdn.net/download/Highning0007/88042779Unity游戏源码分享-

ViDeNN: Deep Blind Video Denoising

ViDeNN: Deep Blind Video Denoising 摘要 We propose ViDeNN: a CNN for Video Denoising without prior knowledge on the noise distribution (blind denoising). The CNN architecture uses a combination of spatial and temporal filtering, learning to spatially deno…

【Java 泛型方法】泛型方法的定义和使用,泛型的通配符和泛型的上下限,泛型的注意事项

博主&#xff1a;_LJaXi Or 東方幻想郷 专栏&#xff1a; Java | 从跨平台到跨行业 开发工具&#xff1a;IntelliJ IDEA Java 泛型方法 泛型方法 ❓需求| 泛型的通配符 | 上限 | 下限 |泛型擦除 ⛔基本数据类型问题 泛型方法 ❓ [修饰符] <类型变量, 类型变量...> [返回…

内容过多,超出部分以省略号“...”显示

效果图如图所示&#xff1a; 1.第一种实现方法&#xff0c;使用纯css实现&#xff08;ps&#xff1a;此方式必须给元素设置宽度&#xff0c;否则可能无效果&#xff09;&#xff0c;代码如下&#xff1a; html代码 <!-- 超过长度&#xff0c;用省略号实现&#xff0c;css的…

相交链表——力扣160

题目描述 法一&#xff09;哈希表 class Solution{ public:ListNode* getIntersectionNode (ListNode* headA, ListNode* headB){unordered_set<ListNode*> st;ListNode* temp headA;while(temp){st.insert(temp);temp temp->next;}temp headB;while(temp){if(st.c…