深入浅出Docker

news2024/9/20 16:17:04

1. Docker引擎

Docker引擎是用来运行和管理容器的核心软件。通常人们会简单的将其指代为Docker或Docker平台。

基于开放容器计划(OCI)相关的标准要求,Docker引擎采用了模块化的设计原则,其组件是可替换的。

Docker引擎由如下主要的组件构成:Docker客户端(Docker Client)、Docker守护进程(Docker daemon)、containerd以及runc。

Docker引擎的架构示意图,如下

在这里插入图片描述

1.1 runc

runc是OCI容器运行时规范的参考实现。去粗取精,会发现runc实质上是一个轻量级的、针对Libcontainer进行了包装的命令行交互工具(Libcontainer取代了早期Docker架构中的LXC,LXC提供了对诸如命令空间namespace和控制组CGroup等基础工具的操作能力)

runc生来只有一个作用 — 创建容器,它是一个CLI包装器,实质上就是一个独立的容器运行时工具。因此直接下载它或者基于源码编译二进制文件,即可拥有一个全功能的runc。但它只是一个基础工具,并不提供类似Docker引擎所拥有的丰富功能。

1.2 containerd

在对Docker daemon的功能拆解后,所有的容器执行逻辑被重构到一个新的名为containerd的工具中。它的主要任务是容器的生命周期管理 — start|stop|pause|rm...

在Docker引擎技术栈中,containerd位于daemon和runc所在的OCI层之间。Kubernetes也可以通过cri-containerd使用containerd。

1.3 启动一个新的容器(流程)

现在我们对Docker引擎已经有了一个总体认识,也了解了一些历史,下面介绍一下创建新容器的过程。

常用的启动容器的方法就是使用Docker命令行工具。下面的docker container run命令会基于alpine:latest镜像启动一个新容器。

docker container run --name ctr1 -it alpine:latest sh

当使用Docker命令行工具执行如上命令时,Docker客户端会将其转换为合适的API格式,并发送到正确的API端点。

API是在daemon中实现的。这套功能丰富、基于版本的REST API已经成为Docker的标志,并且被行业接受成为事实上的容器API。

一旦daemon接收到创建新容器的命令,它就会向containerd发出调用。daemon已经不再包含任何创建容器的代码了!

daemon使用一种CRUD风格的API,通过gRPC与containerd进行通信。

虽然名叫containerd,但是它并不负责创建容器,而是指挥runc去做。containerd将Docker镜像转换为OCI bundle,并让runc基于此创建一个新的容器。

然后,runc与操作系统内核接口进行通信,基于所有必要的工具(NamespaceCGroup等)来创建容器。容器进程作为runc的子进程启动,启动完毕后,runc将会退出。

现在,容器启动完毕了。整个过程如下图。

在这里插入图片描述

1.4 shim

shim是实现无daemon的容器不可或缺的工具。

前面提到,containerd指挥runc来创建新容器。事实上,每次创建容器时它都会fork一个新的runc实例。不过,一旦容器创建完毕,对应的runc进程就会退出。

一旦容器进程的父进程runc退出,相关联的containerd-shim进程就会成为容器的父进程

作为容器的父进程,shim的部分职责如下。

  • 保持所有STDIN和STDOUT流是开启窗台,从而当daemon重启的时候,容器不回因为管道(pipe)的关闭而终止。
  • 将容器的退出状态反馈给daemon。

1.5 daemon的作用

当所有的执行逻辑和运行时代码都从daemon中剥离出来之后,daemon的主要功能包括镜像管理、镜像构建、REST API、身份验证、安全、核心网络以及编排


2. Docker镜像

Docker镜像就是停止运行的容器。如果读者是一名研发人员,可以将镜像理解为类Class。

读者需要先从镜像仓库服务中拉取镜像。常见的镜像仓库服务是Docker Hub,但是也存在其他镜像仓库服务。

镜像由多个层租场,每层叠加之后,从外部看起来就如一个独立的对象。镜像内部是一个精简的操作系统(OS),同时还包含应用运行所必须的文件和依赖包。

镜像中不包含内核,容器都是共享所在Docker主机的内核。


3. Docker容器

容器是镜像的运行时实例。虚拟机和容器最大的区别是容器更快并且更轻量级,与虚拟机运行在完整的操作系统之上相比,容器会共享其所在主机的操作系统/内核

3.1 容器 vs 虚拟机

从更高层面上讲,Hypervisor是硬件虚拟化,Hypervisor将硬件物理资源划分为虚拟资源;容器是操作系统虚拟化,容器将系统资源划分为虚拟资源。

虚拟机模型

在虚拟机模型中,首先要开启物理机并启动Hypervisor引导程序,一旦Hypervisor启动,就会占有机器上的全部物理资源,如CPU、RAM、存储以及NIC。Hypervisor接下来就会将这些物理资源划分为虚拟资源,并且看起来与真实物理资源完全一致。

然后Hypervisor会将这些资源打包进一个叫做虚拟机(VM)的软件结构当中。这样用户就可以使用这些虚拟机,并在其中安装操作系统和应用。

容器模型

与操作系统模型相同的是,OS也占用了全部硬件资源。

在OS层之上,需要安装容器引擎(如Docker)。容器引擎可以获取系统资源,如进程树、文件系统以及网络栈,接着将资源分割为安全的相互隔离的资源结构,称之为容器。每个容器看起来就像一个真实的操作系统,在其内部可以运行应用。

虚拟机的额外开销

虚拟机模型通过Hypervisor将底层硬件资源划分为虚拟机当中。每个虚拟机都是包含了虚拟CPU、虚拟RAM、虚拟磁盘等资源的一种软件结构。因此,每个虚拟机都需要有自己的操作系统来声明、初始化并管理这些虚拟资源。但不幸的是,操作系统本身是有额外开销的。

容器模型具有宿主机操作系统中运行的单个内核。这意味着只有一个操作系统消耗CPU、RAM和存储资源。简而言之,就是只有一份OS损耗!


4. 应用容器化

容器是为应用而生!具体来说,容器能够简化应用的构建、部署和运行过程。

完整的应用容器化过程主要分为以下几个步骤。

(1)编写应用代码。
(2)创建一个Dockerfile,其中包括当前应用的描述、依赖以及该如何运行这个应用。
(3)对该Dockerfile执行docker image build命令。
(4)等待Docker将应用程序构建到Docker镜像中。

在这里插入图片描述


5. 容器网络

Docker对于容器之间、容器与外部网络和VLAN之间的连接均有相应的解决方案。

Docker网络架构源自一种叫做容器网络模型(CNM)的方案,该方案是开源的并且支持插接式连接。Libnetwork是Docker对CNM的一种实现,提供了Docker核心网络架构的全部功能。不同的驱动可以通过插拔的方式接入Libnetwork来提供定制化的网络拓扑。

为了实现开箱即用的效果,Docker封装了一系列本地驱动,覆盖了大部分常见的网络需求。其中包括单机桥接网络(Single-Host Bridge Network)、多机覆盖网络(Multi-Host Overlay),并且支持接入现有VLAN。

最后要说的是,Libnetwork提供了本地服务发现和基础的容器负载均衡解决方案。

基础理论

在顶层设计中,Docker网络架构由3个主要部分构成:CNM、Libnetwork、驱动。

CNM是设计标准。Libnetwork是CNM的具体实现。驱动通过实现特定网络拓扑的方式来扩展该模型的能力。

5.1 CNM

Docker网络架构的设计规范是CNM。CNM中规定了Docker网络的基础组成要素。

CNM定义了3个基本要素:沙盒(Sandbox)、终端(Endpoint)和网络(Network)。

  • 沙盒是一个独立的网络栈。其中包括以太网接口、端口、路由表以及DNS配置。

  • 终端就是虚拟网络接口。在CNM中,终端负责将沙盒连接到网络。

  • 网络802.1d网桥(类似于大家熟知的交换机)的软件实现。因此,网络就是需要交换的终端的集合,并且终端之间相互独立。

在这里插入图片描述

Docker环境中最小的调度单位就是容器,图11.3展示了CNM组件是如何与容器进行关联的 — 沙盒被放置在容器内部,为容器提供网络连接。

在这里插入图片描述
容器A只有一个网络接口(终端)并连接到了网络A。容器B有两个接口(终端)并且分别接入了网络A和网络B。容器A和容器B之间是可以相互通信的,因为都接入了网络A。但是,如果没有三层路由器的支持,容器B的两个终端之间是不能通信的。

5.2 Libnetwork

CNM是设计规范文档,Libnetwork是标准的实现。

Docker将网络部分从daemon中拆分,并重构为一个叫作Libnetwork的外部类库。Libnetwork实现了CNM中定义的全部3个组件。此外它还实现了本地服务发现(Service Discovery)、基于ingress的容器负载均衡,以及网络控制层和管理层功能。

5.3 驱动

如果说Libnetwork实现了控制层和管理层功能,那么驱动就负责实现数据层

Docker封装了若干内置驱动,通常被称为原生驱动或者本地驱动。在Linux上包括Bridge、Overlay以及Macvlan。第三方也可以编写Docker网络驱动,这些驱动叫作远程驱动,例如Calico、Contiv、Kuryr以及Weave。

在这里插入图片描述
每个驱动都负责其上所有网络资源的创建和管理。


6. Docker覆盖网络Overlay

容器间通信的可靠性和安全性相当重要,即使容器分属于不同网络中的不同主机。这也是覆盖网络大展拳脚的地方,它允许读者创建扁平、安全的二层网络来连接多个主机,容器可以连接到覆盖网络并直接通信。

创建overlay网络命令

docker network create -d overlay uber-net

6.1 工作原理VXLAN

首先必须知道,Docker使用VXLAN隧道技术创建了虚拟二层覆盖网络

在VXLAN的设计中,允许用户基于已经存在的三层网络结构创建虚拟二层网络。VXLAN的美妙之处在于它是一种封装技术,能使现存的路由器和网络架构看起来就像普通的IP/UDP包一样,并且处理起来毫无问题。

为了创建二层覆盖网络,VXLAN基于现有的三层IP网络创建了隧道,VXLAN隧道终端(VXLAN Tunnel Endpoint, VTEP)。VTEP完成了封装和解压的步骤,以及一些功能实现所必须的操作。

6.2 网络联通举例

假设当前有2个网络(172.31.1.0/24,192.168.1.0/24),每个网络下有一台主机。通过IP网络将两台主机连接起来。每个主机运行了一个容器,之后又为容器连接创建一个VXLAN覆盖网络

为了实现上述场景,在每台主机上都新建了一个Sandbox(网络命名空间)。Sandbox就像一个容器,但其中运行的不是应用,而是当前主机上独立的网络栈

在Sandbox内部创建了一个名为Br0虚拟交换机(又称虚拟网桥)。同时Sandbox内部还创建了一个VTEP,其中一端接入到名为Br0的虚拟交换机当中,另一端接入主机网络栈(VTEP)。在主机网络栈中的终端从主机所连接的基础网络中获取到IP地址,并以UDP Socket的方式绑定到4789端口。不同主机上的两个VTEP通过VXLAN隧道创建了一个覆盖网络,如下图所示。

在这里插入图片描述

这是VXLAN上层网络创建和使用所必需的。

接下来每个容器都会有自己的虚拟以太网(veth)适配器,并接入本地Br0虚拟交换机。目前拓扑结果如图12.7所示,虽然是在主机所属网络互相独立的情况下,但这样能更容器看出两个分别位于不同主机上的容器之间是如何通过VXLAN上层网络进行通信的。

在这里插入图片描述

6.3 通信示例

在本例中,将node1上的容器称为C1node2上的容器称为C2,如图12.8所示。假设C1希望pingC2

在这里插入图片描述

C1发送ping请求,目标IP为C2的地址10.0.0.4。该请求的流量通过连接到Br0虚拟交换机veth接口发出。虚拟交换机并不知道将包发送在哪里,因为在虚拟交换机的MAC地址映射表(ARP映射表)中并没有与当前目的IP对应的MAC地址。所以虚拟交换机会将该包发送到其上的全部端口。连接到Br0的VTEP接口知道如何转发这个数据帧,所以会将自己的MAC地址返回。这就是一个代理ARP响应,并且虚拟交换机Br0根据返回结果学会了如何转发该包。接下来虚拟交换机会更新自己的ARP映射表,叫10.0.0.4映射到本地VTEPMAC地址上。

现在Br0交换机已经学会如何转发目标C2的流量,接下来所有发送到C2的包都会被直接转发到VTEP接口。VTEP接口知道C2,是因为所有新启动的容器都会将自己的网络详情采用网络内置Gossip协议发送给相同Swarm集群内的其他节点。

交换机会将包转发到VTEP接口,VTEP完成数据帧的封装,这样就能在底层网络传输。具体来说,封装操作就是把VXLAN Header信息添加到以太帧当中。

VXLAN Header信息包含了VXLAN网络ID(VNID),其作用是记录VLAN到VXLAN的映射关系。每个VLAN都对应一个VNID,以便可以在解析后被转发到正确的VLAN。封装的时候会将数据帧放到UDP包中,并设置UDP的目的IP字段为node2节点的VTEPIP地址,同时设置UDP Socket端口为4789。这种封装方式保证了底层网络即使不知道任何关于VXLAN的信息,也可以完成数据传输。

当包达到node2之后,内核发现目的端口为UDP端口4789,同时还知道存在VTEP接口绑定到该Socket。所以内核将包发给VTEP,由VTEP读取VNID,解压包信息,并根据VNID发送到本地名为Br0的连接到VLAN的交换机上。在该交换机上,包被发送给容器C2

以上大体介绍了Docker覆盖网络是如何利用VXLAN技术的。

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

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

相关文章

从理论到实践:全面指导企业实现数字化转型的战略路径

全球企业数字化转型的必然性 在全球范围内,数字化转型成为了企业战略中的核心命题。随着云计算、大数据、人工智能等新兴技术的快速发展,企业的运营模式、管理体系及客户体验正在发生深刻的变革。数字技术不仅为企业带来了新的商业机会,还使…

【Elasticsearch】-图片向量化存储

需要结合深度学习模型 1、pom依赖 注意结尾的webp-imageio 包&#xff0c;用于解决ImageIO.read读取部分图片返回为null的问题 <dependency><groupId>org.openpnp</groupId><artifactId>opencv</artifactId><version>4.7.0-0</versio…

【2025】中医药健康管理小程序(安卓原生开发+用户+管理员)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

海报制作哪个软件好?这些在线工具不容错过

国庆节的脚步越来越近&#xff0c;不少公司正计划利用这个时机开展一些特别的庆典活动。 在这些活动中&#xff0c;海报作为一种传统的宣传方式&#xff0c;仍然是不可或缺的。但在制作海报时&#xff0c;我们可能会遇到创意瓶颈、时间限制或者预算约束等问题。 幸运的是&…

高棉语翻译神器上线!中柬互译,OCR识别,语音翻译一应俱全,《柬埔寨语翻译通》App

全新的高棉语翻译神器已经正式上架&#xff01; 无论你是安卓还是iOS用户&#xff0c;现在都可以轻松开始使用&#xff0c;开启你的翻译之旅&#xff01; 这款应用不仅仅是一个简单的翻译工具&#xff0c;它还支持中文与高棉语的双向翻译。翻译结果可以语音播放&#xff0c;翻…

AI服务器是什么?为什么要用AI服务器?

AI服务器的定义 AI服务器是一种专门为人工智能应用设计的服务器&#xff0c;它采用异构形式的硬件架构&#xff0c;通常搭载GPU、FPGA、ASIC等加速芯片&#xff0c;利用CPU与加速芯片的组合来满足高吞吐量互联的需求&#xff0c;为自然语言处理、计算机视觉、机器学习等人工智…

企业微信-前往服务商后台页面对接解决方案

序 我会告诉你在哪里点我会告诉你在哪里配置点下去他只返回auth_code的&#xff0c;我怎么登录 正文 他是在这个位置 是这样&#xff0c;应用授权安装第三方应用后&#xff0c;企业微信&#xff08;管理员角色&#xff09;是可以从pc端企业后台点第三方应用的。 如果我没记…

【余弦相似度】

余弦相似度 又称为余弦距离&#xff0c;利用两个向量之间的夹角的余弦值来衡量两个向量的余弦相似度&#xff0c;两个向量夹角越小&#xff0c;余弦值越接近1。 向量模&#xff08;向量长度&#xff09;计算方法&#xff1a; n维向量的相似度计算&#xff1a; 余弦相似度的取…

黑盒测试 | 挖掘.NET程序中的反序列化漏洞

通过不安全反序列化漏洞远程执行代码 img 今天&#xff0c;我将回顾 OWASP 的十大漏洞之一&#xff1a;不安全反序列化&#xff0c;重点是 .NET 应用程序上反序列化漏洞的利用。 &#x1f4dd;$ _序列化_与_反序列化 序列化是将数据对象转换为字节流的过程&#xff0c;字节流…

Entity更新坐标不闪烁需采用setCallbackPositions方法赋值

问题描述&#xff1a; 1.new mars3d.graphic.PolygonEntity({在更新点位高度模拟水面上身的时候&#xff0c;会存在闪烁 2.当把addDemoGraphic4添加到图层后&#xff0c;addDemoGraphic1水位变化不闪烁&#xff0c;把addDemoGraphic4注释后&#xff0c;addDemoGraphic1闪烁。…

UI自动化测试的边界怎么定义?

标题&#xff1a;定义UI自动化测试的边界&#xff1a;从0到1的详细指南 引言&#xff1a; UI自动化测试是现代软件开发过程中至关重要的一环。为了确保自动化测试的有效性和准确性&#xff0c;我们需要明确定义测试的边界。本文将从0到1为您提供一篇详细且规范的指南&#xf…

基于YOLOv8/YOLOv9/YOLOv10的河道漂浮物检测识别系统

摘要&#xff1a; 河道漂浮物检测识别是指利用技术手段自动识别河流、湖泊等水体表面的漂浮垃圾或物体的过程。随着环境保护意识的增强和技术的进步&#xff0c;河道漂浮物检测已经成为水环境保护和管理的重要组成部分。这项技术的应用可以帮助及时发现污染源&#xff0c;采取措…

一些线上常用排查问题的命令

排查CPU过高时使用到的一些命令 top free df top命令 top 命令是一个动态的实时视图&#xff0c;显示系统的整体运行状况&#xff0c;包括 CPU 使用率、内存使用情况、进程信息等。 free 命令 free 命令用于显示系统中物理内存和交换内存的使用情况。 df 命令 df 命令用…

纯前端表格导出Excel

先写好两个js文件 直接复制粘贴 文件目录是这样的 Bolb.js /* eslint-disable */ /* Blob.js* A Blob implementation.* 2014-05-27** By Eli Grey, http://eligrey.com* By Devin Samarin, https://github.com/eboyjr* License: X11/MIT* See LICENSE.md*//*global self, …

Vuex 入门与实战

引言 Vuex 是 Vue.js 官方推荐的状态管理库&#xff0c;它可以帮助我们更好地管理 Vue 应用的状态。在大型应用中&#xff0c;组件之间的状态共享和通信是一个非常重要的问题&#xff0c;而 Vuex 提供了一种优雅的解决方案。 在 Vue 应用中&#xff0c;数据的流动一般是单向的…

PCA贡献率

什么是 PCA&#xff1f; PCA&#xff08;Principal Component Analysis, 主成分分析&#xff09;是一种常用的数据降维技术。它通过找到一组新的互不相关的正交轴&#xff08;主成分&#xff09;&#xff0c;将高维数据映射到低维空间。这些新轴是按照数据的方差大小排列的&am…

让Tkinter更美观:教你同步Tkinter窗口与弹窗图标(Tkinter同步主窗口与Messagebox的图标)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 步骤1:主窗口图标📝 步骤2:messagebox 图标📝 示例代码📝 实现原理与代码解释⚓️ 相关链接 ⚓️📖 介绍 📖 你有没有注意到,在开发软件图形界面时,会需要弹出一些提示框,而这些提示框的图标总…

阿里国际发布最新版多模态大模型Ovis,拿下开源第一

看一眼菜品图就知道怎么做、能给植物看病、能把手写英文准确翻译成中文、还能精准分析财报数据……多模态能力再次升级&#xff01;阿里国际AI团队发布了一款多模态大模型Ovis&#xff0c;在图像理解任务上不断突破极限&#xff0c;多种具体的子类任务中均达到了SOTA&#xff0…

【Linux】-----进程第一弹

目录 概念 描述进程-PCB 查看进程 获取进程标识符 终止进程 fork创建进程 返回值说明 进程的状态 ①运行状态(R) ②浅度睡眠(S) ③深度睡眠(D) ④暂停状态(T) ⑤僵尸状态(Z)(重点) 是什么&#xff1f; 举例 危害 孤儿进程 ⑥死亡状态(X) 概念 课本上对于进程…

如何保护电脑文件夹?多种方法保护数据安全

在数字化时代&#xff0c;电脑中的文件夹往往存储着我们最私密、最重要的数据&#xff0c;如个人文档、照片、工作资料等。因此&#xff0c;保护这些文件夹免受未经授权的访问、盗窃或损坏变得尤为重要。本文将介绍多种方法来有效保护电脑文件夹及其数据安全。 文件夹保护3000 …