Docker核心架构原理的深入分析

打印 上一主题 下一主题

主题 792|帖子 792|积分 2376

一、前言

由于平常工作中对Docker使用还是比较频繁的,但是一样平常都是基础的功能使用,并未对其核心架构原理做梳理,因此抽空简单总结一下这玩意的一些核心概念点知识,以备后面求职工作时可以更为深入地相识这个容器化工具。
二、Docker简介

这个就再简单说一下,因为以前的一些文章也经常提到过基础先容了。
Docker的英文翻译是”搬运工“的意思,他搬运的东西就是我们常说的集装箱Container,Container 里面装的是任意类型的App,我们的开发职员可以通过Docker 将App变成一种尺度化的、可移植的、自管理的组件,我们可以在任何主流的利用系统中开发、调试和运行。

从他的官方先容图也就不难看出了:一个运货物的鲸鱼 。可以说非常形象,从概念上来看Docker和我们传统的虚拟机比较类似,只是更加轻量级,更加方便使用,非常得当高密度环境以及中小型部署,可以让我们用更少的资源做更多的事情。
和传统虚拟机相比较他主要有以下几点区别:

  • 传统的虚拟机必要模拟整台机器包罗硬件,每台虚拟机都必要有本身的利用系统,虚拟机一旦被开启,预分配给他的资源将全部被占用,每一个虚拟机包罗应用,必要的二进制和库,以及一个完备的用户利用系统;而容器技术是和我们的宿主机共享硬件资源及利用系统可以实现资源的动态分配。
  • 虚拟化技术依靠的是物理CPU和内存,是硬件级别的;而我们的Docker是构建在利用系统层面的,使用利用系统的容器化技术,所以Docker同样的可以运行在虚拟机上面
  • 虚拟机中的系统就是我们常说的利用系统镜像,比较复杂;而Docker比较轻量级,我们可以使用Docker部署一个独立的MySQL,就像类似于在虚拟机当中安装一个MySQL应用,但是我们用Docker部署的应用是完全隔离的。
  • 在传统的虚拟化技术是通过快照来生存的;而Docker引用了类似于源码的管理机制,将容器的快照汗青版本一一记录下来,切换成本之低
  • 传统的虚拟化技术在构建系统的时候非常复杂;而Docker可以通过一个简单的Dockerfile文件来构建整个容器,更紧张的是Dockerfile可以手动编写,如许应用开发职员可以通过发布Dockerfile来界说应用的环境和依靠,如许对于持续交付非常有利。
这些区别我们可以通过二者的结构图来看看:

不难看出,虚拟机和容器都是在硬件和利用系统以上的,虚拟机有 Hypervisor 层,Hypervisor 是整个虚拟机的核心地点。它为虚拟机提供了虚拟的运行平台,管理虚拟机的利用系统运行。每个虚拟机都有本身的系统和系统库以及应用。
而容器没有 Hypervisor 这一层,并且每个容器是和宿主机共享硬件资源及利用系统,那么由 Hypervisor 带来性能的损耗,在 linux 容器这边是不存在的。
但是虚拟机技术也有其优势,能为应用提供一个更加隔离的环境,不会因为应用步调的漏洞给宿主机造成任何威胁。同时还支持跨利用系统的虚拟化,例如你可以在 linux 利用系统下运行 windows 虚拟机。
从虚拟化层面来看,传统虚拟化技术是对硬件资源的虚拟,容器技术则是对进程的虚拟,从而可提供更轻量级的虚拟化,实现进程和资源的隔离。
从架构来看,Docker 比虚拟化少了两层,取消了 hypervisor 层和 GuestOS 层,使用 Docker Engine 进行调度和隔离,全部应用共用主机利用系统,因此在体量上,Docker 较虚拟机更轻量级,在性能上优于虚拟化,接近裸机性能。
   Docker Engine
  这个应该是我们安装docker经常都能见到的一个东西,那他详细是个啥呢?
现实上Docker Engine是一种开源容器化技术,用于构建和容器化我们的应用步调。Docker Engine充当具有以下功能的客户端服务器应用步调,他主要包罗下面几个组件:


  • 常驻运行的守护进程的服务器Dockerd
  • API,用于指定步调可以用来与Docker守护步调进行对话和指示的接口。
  • 命令行界面CLI,通过和REST API进行交互
CLI使用Docker API通过脚本或直接CLI命令来控制Docker守护步调或与Docker守护步调进行交互。很多其他Docker应用步调都使用基础API和CLI。守护步调创建和管理Docker对象,例如映像,容器,网络和卷。
 

   Docker架构 
  Docker使用了C/S体系架构,Docker客户端与Docker守护进程通信,Docker守护进程负责构建,运行和分发Docker容器。Docker客户端和守护进程可以在同一个系统上运行,也可以将Docker客户端毗连到远程Docker守护进程。Docker客户端和守护进程使用REST API通过UNIX套接字或网络接口进行通信。


  • Docker Damon DockerD用来监听Docker API的请求和管理Docker对象,好比镜像、容器、网络和Volume。
  • Docker Client docker client是我们和Docker进行交互的最主要的方式方法,好比可以通过docker run来运行一个容器,然后我们的这个client会把命令发送给上面的Docker。
  • Docker Registry 用来存储Docker镜像的堆栈,Docker Hub是Docker官方提供的一个公共堆栈,而且Docker默认也是从Docker Hub上查找镜像的,固然你也可以很方便的运行一个私有堆栈,当我们使用docker pull或者docker run命令时,就会从我们配置的Docker镜像堆栈中去拉取镜像,使用docker push命令时,会将我们构建的镜像推送到对应的镜像堆栈中。
  • Images 镜像,镜像是一个制度模板,带有Docker容器的说明,一样平常来说的,镜像会基于另外的一些基础镜像上面安装一个Nginx服务器,如许就可以构建一个属于我们本身的镜像了。
  • Containers 容器,容器是一个镜像的可运行的实例,可以使用Docker REST API或者CLI来利用容器,容器的实质是进程,但与直接在宿主执行的实例进程差别,容器进程属于本身的独立的命名空间。因此容器可以拥有本身的root文件系统、本身的网络配置、本身的进程空间、甚至本身的用户ID。容器内的经常是运行在一个隔离的环境里,使用起来,就好像在一个独立于宿主的系统下利用一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。
三、Docker的核心概念

   Docker namespace

  Linux 内核2.4.19中开始连续引用了namespace概念。目的是将某个特定的全局系统资源(global system resource)通过抽象方法使得namespace中的进程看起来拥有它们本身的隔离的全局系统资源实例。为运行中的进程提供了隔离,从而限定了它们对系统资源的访问,而运行中的进程却没故意识到这些限定。
命名空间是Linux内核强盛的特性。每个容器都有本身的命名空间,运行在此中的应用都是在独立利用系统中运行一样。命名空间包管了容器之间相互互不影响。

   Docker UnionFS

  UnionFS顾名思义,可以把文件系统上多个目录(分支)内容团结挂载到同一个目录下,而目录的物理位置是分开的。要理解unionFS,我们起首必要先相识bootfs和rootfs:

  • boot file system (bootfs) 包罗利用系统boot loader和kernel。用户不会修改这个文件系统,一旦启动乐成后,整个Linux内核加载进内存,之后bootfs会被卸载掉,从而释放内存。同样的内核版本差别Linux发行版,其bootfs都是不停的
  • root file system (rootfs) 包罗典范的目录结构(/dev/,/proc,/bin,/etc,/lib,/usr,/tmp)
Linux系统在启动时,rootfs起首会被挂载为只读模式,然后在启动完成后被修改为读写模式,随后它们就可以被修改了假设Dockerfile内容如下:
  1. FROM ubuntu:14.04
  2. ADD run.sh /
  3. VOLUME /data
  4. CMD ["./run.sh"]
复制代码
那么团结文件系统对应的层次结构如下图所示:

图中的顶上两层,是Docker为Docker容器新建的内容,而这两层属于容器范畴。这两层分别为Docker容器的初始层(init Layer)与可读写层(Read-write Layer)
初始层: 大多是初始化容器环境时,与容器相关的环境信息,如容器主机名,主机host信息以及域名服务文件等。
读写层: Docker容器内的进程只对可读可写层拥有写权限,别的层进程而言都是只读的(Read-Only)。关于VOLUME以及容器的host、hostname、resolv.conf文件都会挂载到这里


  • FROM ubuntu:14.04 设置基础镜像,此时会使用Ubuntu:14.04作为基础镜像
  • ADD run.sh / 将Dockerfile地点目录下的run.sh加至镜像的根目录,此时新一层的镜像只有一项内容,即根目录下的run.sh
  • VOLUME /data 设置镜像的存储,此VOLUME在容器内部的路径为/data。此时并未在新一层的镜像中添加任何文件,但是更新了镜像的json文件,以便通过此镜像启动容器时获取这方面的信息(下面会有详细的先容)
  • CMD ["./run.sh"] 设置镜像的默认执行入口,此命令同样不会在新建镜像中添加任何文件,仅仅在上一层镜像json文件的基础上更新新的镜像的json文件
   Docker CGroups

  Docker CGroups(也称为控制组)是Linux内核的一个特性,用于限定和隔离资源的使用。Docker使用CGroups来管理和分配系统资源,以确保容器之间的资源互不干扰。
之前也提到过,Docker容器使用Linux namespace来隔离其运行环境,使得容器中的进程看起来就像在一个独立的环境中运行。但是光有运行环境隔离还不敷,因为这些进程还是可以不受限定地使用系统资源,好比网络、磁盘、CPU以及内存等。关于其目的,是为了防止它占用了太多的资源而影响到别的进程;另一方面,在系统资源耗尽的时候,Linux内核会触发OOM (out of memory killer,OOM会在系统内存耗尽的环境下跳出来,选择性的干掉一些进程以求释放一些内存)这会让一些被杀掉的进程成了无辜的替死鬼,因此为了让容器中的进程更加可控,Docker使用Linux CGroups来限定容器中的进程允许使用的系统资源。
CGroups允许管理员将一组进程构造在一起,并为它们分配特定资源的限定。这些资源可以包罗CPU、内存、磁盘I/O、网络带宽等。通过使用CGroups,Docker可以为每个容器分配一定数量的资源,并确保容器不会凌驾其限定。
CGroups通过将进程分配到差别的组中,同时使用Linux内核的调度器来控制资源分配。每个CGroup都有一个层次结构,可以将进程分配到差别的组中,从而实现资源的隔离和限定。
Docker使用CGroups来限定容器的资源使用。例如,我们可以使用CGroups来限定容器使用的CPU的数量和频率,以防止容器占用全部系统资源。也可以使用CGroups来限定容器使用的内存量,以防止容器使用过多的内存导致系统宕机。
四、Docker存储驱动

Docker最开始采用AUFS作为文件系统,也得益于AUFS分层的概念,实现了多个Container可以共享一个image。但是由于AUFS未并入Linux内核,且只支持Ubuntu,考虑到兼容性题目,在Docker 0.7 版本中引入了存储驱动,如今,Docker支持AUFS、Btrfs、Devicemapper、OverlayFS、ZFS五种存储驱动。
(1)原理说明

写时复制 (CoW)

全部驱动都用到的技术————写时复制,Cow全称copy-on-write,表现只是在必要写时才去复制,这个是针对已有文件的修改场景。好比基于一个image启动多个Container,如果每个Container都去分配一个image一样的文件系统,那么将会占用大量的磁盘空间。而CoW技术可以让全部的容器共享image的文件系统,全部数据都从image中读取,只有当要对文件进行写利用时,才从image里把要写的文件复制到本身的文件系统进行修改。所以无论有多少个容器共享一个image,所做的写利用都是对从image中复制到本身的文件系统的副本上进行,并不会修改image的源文件,且多个容器利用同一个文件,会在每个容器的文件系统里生成一个副本,每个容器修改的都是本身的副本,相互隔离,互不影响。使用CoW可以有效的提高磁盘的使用率。
用时分配 (allocate-on-demand)

写是分配是用在原本没有这个文件的场景,只有在要新写入一个文件时才分配空间,如许可以提高存储资源的使用率。好比启动一个容器,并不会因为这个容器分配一些磁盘空间,而是当有新文件写入时,才按需分配新空间。
(2)存储驱动先容

AUFS

AUFS (AnotherUnionFS)是一种UnionFS,是文件级的存储驱动。AUFS能透明覆盖一或多个现有文件系统的层状文件系统,把多层合并成文件系统的单层表现。简单来说就是支持将差别目录挂载到同一个虚拟文件下的文件系统。这种文件系统可以一层一层地叠加修改文件。无论底下有多少层都是只读的,只有最上层的文件系统是可写的。当必要修改一个文件时,AUFS创建该文件的一个副本,使用CoW将文件从只读层复制到可写层进行修改,效果也生存在可写层。在Docker中,只读层就是image,可写层就是Container。

 OverlayFS

OverlayFS是一种和AUFS很类似的文件系统,与AUFS相比,OverlayFS有以下特性;
1) 更简单地设计;
2) 从Linux 3.18开始,就加入了Linux内核主线;
3) 速度更快
因此,OverlayFS在Docker社区关注提高很快,被很多人认为是AUFS的继承者。Docker的overlay存储驱动使用了很多OverlayFS特性来构建和管理镜像与容器的磁盘结构
从Docker1.12起,Docker也支持overlay2存储驱动,相比于overlay来说,overlay2在inode优化上更加高效,但overlay2驱动只兼容Linux kernel4.0以上的版本
注意: 自从OverlayFS加入kernel主线后,它的kernel模块中的名称就从overlayfs改为overlay了
OverlayFS使用两个目录,把一个目录置放于另一个智商,并且对外提供单个同一的视角。这两个目录通常被称作层,这个分层的技术被称作union mount。术语上,下层的目录叫做lowerdir,上层的叫做upperdir。对外展示的同一视图称作merged。

注意镜像层和容器层是如何处理雷同文件的: 容器层(upperdir)的文件是显性的,会隐藏镜像层(lowerdir)雷同文件的存在。并在容器映射(merged)表现出同一视图。
overlay驱动只能工作在两层之上,也就是说多层镜像不能用多层OverlayFS实现。替换的,每个镜像层在/var/lib/docker/overlay中用本身的目录来实现,使用硬链接这种有效使用空间的方法,来引用底层分享的数据。
注意: Docker1.10之后,镜像层ID和/var/lib/docker中的目录名不再一一对应。
创建一个容器,overlay驱动团结镜像层和一个新目录给容器。镜像顶层中的overlay是只读lowerdir,容器的新目录是可写的upperdir
   OverlayFS (overlay2)镜像分层与共享
  overlay驱动只工作在一个lower OverlayFS层之上,因此必要硬链接来实现多层镜像,但overlay2驱动原生地支持多层lower OverlayFS镜像(最多128层)。因此overlay2驱动在合层相关的命令(如build何commit)中提供了更好的性能,与overlay驱动对比,减少了inode消耗
   容器overlay读写
  有三种场景,容器会通过overlay只读访问文件:

  • 容器层不存在的文件 如果容器只读打开一个文件,但该容器不在容器层(upperdir),就要从镜像层(lowerdir)中读取。这会引起很小的性能消耗
  • 只存在于容器层的文件 如果容器只读权限打开一个文件,并且容器只存在于容器层(upperdir)而不是镜像层(lowerdir),那么直接从镜像层读取文件,无额外的性能损耗
  • 文件同时存在于容器层和镜像层 那么会读取容器层的文件,因为容器层(upperdir)隐层了镜像层(lowerdir)的同名文件,因此,也没有额外的性能损耗
有以下场景容器修改文件
第一次写一个文件,容器第一次写一个已经存在的文件,容器层不存在这个文件。overlay/overlay2驱动执行copy-up利用,将文件从镜像层拷贝到容器层。然后容器修改容器层新拷贝的文件


  • copy-up 利用只发生在第一次写文件时,后续的对同一个文件的鞋利用都是直接针对拷贝到容器层的文件
  • OverlayFS只工作在两层中。这比AUFS要在多层镜像中查找时性能要好
删除文件和目录 删除文件时,容器会在镜像层创建一个whiteout文件,而镜像层的文件并没有删除,但是whiteout文件会隐藏它。容器中删除一个目录,容器层会创建一个不透明目录,这和whiteout文件隐藏镜像层的文件类似
重命名目录 只有在源文件和目的路径都在顶层容器层时,才允许执行rename利用,否则返回EXDEV。因此,应用必要能够处理EXDEV,并且回滚利用,执行替换的"拷贝和删除"策略
   在Docker中配置overlay2 存储驱动
  为了给Docker配置overlay存储驱动,你的Docker host必须在Linux kernel3.18版本之上,并且加载了overlay内核驱动。对于overlay2驱动,kernel版本必须在4.0或以上。OverlayFS可以运行在大多数Linux文件系统之上。这里我用Ubuntu22.04进行配置:
  1. #1.停止Docker
  2. root@young-virtual-machine:~/桌面#systemctl stop docker
  3. #2.检查kernel版本,确定overlay的内核模块是否加载
  4. root@young-virtual-machine:~/桌面# uname -r
  5. 6.5.0-26-generic
  6. root@young-virtual-machine:~/桌面# lsmod |grep overlay
  7. overlay               196608  8
  8. #如果没有过滤出overlay模块,说明驱动没有加载,使用下面方法进行加载
  9. root@young-virtual-machine:~/桌面# modprobe overlay
复制代码
然后使用verlay2存储来启动docker,配置方法有2种:

  • 在Docker的启动配置文件中添加--storage-driver=overlay2的标志到DOCKER_OPTS中,如许可以持久化配置。
  • 或者将配置持久化到配置文件/etc/docker/daemon.json中 :"storage-driver": "overlay2"。
  1. root@young-virtual-machine:~/桌面# cat /etc/docker/daemon.json
  2. {
  3. "exec-opts": ["native.cgroupdriver=systemd"],
  4. "registry-mirrors": ["https://hjvrgh7a.mirror.aliyuncs.com"],
  5. "log-driver": "json-file",
  6. "log-opts": {
  7. "max-size": "100m"
  8. },
  9. "storage-driver": "overlay2"
  10. }
  11. root@young-virtual-machine:~/桌面# docker info
  12. Client: Docker Engine - Community
  13. Version:    25.0.4
  14. Context:    default
  15. Debug Mode: false
  16. Plugins:
  17.   buildx: Docker Buildx (Docker Inc.)
  18.     Version:  v0.13.0
  19.     Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  20.   compose: Docker Compose (Docker Inc.)
  21.     Version:  v2.24.7
  22.     Path:     /usr/libexec/docker/cli-plugins/docker-compose
  23. Server:
  24. Containers: 8
  25.   Running: 8
  26.   Paused: 0
  27.   Stopped: 0
  28. Images: 8
  29. Server Version: 25.0.4
  30. Storage Driver: overlay2
  31.   Backing Filesystem: extfs
  32.   Supports d_type: true
  33.   Using metacopy: false
  34.   Native Overlay Diff: true
  35.   userxattr: false
  36. Logging Driver: json-file
  37. Cgroup Driver: systemd
  38. Cgroup Version: 2
  39. Plugins:
  40.   Volume: local
  41.   Network: bridge host ipvlan macvlan null overlay
  42.   Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
  43. Swarm: inactive
  44. Runtimes: io.containerd.runc.v2 runc
  45. Default Runtime: runc
  46. Init Binary: docker-init
  47. containerd version: ae07eda36dd25f8a1b98dfbf587313b99c0190bb
  48. runc version: v1.1.12-0-g51d5e94
  49. init version: de40ad0
  50. Security Options:
  51.   apparmor
  52.   seccomp
  53.    Profile: builtin
  54.   cgroupns
  55. Kernel Version: 6.5.0-26-generic
  56. Operating System: Ubuntu 22.04.4 LTS
  57. OSType: linux
  58. Architecture: x86_64
  59. CPUs: 4
  60. Total Memory: 3.78GiB
  61. Name: young-virtual-machine
  62. ID: 83b0f441-c3fa-446a-b3b1-85ae528fd8ef
  63. Docker Root Dir: /var/lib/docker
  64. Debug Mode: false
  65. Experimental: false
  66. Insecure Registries:
  67.   127.0.0.0/8
  68. Registry Mirrors:
  69.   https://hjvrgh7a.mirror.aliyuncs.com/
  70. Live Restore Enabled: false
复制代码
此时可以看到Docker已经使用overlay2作为存储引擎了。
Devicemapper

Device mapper是Linux内核2.6.9后支持的,提供的一种从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据本身必要制定实现存储资源的管理策略。AUFS和OverlayFS都是文件级存储,而Devicemapper是块级存储,全部的利用都是直接对块进行利用,而不是文件。
Devicemapper驱动会先在块设备上创建一个资源池,然后在资源池上创建一个带有文件系统的根本设备,全部镜像都是这个根本设备的快照,而容器则是镜像的快照。所以在容器看到文件系统是资源池上根本设备的文件系统的快照,并不是为容器分配空间。当要修改已有文件时,再使用CoW为容器快照分配块空间,将要修改的数据复制到容器快照中的新快里再进行修改。
Devicemapper驱动默认会创建一个100G的文件包罗镜像和容器,每个容器被限定在10G巨细的卷内,可以本身配置调整。

   Btrfs
  Btrfs被称为下一代写时复制的文件系统,并入Linux内核,也是文件级存储,但可以像Devicemapper不停被利用底层设备。Btrfs把文件系统的一部门配置为一个完备的子文件系统,称之为subvolume。采用subvolume,一个大的文件系统可以被分别多个子文件系统,这些子文件系统共享底层的设备空间,在必要磁盘空间时便从底层设备中分配,好比Btrfs支持动态添加设备。用户在系统中新增长硬盘后,可以使用Btrfs的命令将该设备添加到文件系统中。
Btrfs把一个大的文件系统当成一个资源池,配置成多个完备的子文件系统,还可以往资源池里加新的子文件系统,而基础镜像则是子文件系统的快照,每个子镜像和容器都有本身的快照,这些快照都是subvolume的快照。

当写入一个新文件时,在容器的快照里为其分配了一个新的数据块,文件写在这个空间里,叫做用时分配。而当修改已有文件时,使用CoW复制分配一个新的原始数据和快照,在这个新分配的空间变动数据,等结束后再进行相关的数据结构指引到新子文件系统和快照,原来的原始数据和快照没有指针指示,被覆盖。
ZFS

ZFS文件系统是一个革命性的全新的文件系统,它从根本上改变了文件系统的管理方式,ZFS完全扬弃了"卷管理",不再创建虚拟的卷,而是把全部设备会合到一个存储池中来进行管理,用"存储池"的概念来管理物理存储空间。
已往,文件系统都是构建在物理设备之上的,并为数据提供冗余,"卷管理"的概念提供了一个单设备的映像。而ZFS创建在虚拟的,被称为"zpools"的存储池上。每个存储池由若干虚拟设备(virtual devices,vdevs)组成。这些虚拟设备可以是原始磁盘,也可以是一个RAID的镜像设备,或者是非尺度RAID等级的多磁盘组。如许zpool上的文件系统可以使用这些虚拟设备的总存储容量。

在Docker宿主机上使用ZFS存储驱动,镜像的最底层(base layer)是一个ZFS文件系统。每一个镜像子层都是一个基于下层ZFS快照的ZFS克隆实体。一个容器的文件系统是一个ZFS克隆,下层是从镜像层创建的快照。全部ZFS数据实体都是从一个共用的zpool分配空间。他们间的关联关系如下:

起首从zpool里分配一个ZFS文件系统给镜像的基础层,而别的镜像层则是这个ZFS文件系统快照的克隆。克隆是可写的,并根据必要在zpool中分配物理空间。而快照是只读的,让base层成为一个不变的实体。当容器启动时再将一个读写层加入到镜像的最上层。
当要写一个新文件时,使用按需分配,一个新的数据块从zpool里生成,新的数据写入这个块,而这个新的空间存储于容器(ZFS的克隆)里。当要修改一个已存在的文件时,使用写时复制,分配一个新空间并把原始数据复制到新空间完成修改。
存储驱动的对比及适应场景

存储驱动名称特点优点缺点适用场景
AUFS
团结文件系统未并入内核主线文件存储
作为doker的第一个存储驱动,新版默认使用Devicemapper有多层,在进行写复制利用时,如果文件比较大且勋在比较低的层,大概较慢大并发但少IO的场景
OverlayFS团结文件系统未并入内核主线文件存储只有两层不管修改的内容巨细,都会复制整个文件,对大文件进行修改时要比小文件要消耗更多时间大并发但少IO的场景
Devicemapper并入内核主线块级存储块级无论是大文件还是小文件都只复制必要修改的块并不是整个文件不支持共享存储,表现当有多个容器读同一个文件时,必要生成多个副本,在很多容器后停环境下大概会导致磁盘溢出得当IO密集的场景
Btrfs并入内核主线块级存储可以像Devicemapper直接利用系统底层设备支持动态添加设备不支持共享存储,当有多个容器读同一个文件时,必要生成多个副本不得当在高密度容器的PAAS平台
ZFS把全部设备会合到一个存储池来进行管理支持多个容器共享一个缓存块得当内存大的环境COW使碎片化题目更加严肃文件在硬盘上的物理地址会变得不再连续,次序会变得性能比较差。得当PAAS和高度密集的场景
一样平常来说,overlay2驱动更快一些,几乎肯定比AUFS和devicemapper更快,在某些环境下,大概比Btrfs也快。在使用overlay2存储驱动时,必要注意以下几点:


  • Page Caching 页缓存
  • OverlayFS支持页缓存,也就是说如果多个容器访问同一个文件,可以共享一个或多个页缓存选项。这使得overlay2驱动高效地使用了内存,是Pass平台或者高密度场景很好的选择
  • copy_up 和AUFS一样,在容器第一次修改文件时,OverlayFS都必要执行copy_up利用,这会给利用带来一些耽误————尤其这个拷贝很大的文件时,不外一旦文件已经执行了这个向上拷贝的利用后,全部后续对这个文件的利用都只针对这份容器层的拷贝而已
  • Inode limits 使用overlay存储驱动大概导致过多的inode消耗,尤其是Docker host上镜像和容器的数量增长时。大量的镜像或者很多容器启停,会迅速消耗该Docker host的inode。但是overlay2 存储驱动不存在这个题目
overlay2存储驱动已经成为了Docker首选存储驱动,并且性能优于AUFS和devicemapper。不外,也带来了一些与其他文件系统不兼容性,如对open和rename利用的支持,另外,overlay和overlay2相比,overlay2支持了多层镜像,优化了inode的使用。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

涛声依旧在

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表