docker的联合文件系统 UnionFS《深入docker底层原理》

介绍

docker最大的贡献就是定义了容器镜像的分层的存储格式,docker镜像技术的基础是联合文件系统(UnionFS),其文件系统是分层的。这样既可以充分利用共享层,又可以减少存储空间占用。

联合挂载系统的工作原理:读:如果文件在upperdir(容器)层,直接读取文件;如果文件不在upperdir(容器)层,则从镜像层(lowerdir)读取。

目前docker支持的联合文件系统有很多种,包括:AUFS、overlay、overlay2、DeviceMapper、VSF等。
在这里插入图片描述

查看docker容器使用的文件系统使用的命令如下,其中Storage Driver: overlay2代表使用的是overlay2联合文件系统。

[root@home]# docker info
Client:Context:    defaultDebug Mode: falsePlugins:app: Docker App (Docker Inc., v0.9.1-beta3)buildx: Docker Buildx (Docker Inc., v0.9.1-docker)scan: Docker Scan (Docker Inc., v0.21.0)Server:Containers: 2Running: 1Paused: 0Stopped: 1Images: 17Server Version: 20.10.21Storage Driver: overlay2Backing Filesystem: xfsSupports d_type: trueNative Overlay Diff: trueuserxattr: falseLogging Driver: json-fileCgroup Driver: cgroupfsCgroup Version: 1Plugins:Volume: localNetwork: bridge host ipvlan macvlan null overlayLog: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslogSwarm: inactiveRuntimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runcDefault Runtime: runcInit Binary: docker-initcontainerd version: 1c90a442489720eec95342e1789ee8a5e1b9536frunc version: v1.1.4-0-g5fd4c4dinit version: de40ad0Security Options:seccompProfile: defaultKernel Version: 3.10.0-957.el7.x86_64Operating System: CentOS Linux 7 (Core)OSType: linuxArchitecture: x86_64CPUs: 2Total Memory: 3.701GiBName: 10-6-9-59ID: XISV:HHG5:YV5H:AQIM:WE4G:6IXJ:2N2Q:SZOM:XBCP:BTGB:HI7P:4W7ODocker Root Dir: /var/lib/dockerDebug Mode: falseRegistry: https://index.docker.io/v1/Labels:Experimental: falseInsecure Registries:harbor.lys.siteRegistry Mirrors:https://harbor.lys.site/https://vre6wzor.mirror.aliyuncs.com/Live Restore Enabled: false

修改

修改对应文件系统,可以通过/etc/docker/daemon.json文件的 “storage-driver”:参数

[root@home]# cat /etc/docker/daemon.json 
{"registry-mirrors": ["https://vre6wzor.mirror.aliyuncs.com"],"exec-opts": ["native.cgroupdriver=systemd"],"log-driver": "json-file","log-opts": {"max-size": "100m"},"storage-driver": "overlay2","storage-opts": ["overlay2.override_kernel_check=true"]
}

原理

UnionFS

UnionFS 其实是一种为 Linux 操作系统设计的用于把多个文件系统『联合』到同一个挂载点的文件系统服务。而 AUFS 即 Advanced UnionFS 其实就是 UnionFS 的升级版,它能够提供更优秀的性能和效率。

AUFS 作为联合文件系统,它能够将不同文件夹中的层联合(Union)到了同一个文件夹中,这些文件夹在 AUFS 中称作分支,整个『联合』的过程被称为联合挂载(Union Mount):

在这里插入图片描述

overlay2

在这里插入图片描述
如上图所示,OverlayFS将单个Linux主机上的两个目录合并成一个目录,这些目录被称为层,统一过程被称为联合挂载。OverlayFS关联的底层目录称为lowerdir,lowerdir是只读的镜像层(image layer),其中就包含bootfs/rootfs层,bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,当boot成功 kernel 被加载到内存中,bootfs就被umount了,rootfs(root file system)包含的就是典型Linux系统中的/dev、/proc、/bin、/etc等标准目录。lowerdir是可以分很多层的,除了bootfs/rootfs层以外,还可以通过Dockerfile建立很多image层。

对应的高层目录upperdir层是lowerdir的上一层,只有这一层可读可写的,其实就是Container层,在启动一个容器的时候会在最后的image层的上一层自动创建,所有对容器数据的更改都会发生在这一层。

联合挂载后merged层就是联合挂载层,也就是给用户暴露的统一视觉,将image层和container层结合,就如最上边的图中描述一致,同一文件,在此层会展示离它最近的层级里的文件内容,或者可以理解为,只要container层中有此文件,便展示container层中的文件内容,若container层中没有,则展示image层中的。

如下容器的整体结构

在这里插入图片描述
在centos操作系统下,对应联合文件系统overlay2目录是:/var/lib/docker/overlay2,使用docker inspect [容器ID]就可以看到这几个层所在的位置。示例

docker inspect 03cf6fafe267
[{"Id": "03cf6fafe26723252ba50f559354575c9ee8518af9c94380f2286a7ded7fe5d2","Created": "2023-06-30T10:07:07.228528513Z","Path": "/portainer","Args": [],"State": {"Status": "running","Running": true,"Paused": false,"Restarting": false,"OOMKilled": false,"Dead": false,"Pid": 3670,"ExitCode": 0,"Error": "","StartedAt": "2023-06-30T10:07:07.822465986Z","FinishedAt": "0001-01-01T00:00:00Z"},"Image": "sha256:580c0e4e98b06d258754cf28c55f21a6fa0dc386e6fe0bf67e453c3642de9b8b","ResolvConfPath": "/var/lib/docker/containers/03cf6fafe26723252ba50f559354575c9ee8518af9c94380f2286a7ded7fe5d2/resolv.conf","HostnamePath": "/var/lib/docker/containers/03cf6fafe26723252ba50f559354575c9ee8518af9c94380f2286a7ded7fe5d2/hostname","HostsPath": "/var/lib/docker/containers/03cf6fafe26723252ba50f559354575c9ee8518af9c94380f2286a7ded7fe5d2/hosts","LogPath": "/var/lib/docker/containers/03cf6fafe26723252ba50f559354575c9ee8518af9c94380f2286a7ded7fe5d2/03cf6fafe26723252ba50f559354575c9ee8518af9c94380f2286a7ded7fe5d2-json.log","Name": "/prtainer-test","RestartCount": 0,"Driver": "overlay2","Platform": "linux","MountLabel": "","ProcessLabel": "","AppArmorProfile": "","ExecIDs": null,"HostConfig": {"Binds": ["/var/run/docker.sock:/var/run/docker.sock"],"ContainerIDFile": "","LogConfig": {"Type": "json-file","Config": {}},"NetworkMode": "default","PortBindings": {"9000/tcp": [{"HostIp": "","HostPort": "9000"}]},"RestartPolicy": {"Name": "always","MaximumRetryCount": 0},"AutoRemove": false,"VolumeDriver": "","VolumesFrom": null,"CapAdd": null,"CapDrop": null,"CgroupnsMode": "host","Dns": [],"DnsOptions": [],"DnsSearch": [],"ExtraHosts": null,"GroupAdd": null,"IpcMode": "private","Cgroup": "","Links": null,"OomScoreAdj": 0,"PidMode": "","Privileged": false,"PublishAllPorts": false,"ReadonlyRootfs": false,"SecurityOpt": null,"UTSMode": "","UsernsMode": "","ShmSize": 67108864,"Runtime": "runc","ConsoleSize": [0,0],"Isolation": "","CpuShares": 0,"Memory": 0,"NanoCpus": 0,"CgroupParent": "","BlkioWeight": 0,"BlkioWeightDevice": [],"BlkioDeviceReadBps": null,"BlkioDeviceWriteBps": null,"BlkioDeviceReadIOps": null,"BlkioDeviceWriteIOps": null,"CpuPeriod": 0,"CpuQuota": 0,"CpuRealtimePeriod": 0,"CpuRealtimeRuntime": 0,"CpusetCpus": "","CpusetMems": "","Devices": [],"DeviceCgroupRules": null,"DeviceRequests": null,"KernelMemory": 0,"KernelMemoryTCP": 0,"MemoryReservation": 0,"MemorySwap": 0,"MemorySwappiness": null,"OomKillDisable": false,"PidsLimit": null,"Ulimits": null,"CpuCount": 0,"CpuPercent": 0,"IOMaximumIOps": 0,"IOMaximumBandwidth": 0,"MaskedPaths": ["/proc/asound","/proc/acpi","/proc/kcore","/proc/keys","/proc/latency_stats","/proc/timer_list","/proc/timer_stats","/proc/sched_debug","/proc/scsi","/sys/firmware"],"ReadonlyPaths": ["/proc/bus","/proc/fs","/proc/irq","/proc/sys","/proc/sysrq-trigger"]},"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/840faba1dd5726eec55029b0da956195e2234853313e3c78e8f3f96e51244401-init/diff:/var/lib/docker/overlay2/0b1f62ad330df70a06a47e85689eedbb1c59f48df4b775c166468286f6aa3198/diff:/var/lib/docker/overlay2/5d83a80e080ae21964392ebfb9868e217bc223f9b5b70018042765b7a9ea3995/diff:/var/lib/docker/overlay2/fce6d44bff996fcd898fb8cc182389be24c9798d2cef20ecf0caa7eac428a316/diff","MergedDir": "/var/lib/docker/overlay2/840faba1dd5726eec55029b0da956195e2234853313e3c78e8f3f96e51244401/merged","UpperDir": "/var/lib/docker/overlay2/840faba1dd5726eec55029b0da956195e2234853313e3c78e8f3f96e51244401/diff","WorkDir": "/var/lib/docker/overlay2/840faba1dd5726eec55029b0da956195e2234853313e3c78e8f3f96e51244401/work"},"Name": "overlay2"},"Mounts": [{"Type": "bind","Source": "/var/run/docker.sock","Destination": "/var/run/docker.sock","Mode": "","RW": true,"Propagation": "rprivate"},{"Type": "volume","Name": "e77fbc451ca1b8366c10a52dc30d87aa6b482f78e48c52f8082e607e316128f0","Source": "/var/lib/docker/volumes/e77fbc451ca1b8366c10a52dc30d87aa6b482f78e48c52f8082e607e316128f0/_data","Destination": "/data","Driver": "local","Mode": "","RW": true,"Propagation": ""}],"Config": {"Hostname": "03cf6fafe267","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"ExposedPorts": {"9000/tcp": {}},"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],"Cmd": null,"Image": "portainer/portainer","Volumes": {"/data": {}},"WorkingDir": "/","Entrypoint": ["/portainer"],"OnBuild": null,"Labels": {}},"NetworkSettings": {"Bridge": "","SandboxID": "3a7037ed8c5eee246cc4cee7a525bca0fad7dfc3f3aa455d34e2333c58e460b8","HairpinMode": false,"LinkLocalIPv6Address": "","LinkLocalIPv6PrefixLen": 0,"Ports": {"9000/tcp": [{"HostIp": "0.0.0.0","HostPort": "9000"},{"HostIp": "::","HostPort": "9000"}]},"SandboxKey": "/var/run/docker/netns/3a7037ed8c5e","SecondaryIPAddresses": null,"SecondaryIPv6Addresses": null,"EndpointID": "7eee2f172e17fe50813a1ba82b76a0b32cdd9b8011eb3337ac530d73dcac9b5f","Gateway": "172.17.0.1","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","MacAddress": "02:42:ac:11:00:02","Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "5c0d2dd61ef719f9e167485e3f80151c47c60e973d16b8ec40f41367adb4cf91","EndpointID": "7eee2f172e17fe50813a1ba82b76a0b32cdd9b8011eb3337ac530d73dcac9b5f","Gateway": "172.17.0.1","IPAddress": "172.17.0.2","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:11:00:02","DriverOpts": null}}}}
]

overlay的模拟实践

1.显示已挂载的Overlay文件系统

[root@newhostname to]# mount | grep overlay
overlay on /var/lib/docker/overlay2/083352f2addd2a15848f6f2742595c7706d74721b688f2665766c2397690febb/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/RFCU37H7W5QLVKZQYWK4WKS2ZR:/var/lib/docker/overlay2/l/A2GRPWBIX7ETOJISQK6HBFAXDR:/var/lib/docker/overlay2/l/722WJHOAIK2L42LBVVRQAKDSA4:/var/lib/docker/overlay2/l/M6XHLB5ZALNKEPMJBDGUAZ5LTG,upperdir=/var/lib/docker/overlay2/083352f2addd2a15848f6f2742595c7706d74721b688f2665766c2397690febb/diff,workdir=/var/lib/docker/overlay2/083352f2addd2a15848f6f2742595c7706d74721b688f2665766c2397690febb/work)

请按照以下步骤进行操作:

2. 创建一个存在的目录作为挂载点:

sudo mkdir /path/to/mount/point

3. 使用overlay文件系统挂载:

sudo mount -t overlay overlay -o lowerdir=/path/to/lower,upperdir=/path/to/upper,workdir=/path/to/work /path/to/mount/point

请将/path/to/lower替换为底层目录的实际路径,将/path/to/upper替换为上层目录的实际路径,将/path/to/work替换为工作目录的实际路径。

4. 卸载Overlay文件系统时,请使用以下命令:

sudo umount /path/to/mount/point

请注意修改命令中的路径以正确适配您的系统配置,确保目录的存在和权限设置正确。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GPT API+自动化提高生产力

一、简介 一句话说明白,就是自动采集需求,通过GPT API传送给GPT,然后GPT加工后,输出结果,利用自动化工具进行回复/存储/发布,甚至调用手机硬件或者使用WEBHOOK,或者联动IFTTT触发智能硬件的应用…

计算机体系结构基础知识介绍之缓存性能的十大进阶优化之编译器优化和硬件预取(六)

优化七:编译器优化,降低miss率 处理器和主内存之间不断扩大的性能差距促使编译器编写者仔细检查内存层次结构,看看编译时优化是否可以提高性能。再次,研究分为指令缺失的改进和数据缺失的改进。接下来介绍的优化可以在许多现代编…

rocketMq消息队列原生api使用以及rocketMq整合springboot

rocketMq消息队列 文章目录 rocketMq消息队列一、RocketMQ原生API使用1、测试环境搭建2、RocketMQ的编程模型3、RocketMQ的消息样例3.1 基本样例3.2 顺序消息3.3 广播消息3.4 延迟消息3.5 批量消息3.6 过滤消息3.7 事务消息3.8 ACL权限控制 二、SpringBoot整合RocketMQ1、快速实…

某网站JS加密、OB混淆与CSS反爬实战分析

1. 写在前面 最近一段时间接触了一些小说网站的业务。发现很多的小说网站,甚至一些小站它们的安全防护措施做的都很到位!例如上次说到的的五秒盾也是存在于一个小说小站。今天要讲的这个网站它集JS加密、ob混淆、CSS反爬于一体 目标站点: aH…

pytest自动化测试实战之执行参数

上一篇介绍了如何运行pytest代码,以及用例的一些执行规则,执行用例发现我们中间print输出的内容,结果没有给我们展示出来,那是因为pytest执行时,后面需要带上一些参数。 参数内容 我们可以在cmd中通过输入 pytest -h…

RuoyiCloudPlus结合SkyWalking-9.4.0 docker部署流程

一、SkyWalking-9.4.0 docker部署流程 docker-compse.yml sky-oap:image: apache/skywalking-oap-server:9.3.0container_name: ruoyi-sky-oapports:- "11800:11800"- "12800:12800"environment:JAVA_OPTS: -Xms1G -Xmx2G#记录数据的有效期,单…

Devops系列四(使用argocd部署java应用到k8s容器)

一、说在前面的话 上文已为我们准备好了以下内容: 制作java应用的docker镜像,并推送至镜像仓库上传helm yaml代码至gitlab仓库(此gitlab和java应用所在的gitlab可以独立,也可以在一起,但是不宜在同一个工程&#xff…

Vscosde中写html的速写规则和快捷键

目录 vsCode速写规则! enter 生成html框架ctrl / 注释生成html元素:直接写html,enter直接生成 并且添加内容批量生成> 元素嵌套 同级生成每个元素都有的属性. class # id样式放入css中 link 连接快速使用样式优先级 vsCode速写规则 ! enter 生成h…

PS188——谱瑞(Parade)推动的 Type-C扩展坞红海战略

2020年7月份谱瑞(Parade)以3750万美元的价格收购了睿思科技(Fresco Logic),对于芯片设计公司来说,并购往往是资本因素考量 >技术因素考量 >市场战略考量。 芯片设计公司的并购,往往更看重的是客户的…

mysql离线安装

MySQL离线安装 进行MySQL离线安装包,当前安装版本为MySQL8.0.32 下载页面:https://downloads.mysql.com/archives/community/ 下载地址:https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.36-1.el7.x86_64.rpm-bundle.tar 将下载完成的安…

梅雨季“霉”烦恼,防潮自救指南请收好

魔都的雨下个不停,天气也异常闷热,原来是上海已经入梅了。“雨连连、湿哒哒、闷兮兮”的梅雨季,湿漉漉的空气,感觉身体也跟着“发霉”。不想做梅雨季最“潮”人,赶紧码住这份抗“霉”攻略。 梅雨季最大的特点是空气湿度…

第2章 SSD主控和全闪存阵列

通过第一章可知,SSD主要由两大模块组成:主控和闪存介质。其中,主控的作用包括: (1)实现标准主机接口与主机通信; (2)实现与闪存的通信; (1&#x…