文章目录

  • 前言
  • Docker镜像分层原理
    • Docker简述
    • 文件联合系统(UnionFS)
    • Docker使用UnionFS
      • 思考
      • 写时拷贝(Copy-on-Write)
      • Docker 镜像原理

前言

本文仅介绍Docker镜像分层原理-UnionFS
完整版Docker教程请移步:Docker 完整版教程笔记

Docker镜像分层原理

Docker简述

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。

文件联合系统(UnionFS)

UnionFS (Union File System)
2004年由纽约州立大学开发,它可以把多个目录内容联合挂载到同一个目录下,而目录的物理位置是分开的。UnionFs可以把只读和可读写文件系统合并在一起,具有写时复制功能,允许只读文件系统的修改可以保存到可写文件系统当中。

  • UnionFs: UnionFS 时一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。
  • 特性: 一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

Docker使用UnionFS

Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像。可以制作各种具体的应用镜像。
分层的优点:

  • 分层最大的一个优点是共享资源;
  • 多个镜像都从相同的base镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像即可;
  • 同时内存中也只需要加载一份base镜像,就可以为所有容器服务,而且镜像的每一层都可以被共享。

思考

当我们浏览Docker hub时,能发现大多数镜像都不是从头开始制作,而是从一些base镜像基础上创建,比如centos基础镜像,而新镜像就是从基础镜像上一层层叠加新的逻辑构成的。这种分层设计,一个优点就是资源共享。

  1. 想象这样一个场景,一台宿主机上运行了100个基于centos base镜像的容器,难道每个容器里都有一份重复的debian拷贝呢?

这显然不合理!借助Linux的UnionFS,宿主机只需要在磁盘上保存一份base镜像,内存中也只需要加载一份,就能被基于这个镜像的所有容器共享。

  1. 当某个容器修改了基础镜像的内容,比如 /bin文件夹下的文件,这时其他容器的/bin文件夹是否会发生变化呢?

根据容器镜像的 写时拷贝(Copy-on-Write) 技术,某个容器对基础镜像的修改会被限制在单个容器内。

写时拷贝(Copy-on-Write)

容器镜像由多个镜像层组成,所有镜像层会联合在一起组成一个统一的文件系统。如果不同层中有一个相同路径的文件,比如 /text,上层的 /text 会覆盖下层的 /text,也就是说用户只能访问到上层中的文件 /text,这就是COW技术。

Docker 镜像原理

  • docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统为UnionFS

  • bootfs(boot file system) 主要包含bootloader 和 kernel,bootloader主要引导加载kernel,linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层时bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此使内存的使用权已由bootfs转交给内核,此使系统也会卸载bootfs。

  • rootfs(root file system) ,在bootfs之上。包含的就是典型Linux系统中的/dev、/proc、/bin、/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,CentOS等等

  • 将中间只读的 rootfs 的集合称为 Docker 镜像,Docker 镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。UnionFS 使得镜像的复用、定制变得更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。

  • 当用docker run启动这个容器时,实际上在镜像的顶部添加了一个新的可写层,这个可写层也叫容器层

  • 容器启动后,其内的应用所有对容器的改动,文件的增删改操作都只会发生在容器层中,对容器层下面的所有只读镜像层没有影响。

Docker 镜像都是只读的,当容器启动时,一个新的写层加载到镜像的顶部,这一层就是我们通常说的容器层,容器之下的都叫镜像层

  • layer
# docker image inspect 镜像名
# 查看镜像分层方式
[root@VM-16-4-centos ~]# docker image inspect python
[{"Id": "sha256:0f95b1e38607bbf15b19ad0d111f2316e92eb047a35370eac71973c636acb9d2","RepoTags": ["python:latest"],"RepoDigests": ["python@sha256:eeed7cac682f9274d183f8a7533ee1360a26acb3616aa712b2be7896f80d8c5f"],"Parent": "","Comment": "","Created": "2022-06-23T10:44:58.474893642Z","Container": "fceecb8656d753a144b3968d1c6c9b8f5453ff307d0688242f642743d9680beb","ContainerConfig": {"Hostname": "fceecb8656d7","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","LANG=C.UTF-8","GPG_KEY=A035C8C19219BA821ECEA86B64E628F8D684696D","PYTHON_VERSION=3.10.5","PYTHON_PIP_VERSION=22.0.4","PYTHON_SETUPTOOLS_VERSION=58.1.0","PYTHON_GET_PIP_URL=https://github.com/pypa/get-pip/raw/6ce3639da143c5d79b44f94b04080abf2531fd6e/public/get-pip.py","PYTHON_GET_PIP_SHA256=ba3ab8267d91fd41c58dbce08f76db99f747f716d85ce1865813842bb035524d"],"Cmd": ["/bin/sh","-c","#(nop) ","CMD [\"python3\"]"],"Image": "sha256:f968cc011b4d45dae5d5973d55488b86535bf317efb8f81481889503b79d1f8a","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": {}},"DockerVersion": "20.10.12","Author": "","Config": {"Hostname": "","Domainname": "","User": "","AttachStdin": false,"AttachStdout": false,"AttachStderr": false,"Tty": false,"OpenStdin": false,"StdinOnce": false,"Env": ["PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","LANG=C.UTF-8","GPG_KEY=A035C8C19219BA821ECEA86B64E628F8D684696D","PYTHON_VERSION=3.10.5","PYTHON_PIP_VERSION=22.0.4","PYTHON_SETUPTOOLS_VERSION=58.1.0","PYTHON_GET_PIP_URL=https://github.com/pypa/get-pip/raw/6ce3639da143c5d79b44f94b04080abf2531fd6e/public/get-pip.py","PYTHON_GET_PIP_SHA256=ba3ab8267d91fd41c58dbce08f76db99f747f716d85ce1865813842bb035524d"],"Cmd": ["python3"],"Image": "sha256:f968cc011b4d45dae5d5973d55488b86535bf317efb8f81481889503b79d1f8a","Volumes": null,"WorkingDir": "","Entrypoint": null,"OnBuild": null,"Labels": null},"Architecture": "amd64","Os": "linux","Size": 919687727,"VirtualSize": 919687727,"GraphDriver": {"Data": {"LowerDir": "/var/lib/docker/overlay2/f4cd5061845ac5514f5aaa387dd58b63ea37c14d4383e6f01360c5ab1a6357b5/diff:/var/lib/docker/overlay2/a2eeebe65fe6050b40368dfaaf6115998e46544636faf3c820c686d7fb1bde16/diff:/var/lib/docker/overlay2/4866d5cf1beb0816ba148e1700d92ea0c42cf1f7ba1ffd80e53113f95dcc2c8e/diff:/var/lib/docker/overlay2/bc1115c2e1d53bfd674718bdd08ef6a2c82c73667067fed2e05c18f2131e1c3d/diff:/var/lib/docker/overlay2/616914d1a8c57dd7386b550dbcd1ba501d11c09380afffa39fd227dcf3e4123d/diff:/var/lib/docker/overlay2/34ed671ac7b1d2cf8e30cf0f3cf85da97c34b643e217325c8110dea59c36c730/diff:/var/lib/docker/overlay2/b4e5edd486054fdcfbc558c6c2b64ccdd27e62776e6330828beab3674acfdcd6/diff:/var/lib/docker/overlay2/a09d8bfe4e8ff39f2b4b6589d36dc5bb97d3440aa2afc8d86e671a584f460eaa/diff","MergedDir": "/var/lib/docker/overlay2/a34dc8c6fd5f524c445da51fff81a50b3e15cf53c1db69aadca32c732b88209b/merged","UpperDir": "/var/lib/docker/overlay2/a34dc8c6fd5f524c445da51fff81a50b3e15cf53c1db69aadca32c732b88209b/diff","WorkDir": "/var/lib/docker/overlay2/a34dc8c6fd5f524c445da51fff81a50b3e15cf53c1db69aadca32c732b88209b/work"},"Name": "overlay2"},"RootFS": {"Type": "layers","Layers": ["sha256:97d5fec864d84417c057008f153140193d2cc924b545b0c6fec10ae891fb26f9","sha256:6840c8ff46bd2c0ab4086d311c3e4903639b586c84d4f4ad28d156a2cc749e5f","sha256:66183893ba248fa10375cfec3e598d7df626b44c7740156e935ce2fcd5589aa7","sha256:5afd661c6106dfe99ed40c2dd18b8f6ffc5d978fa3302037b513c7a6e366609f","sha256:33a247b4fc529be9d43b5e70cc7d1beadf12e58c6e74967a4ade33e5e58f936d","sha256:ca5c6d5c3d01e1e0463415cd97adc7da3d3d5bb09f9ed01ec9d27cf6eeacb928","sha256:a8db90eb5ce025d596d828c84dec139ef539fb2bfb67c47e046fff306cb8b79b","sha256:9d17ba627a77ee6184993444d132f0dc9b7527db91af69f5fd9493dc29006957","sha256:a84ac09f498fca42148b003e0a51971916a5ef676e676c9522910f1e406e12bb"]},"Metadata": {"LastTagTime": "0001-01-01T00:00:00Z"}}
]

总结:

  1. 平时我们安装进虚拟机的CentOS都是好几个G,而docker为什么只需要200多M?
  • 这是因为对于精简的 OS,rootfs 可以很小,只需要包合最基本的命令,工具和程序库就可以了,因为底层直接用宿主机的kernel,自己只需要提供 rootfs 就可以了。
  • 由此可见对于不同的Linux发行版, bootfs 基本是一致的,rootfs会有差別,因此不同的发行版可以公用 bootfs。

Docker镜像分层原理-联合文件系统(UnionFS)相关推荐

  1. docker学习(三):docker镜像分层原理及本地镜像推送到阿里云或私服

    文章目录 前言 docker镜像分层加载原理 docker镜像commit操作产生新镜像 本地镜像发布到阿里云 将本地镜像推送到私有库 前言 大家好,这是我学习docker系列的笔记文章,目标是掌握d ...

  2. [docker]七、docker镜像的制作(超详细)、docker镜像结构原理、镜像的分享——harbor

    目录 1.镜像(images) 1.1.Dockerfile:是制作镜像的文件 2.镜像结构原理 2.1.base 镜像 2.1.1.rootfs和bootfs 2.1.2.base 镜像提供的是最小 ...

  3. (转)Docker镜像结构原理

    以下内容转载自 https://blog.51cto.com/liuleis/2070461 第八篇:Docker镜像结构原理 base 镜像 base 镜像有两层含义: 不依赖其他镜像,从 scra ...

  4. linux内核镜像的分层,Docker镜像分层的原理详解

    base镜像 base镜像有两层含义: 不依赖其他镜像,从scratch构建 其他镜像可以之为基础进行扩展 所以,base镜像一般都是各种Linux发行版本的Docker镜像,比如:Ubuntu,De ...

  5. Docker镜像的原理

    centos7系统 包括2部分, linux内核,作用是提供操作系统的基本功能,和机器硬件交互,如何读取磁盘数据,管理网络,使用C编写的,由linus的开发团队,内核只提供操作系统的基本功能和特性,如 ...

  6. 第八篇:Docker镜像结构原理

    一.base 镜像 base 镜像有两层含义: 1. 不依赖其他镜像,从 scratch 构建. 2. 其他镜像可以之为基础进行扩展. base 镜像的通常都是各种 Linux 发行版的 Docker ...

  7. Docker镜像分层和临时容器

    镜像分层:对于已经构建过的镜像,修改Dockerfile文件后,再次构建只会对修改的部分进行执行,已经执行过的步骤并未修改的话会掠过. 临时容器:每执行一个步骤就会产生一个临时容器.

  8. 『 云原生·Docker』Docker镜像分层与Docker镜像操作(二)

    系列文章目录 本系列主要分为以下六大部分,正在更新中,尽请期待! 『 云原生·生之门』 『 云原生·前置知识』 『 云原生·Docker』 『 云原生·Kubernetes』 『 云原生·KubeSp ...

  9. Docker镜像阿里云的上传拉取-私服的搭建-容器

    Docker镜像 一:Docker镜像 1.1联合文件系统(UnionFS) 1.2Docker镜像加载原理 1.3Docker的分层结构 1.4 Docker commit命令 1.5本地镜像发布到 ...

  10. Docker 镜像优化与最佳实践

    云栖TechDay41期,阿里云高级研发工程师御坂带来Docker镜像优化与最佳实践.从Docker镜像存储的原理开始,针对镜像的存储.网络传输,介绍如何在构建中对这些关键点进行优化.并介绍Docke ...

最新文章

  1. 5.3.4 TCP流量控制
  2. leetcode 263. 丑数
  3. Android使用的设计模式2——策略模式
  4. html怎么显示数学公式,怎么使用html数学公式显示库MathJax - js笔记
  5. 自定义View之组合式
  6. Android-界面-布局
  7. 回顾频谱图卷积的经典工作:从ChebNet到GCN
  8. HMI报表设计与打印,标签、账单、支票、条码数据打印与出版VC++源码解决方案2018!
  9. 推荐支持 azw3 、epub 和 mobi 格式的阅读器:FBReader
  10. windows server2012R2 apache+mod_wsgi+django
  11. 家用洗地机买什么牌子好一点?家用洗地机推荐
  12. shell脚本——正则表达式(包含grep详细介绍及应用)
  13. linux ssl证书卸载,linux下nginx怎么卸载ssl证书
  14. 基于Acgis从全球.nc数据中提取中国地图并计算地区CO2值
  15. 动图设置动图设置动图设置
  16. uni-app微信小程序微信登录(获取头像、个性签名等基本信息)
  17. java基本数据类型 string,String是基本的数据类型吗?
  18. 编译安装pypy,让py飞起来
  19. 还愁没壁纸?Python爬取5K分辨率高清桌面壁纸
  20. 微信小程序学习之JS模块化(总结)

热门文章

  1. matlab中concur怎么用,Matlab的concur、repmat、kron、reshape函数介绍
  2. 思科模拟器配置默认路由(下一跳使用端口)
  3. LimeSDR DAB发射 RTL SDR DAB接收
  4. 多边形的凹凸性判断及python实现
  5. python矩阵转置_矩阵转置python
  6. Chrome插件(UserScript)开发教程
  7. Swarm(bzz)主网于6月21日正式启动 ,BZZ币合约已部署?红利提前来了吗?
  8. python怎么撤销_python撤销操作
  9. 23种设计模式之工厂模式
  10. mysql 同义词_在数据库mysql中存储和检索同义词的最佳方法